git rerere
rerere 是啥的缩写?
1
| rerere = reuse recorded resolution
|
rerere是干啥用的?
它会让Git记住你是如何解决某个文件的两个版本之间的conflict,这样在下次Git遇到同样的文件在相同的两个版本间发生冲突时,可以自动帮你使用相同的方法解决冲突。
如何启用rerere?
1
| git config --global rerere.enabled true
|
或者
在repo目录里 mkdir .git/rr-cache
不过推荐前者。
能举例说明吗?
参考inline的注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| $ git init git-rerere-test Initialized empty Git repository in /cygdrive/e/test/git-rerere-test/.git/
$ cd git-rerere-test
$ git config rerere.enabled true
$ echo "What fruit do you like?" >> question
$ git add . && git commit -m "initial drop" [master (root-commit) af9fdf9] initial drop 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 question
$ git branch test
$ echo "I like orange" >> question
$ git add . && git commit -m "answer in master" [master 3b48cca] answer in master 1 files changed, 1 insertions(+), 0 deletions(-)
$ git checkout test Switched to branch 'test'
$ echo "I like apple" >> question
$ git add . && git commit -m "answer in test" [test cda9dab] answer in test 1 files changed, 1 insertions(+), 0 deletions(-)
$ git checkout master Switched to branch 'master'
$ git merge test Auto-merging question CONFLICT (content): Merge conflict in question Recorded preimage for 'question' # 多了这一句,表示Git已经开始track你的操作了 Automatic merge failed; fix conflicts and then commit the result.
$ vim question
$ cat question What fruit do you like? I like orange & apple
$ git status -s UU question
$ git add question
$ git commit -m "merge test" Recorded resolution for 'question'. # Git记录了这次解决冲突的方法 [master 0b55608] merge test
$ git reset --hard HEAD^ HEAD is now at 3b48cca answer in master
$ git merge test Auto-merging question CONFLICT (content): Merge conflict in question Resolved 'question' using previous resolution. # Git已经用记录的方法解决冲突了 Automatic merge failed; fix conflicts and then commit the result.
|
使用场景?
假设你有如下的history
1 2 3
| o---*---o topic / o---o---o---*---o---o master
|
***** 表示的commit同时修改了同一个文件的同一块代码。这时你想测试一下两处修改有没有破坏build/功能。你可能会
1 2
| $ git checkout topic $ git merge master
|
结果是生成了如下的历史树:
1 2 3
| o---*---o---+ topic / / o---o---o---*---o---o master
|
你解决了冲突并生成了+这个commit。测试完成后,你继续在topic分支上工作,同时master分支上也有了新的commit。最终,你在topic分支上的工作完成,merge回master分支。你执行了:
1 2
| $ git checkout master $ git merge topic
|
最终的历史树看起来像这样:
1 2 3
| o---*---o---+---o---o topic / / \ o---o---o---*---o---o---o---o---# master
|
如果你的topic分支会存活很长时间,你可能多次从master分支merge到topic进行测试。那么你可能会看到很多+的commit(从master分支到topic的线),这会让历史树看起来不那么直观。
其实你还有其他选择,在每次merge完成测试以后,丢弃掉这次merge(但是rerere已经帮你记录了如何解决冲突,不用担心日后再次费劲心思的处理),继续原来的历史开发。直到最终topic分支完成任务,被merge到master(这时rerere会帮你处理掉merge conflict),这样你的历史树看起来就像:
1 2 3
| o---*---o-------o---o topic / \ o---o---o---*---o---o---o---o---+ master
|
查看 conflict
rerere帮我自动处理了conflict,但我已经忘了这个文件conflict的时候是啥样子了。。。能看看conflict的时候的样子吗?
执行git checkout --conflict=merge <path>
即可
更多详情参考 git help rerere
Git rerere