原文连接:CS Visualized: Useful Git Commands,by Lydia Hallie(有删改)。css
本文会介绍一些经常使用 Git 指令的图解说明。包括:git
git merge
)当项目中多条功能分支时,有时就须要使用 git merge
命令,指定将某个分支的提交合并到当前分支。Git 中有两个合并策略:fast-forward 和 no-fast-forward。fetch
--ff
)若是当前分支,在合并分支前,没有作过额外提交。那么合并分支的过程不会产生的新的提交记录,而是直接将分支上的提交添加进来。这称为 fast-forward 合并。 ui
dev
分支上的修改已所有合并到主分支
master
上。那 no-fast-forward 又是什么呢?
--no-ff
)上面的场景不多遇到,基本是:在当前分支分离出子分支后,作了一些修改;而分离出的子分支也作了修改。这个时候再使用 git merge
,就会触发 no-fast-forward 策略了。3d
在 no-fast-forward 策略下,Git 会在当前分支(active branch)额外建立一个新的 合并提交(merging commit)。这条提交记录既指向当前分支,又指向合并分支。 日志
若是两个分支的修改存在冲突:好比说同时修改了某个文件的同一行;或者一个分支删除了文件,另外一个分支则修改了文件——对于这种状况,Git 是没法自行决定合并策略的。这个时候,Git 就会把合并操做交给咱们。code
举个例子,两个分支对同一个 README.md
文件作了修改。cdn
若是此时将 dev
合并到 master
,那么就存在合并冲突了:标题是使用 Hello!
仍是 Hey!
呢?blog
当在主分支上执行 git merge
后,Git 会提示存在合并冲突,并把冲突的地方标记出来。咱们手工处理完毕后,保存修改、添加文件、而后提交修改就能够了。 开发
git rebase
)除了 git merge
,还能使用 git rebase
来合并分支。git rebase
指令会 复制 当前分支的全部最新提交,而后将这些提交添加到指定分支提交记录之上。
如图,dev
分支是从主分支上分离出去的(在 i8fe5
处),以后主分支与 dev
分支上都有相应的修改。执行 git rebase master
指令后,dev
分支将本身的最新提交记录复制出来(提交 hash 也发生了改变),拼在了主分支最后一次提交之上。这种合并分支的方式,会另 Git 提交历史看起来很清爽。
变基在开发功能(feature branch)分支时颇有用——在开发功能时,主分支上可能也作了一些更新,咱们能够将主分支上的最新更新经过变基合并到功能分支上来,这在将来在主分支上合并功能分支避免了冲突的发生。
git rebase
时,咱们还能对当前分支上的提交记录作修改!采用 交互式变基(Interactive Rebase) 形式。 变基时提供了 6 种操做模式:
reword
:修改提交信息edit
:修改此提交squash
:将当前提交合并到以前的提交中fixup
:将当前提交合并到以前的提交中,不保留提交日志消息exec
:在每个须要变基的提交上执行一条命令drop
:删除提交以 drop
为例:
squash
为例:
e45cb
(+styles.css) 合并到
ec5be
(+index.js) 提交后,两个提交从新 hash 出了
c4ec9
(+styles.css、+index.js)这个提交记录。
git reset
)若是由于某些缘由(好比新提交致使了 BUG,或只是一个 WIP 提交),须要撤回提交,那么可使用 git reset
指令。 git reset
能够控制当前分支回撤到某次提交时的状态。
执行软重置时,撤回到特定提交以后,已有的修改会保留。
如下图为例:9e78i
提交添加了 style.css
文件,035cc
提交添加了 index.js
文件。使用软重置,咱们能够撤销提交记录,可是保留新建的 style.css
和 index.js
文件。
git status
指令查看,发现新建的
style.css
和
index.js
的两个文件还在,不过对应的提交记录已经移除。这很好,咱们能够对这些文件内容从新编辑,稍后再作提交。
有时重置时,无需保留提交已有的修改,直接将当前分支的状态恢复到某个特定提交下,这种重置称为硬重置,须要注意的是,硬重置还会将当前工做目录(working directory)中的文件、已暂存文件(staged files)所有移除!💣
git status
查看,发现当前操做空间空空如也。Git 丢弃了
9e78i
和
035cc
两次提交引入的修改,将仓库重置到
ec5be
时的状态。
git revert
)另外一种撤销更改的方式,是使用 git revert
指令。用于还原某次提交的修改,会建立一个包含已还原更改的 新提交记录! 举个例子,咱们在 ec5be
上添加了 index.js
文件。以后发现并不须要这个文件。那么就可使用 git revert ec5be
指令还原以前的更改。
新的提交记录 9e78i
还原了 ec5be
引入的更改。git revert
能够在不修改分支历史的前提下,还原某次提交引入的更改。
git cherry-pick
)若是某个分支上的某次提交的修改正是当前分支须要的,那咱们可使用 cherry-pick
命令检出某次的提交更改做为新的提交添加到当前分支上面。
举个例子(以下图所示):dev
分支上的 76d12
提交添加了 index.js
文件,咱们须要将本次提交更改加入到 master
分支,那么就可使用 git cherry-pick 76d12
单独检出这条记录修改。
如今 master
分支包含了 76d12
中引入的修改,并添加了一条提交记录 9e78i
。
git fetch
)假设,咱们在一个有关联远程分支(好比:在 Github 上)的分支上工做,那么就要面临一个问题——你和你的同事都这个分支上工做,你的同事将他作的更改(好比一个 quick fix)提交到了远程分支上,而这些提交是你本地没有的。
此时,就要使用 git fetch
指令将远程分支上的最新的修改下载下来。
能够看见,git fetch
指令并无影响本地分支。
git pull
)除了 git fetch
,咱们还能使用 git pull
获取远程分支数据。有什么不一样呢?git pull
指令实际作了两件事:git fetch
和 git merge
。
以下图所示:
译注:这里的图画的是有问题的——当前主分支并无新的提交,所以 git merge 的结果是直接将远程分支上的提交添加到当前分支以后,而不是如图所示的产生一个合并提交。
git reflog
)每一个人都会犯错,举一个例子:假设你不当心使用 git reset
命令硬重置仓库到某个提交。后面忽然想到,重置致使了一些已有的正常代码的误删! git reflog
是一个很是有用的命令,用于显示全部已执行操做的日志!包括合并、重置、还原:基本上记录了对分支的任何更改。
git reflog
的信息经过重置
HEAD
轻松地重作此操做!
假设,咱们不想合并 origin/master
分支了。执行 git reflog
命令,咱们看到合并以前的仓库状态位于 HEAD@{1}
这个地方,咱们使用 git reset
指令将 HEAD
头指向 HEAD@{1}
。
能够看见,最新的操做信息也已经记录到 reflog
中了!
(正文完)
广告时间(长期有效)
我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。
(完)