git的使用(二)git冲突解决和版本回退

版本回退

git reset——回溯历史版本

回到创建feature-A分支之前的master分支,创建一个名为fix-B的分支

首先查看当前分支图表

$ git log --graph
*   commit a4dc01ab44706349cc7661e7b1c4315d1b6fd405 (HEAD -> master)
|\  Merge: 6ab6d6b 64aa165
| | Author: kingram <kingram@163.com>
| | Date:   Wed Jul 28 18:55:42 2021 +0800
| |
| |     Merge branch 'feature-A'
| |
| * commit 64aa16533ca53ae652aca4f6ce8227b7aabc4ad4 (feature-A)
|/  Author: kingram <kingram@163.com>
|   Date:   Wed Jul 28 18:44:46 2021 +0800
|
|       add feature-A
|
* commit 6ab6d6b65bc4d28be5b571dbc01df81e2231effa
| Author: kingram <kingram@163.com>
| Date:   Wed Jul 28 18:23:10 2021 +0800
|
|     add index
|
* commit 7419956521d4a00e4fa35ec754946f6cdfce10cf
  Author: kingram <kingram@163.com>
  Date:   Wed Jul 28 17:40:54 2021 +0800

      first commit

通过这个命令可以看到创建feature-A分支前的时间点的hash值为6ab6d6b65bc4d28be5b571dbc01df81e2231effa,只要执行git reset --hard +hash就可以回到该hash对应的时间点

$ git reset --hard 6ab6d6b65bc4d28be5b571dbc01df81e2231effa
HEAD is now at 6ab6d6b add index

查看下README.md,还没有新建分支

$ cat README.md
# GIT测试

创建分支fix-B

$ git switch -c fix-B
Switched to a new branch 'fix-B'
$ git branch
  feature-A
* fix-B
  master

修改README.md,增加一行

# GIT测试
- fix-B

提交

$ git add README.md
$ git commit -m "fix B"
[fix-B 8d19107] fix B
 1 file changed, 1 insertion(+)

查看下当前版本库的分支图表

$ git log --graph
* commit 8d191079fac23089ae61d916956dee27faaa4bc2 (HEAD -> fix-B)
| Author: kingram <kingram@163.com>
| Date:   Wed Jul 28 20:05:25 2021 +0800
|
|     fix B
|
* commit 6ab6d6b65bc4d28be5b571dbc01df81e2231effa (master)
| Author: kingram <kingram@163.com>
| Date:   Wed Jul 28 18:23:10 2021 +0800
|
|     add index
|
* commit 7419956521d4a00e4fa35ec754946f6cdfce10cf
  Author: kingram <kingram@163.com>
  Date:   Wed Jul 28 17:40:54 2021 +0800

      first commit

现在要做的就是将fix-B合并到master中,如图中红线标记。注意不是在当前状态直接合并,当前状态切换到master再合并fix-B就没有feature-A分支修改的内容了。

此时在历史记录中,版本库在创建feature-A前的时间点产生了两个分支,一个是feature-A的线,一个是fix-B的线,两条线其实是平行空间的,feature-A的线已经和master合并了,而fix-B的线还没有合并。

avatar

使用git reflog命令查看仓库操作日志,找到合并feature-A分支后的时间点的hash值

$ git reflog
8d19107 (HEAD -> fix-B) HEAD@{0}: commit: fix B
6ab6d6b (master) HEAD@{1}: checkout: moving from master to fix-B
6ab6d6b (master) HEAD@{2}: reset: moving to 6ab6d6b65bc4d28be5b571dbc01df81e2231effa
a4dc01a HEAD@{3}: merge feature-A: Merge made by the 'recursive' strategy.
6ab6d6b (master) HEAD@{4}: checkout: moving from feature-A to master
64aa165 (feature-A) HEAD@{5}: checkout: moving from master to feature-A
6ab6d6b (master) HEAD@{6}: checkout: moving from feature-A to master
64aa165 (feature-A) HEAD@{7}: commit: add feature-A
6ab6d6b (master) HEAD@{8}: checkout: moving from master to feature-A
6ab6d6b (master) HEAD@{9}: commit: add index
7419956 HEAD@{10}: commit (initial): first commit

可以看到merge feature-A的时间点的hash值为a4dc01a

先切换到master分支,再回退到a4dc01a时间点

$ git switch master
Switched to branch 'master'
$ git reset --hard a4dc01a
HEAD is now at a4dc01a Merge branch 'feature-A'

此时状态如图所示:

avatar

现在只要合并fix-B分支到master分支,就完成任务了,但是我们在feature-A分支中也是修改了README.md文件的,所以合并会产生冲突。

$ git merge fix-B
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

CONFLICT中显示README.md文件产生了冲突,查看下文件

$ cat README.md
# GIT测试

<<<<<<< HEAD
- feature-A

=======
- fix-B
>>>>>>> fix-B

=======上面的是当前HEAD内容,下面是要合并的内容。修改如下

$ cat README.md
# GIT测试
- feature-A
- fix-B

解决冲突后提交一下文件

$ git add README.md
$ git commit -m "fixed conflict"
[master d521ac7] fixed conflict

