markdown 如何使用`git mergetool`来解决冲突

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 如何使用`git mergetool`来解决冲突相关的知识,希望对你有一定的参考价值。

# Table Of Content
Skip to the relevant sections if needed.
* [2-min tutorial to do it the quick-and-dirty-way](http://www.git-tower.com/learn/git/ebook/command-line/advanced-topics/merge-conflicts)
* [Concepts for resolving `Git conflicts`](#concepts-for-resolving-git-conflicts)
* [Setting up different editors / tool for using `git mergetool`](#setting-up-different-editors--tool-for-using-git-mergetool)
    * [Finding out what `mergetool` editors are supported](#finding-out-what-mergetool-editors-are-supported)
* [`mergetool` simple code example for `vimdiff`](#mergetool-simple-code-example)   
   * [Resolving conflict from a `Git pull`](#resolving-conflict-from-a-git-pull)
* [Other great references and tutorials](#other-great-references-and-tutorials)

# Concepts for resolving `Git conflicts`
For using `mergetool` in `git`,  we need to understand the following terminology to understand what is being merged:

* `LOCAL` - the `head` for the file(s) from the current branch on the machine that you are using.
* `REMOTE` - the `head` for files(s) from a remote location that you are trying to merge into your `LOCAL` branch.
* `BASE` - the common ancestor(s) of `LOCAL` and `BASE`.
* `MERGED` - the tag / `HEAD` object after the merge - this is saved as a new commit.

Common `mergetool` from editors will display both `LOCAL` and `REMOTE`  so you can decide which changes to keep.
Please read [this tutorial explaining the HEAD objects](http://www.sbf5.com/~cduan/technical/git/git-1.shtml) if you do not know what it is. It will help your understanding of Git tremendously.


# Setting up different editors / tool for using `git mergetool`
We have to change the `git config` to set a default mergetool.
In this example, we will use `vimdiff`:
```Bash
$ git config merge.tool vimdiff      
```
We can also set the editor to display the common ancestor `BASE` while we examine what changes are in `LOCAL` and `REMOTE` with the following setting:
```
$ git config merge.conflictstyle diff3  
```

[back to top](#table-of-content)

## Finding out what `mergetool` editors are supported
```
$ git mergetool --tool-help
```
And we list a few of them:
### Command line `mergetool` editors
* `Emacs` based diff tools: `emerge`, or  [`Ediff`](https://whatworks4me.wordpress.com/2011/04/13/view-git-diffs-in-emacs-using-ediff/)
* `Vim` based diff tool: [`vimdiff`](http://www.rosipov.com/blog/use-vimdiff-as-git-mergetool/)

### GUI `mergetool` editors
* `gvimdiff` - almost identical to `vimdiff` but uses the Linux GUI for `Vim`, please refer to `vimdiff` if you still use the keyboard commands for `GVim`.
* [`kdiff3`](http://kdiff3.sourceforge.net/) 
* [`meld`](http://blog.deadlypenguin.com/blog/2011/05/03/using-meld-with-git-diff/)
* [`tortoisemerge`](http://tortoisesvn.net/docs/nightly/TortoiseMerge_en/tmerge-dug.html)

Or consult the community of your favorite editor to see how to do the equivalent operations for your editor.

## Other useful `mergetool` settings 
Do not prompt before launching the merge resolution tool
```
$ git config mergetool.prompt false
```
[back to top](#table-of-content)

# `mergetool` simple code example
[Ref1 for the example](http://www.rosipov.com/blog/use-vimdiff-as-git-mergetool/)   
[Ref2](http://flaviusim.com/blog/how-to-do-a-git-merge-with-vim/)

## creating the git repo 
```Bash
$ mkdir galaxyZoo
$ cd galaxyZoo
$ git init
$ vim astrophy_obj.txt
```
Add some galaxy types into `astrophy_obj.txt` then save the file.
```
# content of astrophy_obj.txt
spiral
ellipitcal
bar 
irregular
```
save then commit the file.

```
$ git add astrophy_obj.txt
$ git commit -m 'Initial commit'
$ git branch astrophy_objects   # create a new branch
$ git checkout astrophy_objects # change to new branch
$ vim astrophy_obj.txt          # make changes to file 
```
Change `bar` to `barred` in the file.
```
$ git commit -am 'changed bar to barred'
$ git checkout master   # change back to master branch
$ vim astrophy_obj.txt  
# add the word `galaxy` to the end of each line using Vim REGEX 
# type `:%s/$/ galaxy/g` in Vim then press enter and save `:wq`

$ git commit -am 'added galaxy to each line'
# merge from the astrophy_objects branch to current branch, i.e. master
$ git merge astrophy_objects  
```
Then you will see some error messages:
```
Auto-merging astrophy_obj.txt
CONFLICT (content): Merge conflict in astrophy_obj.txt
Automatic merge failed; fix conflicts and then commit the result.
```
We can bring up the `mergetool`:
```
$ git mergetool
```
Then it will bring up the different versions of the file in different `Vim splits` panels.
```
+--------------------------------+
| LOCAL  |     BASE     | REMOTE |
+--------------------------------+
|             MERGED             |
+--------------------------------+
```
The top left split panel is the `LOCAL`, top middle split is `BASE` and top right split is `REMOTE`.
The bottom split refers to the `MERGED` version.
You can find this info in the bottom bar of each split (I have put 3 yellow rectangles to highlight that info).

As you can see form the below image, my `Vim` has highlighted the differences in red for me.
![Vim mergetool image](https://app.box.com/representation/file_version_37661948594/image_2048/1.png?shared_name=ws92iu1ftjib8pcmq0b8hly0hwwnb1jh)

Now if your terminal has any GUI capability and you have compiled `Vim` correctly with GUI support, you can use your mouse to click on the bottom split to edit it.
Or if you are a `Vim` ninja, you can use the keyboard shortcut to move to different splits.
```
Ctrl w + h   # move to the split on the left 
Ctrl w + j   # move to the split below
Ctrl w + k   # move to the split on top
Ctrl w + l   # move to the split on the right
```
You can either incorporate the changes by manually editing the `MERGED` split, 
or use `Vim` shortcuts pull from one of the `LOCAL`, `BASE` ad `REMOTE` versions.

```
:diffg RE  # get from REMOTE
:diffg BA  # get from BASE
:diffg LO  # get from LOCAL
```
save the changes then quit with `:wqa` to close all the splits.
Remember to commit the merge.
```
$ git commit -am 'merged from several branches'
```
## Resolving conflict from a `git pull` 

If you were trying to do a `git pull` when you ran into `merge` conflicts, 
follow all steps in the previous section for using the `mergetool`, then do:
```
$ git rebase –continue
```
This command will 
> Forward-port local commits to the updated upstream HEAD.

according to the documentation, meaning your local commits will be pushed to the `upstream remote branch` 
as a new forward commit that doesn't interfere with previous commits.
Hooray now you can claim that you can collaborate with others with Git without messing up with your collaborators' commits.

[back to top](#table-of-content)

## Other `vimdiff` keyboard shortcuts
```
]c - Jump to the next change.
[c - Jump to the previous change.
```
[ref](http://amjith.blogspot.com/2008/08/quick-and-dirty-vimdiff-tutorial.html)

# Other great references and tutorials
* [Git mergetool documentation on git-scm.com](http://git-scm.com/docs/git-mergetool)   
* [Must-read tutorial: the concepts of branching and merging from Charles Duan](http://www.sbf5.com/~cduan/technical/git/git-3.shtml)       
* [Improving Vimdiff as a Git mergetool](http://vim.wikia.com/wiki/A_better_Vimdiff_Git_mergetool)

[back to top](#table-of-content)

以上是关于markdown 如何使用`git mergetool`来解决冲突的主要内容,如果未能解决你的问题,请参考以下文章

markdown 如何使用`git mergetool`来解决冲突

markdown 如何使用`git mergetool`来解决冲突

markdown 如何从项目git commit history中查找和恢复已删除的文件

markdown 如何在Git中更改提交消息? - 首次发表于fullweb.io第55期

markdown 如何在Git中更改提交消息? - 首次发表于fullweb.io第55期

markdown [git latexdiff使用] #git #latex