[译] 图解经常使用的 Git 指令含义

原文连接:CS Visualized: Useful Git Commands,by Lydia Hallie(有删改)。css

本文会介绍一些经常使用 Git 指令的图解说明。包括:git

合并(git merge

当项目中多条功能分支时,有时就须要使用 git merge 命令,指定将某个分支的提交合并到当前分支。Git 中有两个合并策略:fast-forwardno-fast-forwardfetch

fast-forward(--ff

若是当前分支,在合并分支前,没有作过额外提交。那么合并分支的过程不会产生的新的提交记录,而是直接将分支上的提交添加进来。这称为 fast-forward 合并。 ui

如今 dev 分支上的修改已所有合并到主分支 master 上。那 no-fast-forward 又是什么呢?

no-fast-forward(--no-ff

上面的场景不多遇到,基本是:在当前分支分离出子分支后,作了一些修改;而分离出的子分支也作了修改。这个时候再使用 git merge,就会触发 no-fast-forward 策略了。3d

在 no-fast-forward 策略下,Git 会在当前分支(active branch)额外建立一个新的 合并提交(merging commit)。这条提交记录既指向当前分支,又指向合并分支。 日志

合并后,在当前主分支 master 上包含 dev 分支上的全部修改。

合并冲突

若是两个分支的修改存在冲突:好比说同时修改了某个文件的同一行;或者一个分支删除了文件,另外一个分支则修改了文件——对于这种状况,Git 是没法自行决定合并策略的。这个时候,Git 就会把合并操做交给咱们。code

举个例子,两个分支对同一个 README.md 文件作了修改。cdn

image.png

若是此时将 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.cssindex.js 文件。

使用 git status 指令查看,发现新建的 style.cssindex.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 fetchgit merge

以下图所示:

译注:这里的图画的是有问题的——当前主分支并无新的提交,所以 git merge 的结果是直接将远程分支上的提交添加到当前分支以后,而不是如图所示的产生一个合并提交。

Reflog(git reflog

每一个人都会犯错,举一个例子:假设你不当心使用 git reset 命令硬重置仓库到某个提交。后面忽然想到,重置致使了一些已有的正常代码的误删! git reflog 是一个很是有用的命令,用于显示全部已执行操做的日志!包括合并、重置、还原:基本上记录了对分支的任何更改。

若是你不幸犯错了,你可使用 git reflog 的信息经过重置 HEAD 轻松地重作此操做!

假设,咱们不想合并 origin/master 分支了。执行 git reflog 命令,咱们看到合并以前的仓库状态位于 HEAD@{1} 这个地方,咱们使用 git reset 指令将 HEAD 头指向 HEAD@{1}

能够看见,最新的操做信息也已经记录到 reflog 中了!

(正文完)


广告时间(长期有效)

我有一位好朋友开了一间猫舍,在此帮她宣传一下。如今猫舍里养的都是布偶猫。若是你也是个爱猫人士而且有须要的话,不妨扫一扫她的【闲鱼】二维码。不买也没关系,看看也行。

(完)

相关文章
相关标签/搜索