git命令总结

安装 git

当前用户的 Git 配置文件放在用户主目录下的一个隐藏文件 .gitconfig 中,里面可配置 git 相关的全局信息。

安装好后,最后一步设置

1
2
3
git config --global user.name "korey"
git config --global user.email "xxx@163.com"
git config --global alias.st status #设置别名

大小写敏感

1
git config core.ignorecase false

如果已经在远程仓库出现文件重复的情况

  1. git config core.ignorecase false
  2. 修改文件夹名称为目标名称,然后 push,远程仓库出现文件重复的情况。
  3. git rm --cached src/components/Header -rf
  4. 再次 add->commit->push 即可

列举所有配置

1
git config -l

查看系统 config

1
git config --system --list

查看当前用户(global)配置

1
git config --global --list

查看当前仓库配置信息

1
git config --local  --list

删除某个配置

1
git config --global --unset user.emaill

全局的通过 vim ~/.gitconfig 来查看 局部的通过当前路径下的 .git/config 文件来查看

创建版本库(仓库)

1
2
3
4
mkdir aaa
cd aaa
pwd
git init

三态转换

查看仓库状态

1
git status
  • 工作区 Working tree:即文件目录内容
  • 暂存区 index:目录 .git 内的 stage/index (已 addcommit)
  • 版本库 repo:文件 .git 新修改的文件 (工作区) (untracked)→ 通过 add→ 暂存区 → 通过 commit→ 版本库

工作区->暂存区

1
2
git add <file>
git add .

暂存区->版本库

1
2
3
4
5
git commit <file>
git commit .
git commit -a
git commit -amend #修改最后一次提交
git commit -m “xxx”

撤销工作区的修改

1
2
git checkout --  <file>
git checkout .

checkout 还可以检出提交,查看某个版本的代码:

1
2
git checkout 5aab391 #跳到该commit快照
git checkout - #回到当前

已暂存撤销到工作区(git 不再跟踪)

1
2
3
4
git rm -- cached <file>
git reset <file>
git reset . #--mixed 为默认参数 意思是把变更放在工作区
git reset --hard #工作区和暂存区都撤销

文件改名

1
git mv oldName newName

删除文件

1
git rm <file>

比较 diff

1
2
3
4
5
6
7
git diff                #比较Working tree和index之间的差异
git diff <file> #比较Working tree和index之间的差异
git diff --cached 或 $git diff --staged #两个都是比较index和版本库的差异
git diff HEAD # 查看Working tree和版本库的差异
git diff <$id1> <$id2> #比较两次提交之间的差异
git diff <branch1>..<branch2> #在两个分支之间比较
git diff --name-only HEAD src #显示当前分支最新的提交与工作区或暂存区的比较,只显示文件名

^和~的区别

  • ^代表父提交,当一个提交有多个父提交时,可以通过在^后面跟上一个数字,表示第几个父提交,^相当于^1
  • ~<n>表示第 n 个祖先提交,相当于连续的 n 个^。如HEAD~3即 HEAD 的父提交的父提交的父提交。如要取 merge 的第二个父提交的父提交:HEAD^2~1

查看历史记录

1
2
3
4
git log                      #第一行为commit ID
git log -p <file> #查看指定文件的提交历史
git blame <file> #以列表方式查看指定文件的提交历史
git reflog show master | head #显示所有的版本记录

版本回退

这里收集了 四种 方式实现版本回退,通过git reflog可以查看操作记录。

暴力 reset 回退

1
2
3
4
git checkout master
git pull
git reset --hard <commit>
git push origin master -f

该方式会改变历史进程,多人开发时会混乱,非常不推荐。

使用 revert 生成一个新 commit(撤销某次提交)

1
2
3
git revert 5aab391 #回滚某次commit
git revert -n 5aab391..1hd2d72 #回滚从5aab391到1hd2d72,但中间如果有merge等则不适用
git revert -m 1 5aab391 #回滚某次merge的commit -m 1是选择保留1,抛弃2,这个1,2的定义在git log中的merge那行顺序为准

该方法不会改变历史进程,适用于单个回滚或者多个无 merge 的回滚。

使用 reset –head –soft

1
2
3
4
git reset --hard 5aab391
git reset --soft 1hd2d72 #5aab391到1hd2d72之前的放到了暂存区 ?
git commit -m '生成一个新提交,回滚5aab391到1hd2d72的内容'
git push xxx

该方法不会改变历史进程,生成一个新的 commit 来覆盖之前的内容达到回滚,推荐。

使用 -s ours master

1
2
3
git checkout -b v2 4a50c9f #切一个新分支并使用历史安全版本
git merge -s ours master
git push origin master #等价于git push origin v2:master

该方法不会改变历史进程,生成一个新的 commit 来覆盖之前的内容达到回滚,墙裂推荐。

单个文件版本回退

1
git checkout 需要回退到正确版本的commitID 该文件相对路径

远程仓库

从远程仓库克隆

1
git clone git@git ….

创建 SSH Key

1
ssh-keygen -t rsa -c "623212389@qq.com"

用户主目录下 →.ssh→id_rsa(私钥)+id_rsa.pub(公钥)或\$cat ~/.ssh/id-rsa.pub

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
git remote -v     #查看远程服务器地址和仓库名称
git remote show origin #查看远程服务器仓库状态
git remote add origin git@git…… #添加远程仓库地址
git remote set-url origin git@git…… #修改远程地址
git remote rm #删除远程创库地址

