文章目录
3. 更改提交的操作
3.1 git reset——回溯历史版本
Git 的另一特征便是可以灵活操作历史版本。借助分散仓库的优势,可以在不影响其他仓库的前提下对历史版本进行操作。
回溯历史,创建fix-B 分支:
3.1.1 回溯到创建feature-A 分支前
$ git reset --hard ebcec4282b7792951e478b703df03bd43b819aea
HEAD is now at ebcec42 Add index
3.1.2 创建 fix-B 分支
现在我们来创建特性分支(fix-B)。
$ git checkout -b fix-B
Switched to a new branch 'fix-B'
添加文字:
然后直接提交README.md 文件:
$ git add README.md
$ git commit -m "Fix B"
[fix-B d40dd7b] Fix B
1 file changed, 5 insertions(+), 1 deletion(-)
当前fix-B 分支的状态:
fix-B 分支的下一步目标:
3.1.3 推进至feature-A 分支合并后的状态
首先恢复到feature-A 分支合并后的状态。不妨称这一操作为“推进历史”。
git log命令只能查看以当前状态为终点的历史日志。所以这里要使用git reflog命令,查看当前仓库的操作日志。在日志中找出回溯历史之前的哈希值,通过git reset --hard命令恢复到回溯历史前的状态。
$ git reflog
在日志中,我们可以看到commit、checkout、reset、merge 等Git 命令的执行记录。
即便开发者错误执行了Git 操作,基本也都可以利用git reflog命令恢复到原先的状态。
上面8行表示feature-A 特性分支合并后的状,我们将HEAD、暂存区、工作树恢复到这个时间点的状态:
$ git checkout master
Switched to branch 'master'
$ git reset --hard cfc142d
HEAD is now at cfc142d Merge branch 'feature-A'
使用git reset --hard命令回溯了历史
恢复历史后的状态:
3.2 消除冲突
现在只要合并fix-B 分支,就可以得到我们想要的状态。
$ git merge --no-ff fix-B
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
这时,系统告诉我们README.md 文件发生了冲突(Conflict)。系统在合并README.md 文件时,feature-A 分支更改的部分与本次想要合并的fix-B 分支更改的部分发生了冲突。
不解决冲突就无法完成合并,所以我们打开README.md 文件,解决这个冲突。
3.2.1 查看冲突部分并将其解决
用编辑器打开README.md 文件,就会发现其内容变成了下面这个样子:
我们在编辑器中将其改成想要的样子:
本次修正让feature-A 与fix-B 的内容并存于文件之中。但是在实际的软件开发中,往往需要删除其中之一,所以各位在处理冲突时,务必要仔细分析冲突部分的内容后再行修改。
3.2.2 提交解决后的结果
冲突解决后,执行git add命令与git commit命令:
$ git add README.md
$ git commit -m "Fix conflict"
[master 1f668ba] Fix conflict
由于本次更改解决了冲突,所以提交信息记为"Fix conflict"。
3.3 git commit --amend——修改提交信息
要修改上一条提交信息,可以使用git commit --amend命令。
$ git commit --amend
$ git commit --amend
[master dfef176] Merge branch 'fix-B'
Date: Thu Jul 9 10:17:28 2020 +0800
现在执行git log --graph命令,可以看到提交日志中的相应内容也已经被修改。
$ git log --graph
3.4 git rebase -i——压缩历史
在合并特性分支之前,如果发现已提交的内容中有些许拼写错误等,不妨提交一个修改,然后将这个修改包含到前一个提交之中,压缩成一个历史记录。
3.4.1 创建 feature-C 分支
首先,新建一个feature-C 特性分支:
$ git checkout -b feature-C
Switched to a new branch 'feature-C'
在README.md 文件中添加一行文字,并且故意留下拼写错误,以便之后修正。
提交这部分内容。这个小小的变更就没必要先执行git add命令再执行git commit命令了,我们用git commit -am命令来一次完成这两步操作。
$ git commit -am "Add feature-C"
[feature-C 32ccfa0] Add feature-C
1 file changed, 1 insertion(+)
3.4.2 修正拼写错误
先自行把READ.md的内容进行修正:
$ git diff
然后进行提交:
$ git commit -am "Fix typo"
实际上,我们不希望在历史记录中看到这类提交,因为健全的历史记录并不需要它们。
3.4.3 更改历史
我们来更改历史。将"Fix typo"修正的内容与之前一次的提交合并,在历史记录中合并为一次完美的提交。为此,我们要用到git rebase命令。
$ git rebase -i HEAD~2
$ git rebase -i HEAD~2
Successfully rebased and updated refs/heads/feature-C.
现在再查看提交日志时:
这样一来,Fix typo 就从历史中被抹去,也就相当于Add feature-C 中从来没有出现过拼写错误。这算是一种良性的历史改写。
3.4.4 合并至master 分支
feature-C 分支的使命告一段落,我们将它与master 分支合并。
$ git branch
feature-A
* feature-C
fix-B
master
$ git checkout -
Switched to branch 'master'
$ git merge --no-ff feature-C
Merge made by the 'recursive' strategy.
README.md | 1 +
1 file changed, 1 insertion(+)
$ git log -graph