git commit –amend——修改提交信息

上一条提交信息标记了为fix conflict,但其实是fix-B分支的合并,即:Merge branch 'fix-B'

查看git log

commit d521ac7386bc3aebd58d41c6420d29196751127a (HEAD -> master)
Merge: a4dc01a 8d19107
Author: kingram <kingram@163.com>
Date:   Thu Jul 29 09:24:12 2021 +0800

    fixed conflict

commit 8d191079fac23089ae61d916956dee27faaa4bc2 (fix-B)
Author: kingram <kingram@163.com>
Date:   Wed Jul 28 20:05:25 2021 +0800

    fix B

commit a4dc01ab44706349cc7661e7b1c4315d1b6fd405
Merge: 6ab6d6b 64aa165
Author: kingram <kingram@163.com>
Date:   Wed Jul 28 18:55:42 2021 +0800

    Merge branch 'feature-A'

commit 64aa16533ca53ae652aca4f6ce8227b7aabc4ad4 (feature-A)
Author: kingram <kingram@163.com>
Date:   Wed Jul 28 18:44:46 2021 +0800

    add feature-A

commit 6ab6d6b65bc4d28be5b571dbc01df81e2231effa
Author: kingram <kingram@163.com>
Date:   Wed Jul 28 18:23:10 2021 +0800

    add index

commit 7419956521d4a00e4fa35ec754946f6cdfce10cf
Author: kingram <kingram@163.com>
Date:   Wed Jul 28 17:40:54 2021 +0800

    first commit

修改提交信息

git commit --amend

编译器显示

fixed conflict

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Thu Jul 29 09:24:12 2021 +0800
#
# On branch master
# Changes to be committed:
#       modified:   README.md
#

按下i,修改为Merge branch 'fix-B',按下:wq保存退出

[master a564645] Merge branch 'fix-B'
 Date: Thu Jul 29 09:24:12 2021 +0800

查看当前分支图表

$ git log --graph
*   commit a564645c1cc0bb1f57512fe077abaeaa269aad84 (HEAD -> master)
|\  Merge: a4dc01a 8d19107
| | Author: kingram <kingram@163.com>
| | Date:   Thu Jul 29 09:24:12 2021 +0800
| |
| |     Merge branch 'fix-B'
| |
| * commit 8d191079fac23089ae61d916956dee27faaa4bc2 (fix-B)
| | Author: kingram <kingram@163.com>
| | Date:   Wed Jul 28 20:05:25 2021 +0800
| |
| |     fix B
| |
* |   commit a4dc01ab44706349cc7661e7b1c4315d1b6fd405
|\ \  Merge: 6ab6d6b 64aa165
| |/  Author: kingram <kingram@163.com>
|/|   Date:   Wed Jul 28 18:55:42 2021 +0800
| |
| |       Merge branch 'feature-A'
| |
| * commit 64aa16533ca53ae652aca4f6ce8227b7aabc4ad4 (feature-A)
|/  Author: kingram <kingram@163.com>
|   Date:   Wed Jul 28 18:44:46 2021 +0800
|
|       add feature-A
|
* commit 6ab6d6b65bc4d28be5b571dbc01df81e2231effa
| Author: kingram <kingram@163.com>
| Date:   Wed Jul 28 18:23:10 2021 +0800
|
|     add index
|
* commit 7419956521d4a00e4fa35ec754946f6cdfce10cf
  Author: kingram <kingram@163.com>
  Date:   Wed Jul 28 17:40:54 2021 +0800

      first commit

git rebase -i——压缩历史

在合并特性分支之前,如果发现已提交的内容中有些许拼写错误等,不妨提交一个修改,然后将这个修改包含到前一个提交之中,压缩成一个历史记录。这是个会经常用到的技巧。

$ git switch -c feature-C
Switched to a new branch 'feature-C'

修改README.md文件

# GIT测试
- feature-A
- fix-B
- faeture-C

这里留了个小拼写错误

提交

$ git commit -am "add feature-C"
[feature-C 768f68a] add feature-C
 1 file changed, 1 insertion(+), 1 deletion(-)

修改README.md文件拼写错误

修改后查看区别

$ git diff HEAD
diff --git a/README.md b/README.md
index f583f41..4f997d5 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
 # GIT测试
 - feature-A
 - fix-B
-- faeture-C
+- feature-C

提交

$ git commit -am "fix typo"
[feature-C 65dd8a2] fix typo
 1 file changed, 1 insertion(+), 1 deletion(-

修改历史

git rebase -i HEAD~2

修改编译器内容

pick 768f68a add feature-C
pick 65dd8a2 fix typo

# Rebase a564645..65dd8a2 onto a564645 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

按下ifixtypopick改为fixup,按下:wq保存退出

Successfully rebased and updated refs/heads/feature-C.

系统显示rebase成功,将"Fix typo"的内容合并到了上一个提交 “Add feature-C"中,改写成了一个新的提交。这样一来,Fix typo就从历史中被抹去,也就相当于Add feature-C中从来没有出现过拼写错误。这算是一种良性的历史改写。

合并分支

$ git merge feature-C
Updating a564645..cc1fcc4
Fast-forward
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)