git pull # =git fetch + git merge
git fetch #拉取
git merge #合并
git push # push所有分支
git push origin master # 将本地主分支推到远程主分支
git push -u origin master # 将本地主分支推到远程(如无远程主分支则创建,用于初始化远程仓库)
git push origin <local_branch> # 创建远程分支, origin是远程仓库名
git push origin <local_branch>:<remote_branch> # 创建远程分支
git push origin :<remote_branch> #先删除本地分支(git br -d <branch>),然后再push删除远程分支

git rebase

git remote update origin --prune #更新远程分支信息

分支相关

查看分支

1
git branch

查看远程分支

1
git branch -r

查看所有分支

1
git branch -a #远程分支用的红色

查看已经被合并到当前分支的分支

1
git branch --merged

查看未被合并到当前分支的分支

1
git branch --no-merged

创建分支

1
git branch xxx

切换分支或标签

1
git checkout xxx/tag

创建加切换

1
git checkout -b xxx

重命名本地分支

1
git branch -m old new

删除分支

1
git branch -d xxx   #-D为强制删除

删除远程分支

1
2
3
git push origin --delete <branchName>
#或
git push origin :<branchName> #推送一个空分支到远程

合并分支

merge

feature 分支合到 master:

1
2
3
4
5
git checkout master
git merge feature
// 此时如果有冲突,修改冲突后
git a
git commit -m 'merge'

此时会将 featuremaster 分支融合到一起,其中:

  • 如果 feature 的提交全部在 master 提交时间之后,那么直接将指针移到最后即可,master 分支线只有一条,feature 分支信息不保留,如果想保留则执行 git merge feature --no-ff
  • 如果 featuremaster 提交时间交替,那么会多一次冲突提交,master 分支线有 feature 汇入,提交的时序以各自分支的时间为准(即交替);
  • 如果在合并分支时想同时合并 featurecommit,则执行:git merge feature --squash
  • 撤销合并: git merge --abort

rebase

feature 分支合到 master:

1
2
3
4
5
6
7
8
git checkout feature
git rebase master
// 将 master 作为 基底,此时会将feature上的所有后于master的提交全部转化为一个个的补丁,往master上应用,如果有冲突,修改冲突后
git a
git rebase --continue
// 然后进入下一个补丁应用,补丁打完后,执行
git checkout master
git rebase/merge feature
  • rebase 的好处是分支线将只有一个,没有多余的 feature 分支线,也没有多余的提交历史,提交的时序也发生改变,以打补丁的时间为准(即先是 master 的提交,后是补丁的提交)
  • 撤销合并: git rebase --abort

mergerebase 区别

  • rebase 可以尽可能保持 master 分支干净整洁,但会丢失分支信息 (推荐)
  • merge 不能保持 master 分支干净,但是保持了所有的 commit history

注意 分支 merge 到 master 后,只有一个 commit 即提交解决冲突的 commit。

git merge 和 git rebase 的区别

合并提交(commit)

假如有 6 次提交 commit 从旧到新依次是:master1, master2, master3, master4, master5, master6,目标合并 master3, master4, master5, master6,最终效果为 master1, master2, masterN

reset

1
2
3
git reset HEAD~4 //前4次提交
git a
git commit -m 'masterN'

reabse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
git rebase -i HEAD~4
// 修改 后3个 pick 为 s,即以第一个pick为基点合并
// pick 91a5777 master3
// s dcecb67 master4
// s 5ac7381 master5
// s c032d0b master6
-----
// 然后再删除其他无用的commit信息,重写 1st commit message
# This is the 1st commit message:
// masterN
# This is the commit message #2:
# master4
# This is the commit message #3:
# master5
# This is the commit message #4:
# master6

合并中间部分提交

1
2
3
4
5
6
git checkout -b 分支T <终点提交> // 基于需要被合并的提交段的终点提交创建新的临时分支T
git reset HEAD~4 //前4次提交
git a
git commit -m 'masterN'
git checkout origin
git rebase --onto 分支T <终点提交>

暂存管理

1
2
3
4
5
git stash  #将工作区做的修改暂存到一个git栈中
git stash list #查看栈中所有暂存
git stash apply <暂存编号> #回复对应编号暂存到工作区,如果不指定编号为栈顶的,注意:这些暂存还在栈中
git stash pop #将栈顶的暂存,恢复到工作区,并从栈中弹出
git stash clear #清空暂存栈

意外删除暂存如何处理

场景:正在码代码,这个时候将正在写的代码暂存起来:git stash,然后拉去新的远端代码到本地后,执行 git stash pop 代码大量冲突,然后执行 git reset HEAD --hard 还原本地代码,但此时 stash 里已经没有刚在编写的代码了。

1
2
3
git fsck --unreachable # 显示出所有不可访问的对象
git show 64821f # 上一步得到的commit列表选择最前面的依次查询是否是误删除的修改
git stash apply 64821f # 应用

注意:git 会周期性地执行它的垃圾回收程序(gc),执行之后使用 git fsck 就不能再看到不可访问对象。

创建标签

1
2
3
4
5
6
7
git tag v1.0.0 #id
git tag -a v1.0.0 -m "你的附注信息" #id
git tag
git show v1.0.0
git tag -d v1.0.0
git push origin :refs/tags/v1.0.0
git push --tags #上传所有标签

挑拣提交

1
git cherry-pick 1hs73hds #直接在该分支应用任意其他分支的commit即可

忽略特殊文件

使用 Windows 的童鞋注意了,如果你在资源管理器里新建一个 .gitignore 文件,它会非常弱智地提示你必须输入文件名,但是在文本编辑器里“保存”或者“另存为”就可以把文件保存为 .gitignore 了。

github

GitHub 上,可以任意 Fork 开源仓库; 自己拥有 Fork 后的仓库的读写权限; 可以推送 pull request 给官方仓库来贡献代码。

总览图

git命令总结