• Aucun résultat trouvé

A Merge with a Conflict

Dans le document Version Control with Git (Page 140-144)

| * b384721... Add alternate's line 4

* | 761d917... Another file

|/

* 8f4d2d5... Initial 3 line file

That is exactly the same commit graph shown in “Commit Graphs” on page 72, except this graph is turned sideways, with the most recent commits at the top rather than the right. The two branches have split at the initial commit, 8f4d2d5; each branch shows one commit each (761d917 and b384721); and the two branches merge again at commit 1d51b93.

Using git log --graph is an excellent alternative to graphical tools such as gitk. The visualization provided by git log --graph is well suited to dumb terminals.

Technically, Git performs each merge symmetrically to produce one identical, com-bined commit that is added to your current branch. The other branch is not affected by the merge. Because the merge commit is added only to your current branch, you can say, “I merged some other branch into this one.”

A Merge with a Conflict

The merge operation is inherently problematic because it necessarily brings together potentially varying and conflicting changes from different lines of development. The changes on one branch may be similar to or radically different from the changes on a different branch. Modifications may alter the same files or a disjoint set of files. Git can handle all these varied possibilities, but often it requires guidance from you to resolve conflicts.

Let’s work through a scenario in which a merge leads to a conflict. We begin with the results of the merge from the previous section and introduce independent and con-flicting changes on the master and alternate branches. We then merge the alternate branch into the master branch, face the conflict, resolve it, and commit the final result.

On the master branch, create a new version of file with a couple additional lines in it and then commit it:

$ git checkout master

$ cat >> file Line 5 stuff

Line 6 stuff

^D

$ git commit -a -m"Add line 5 and 6"

Created commit 4d8b599: Add line 5 and 6

1 files changed, 2 insertions(+), 0 deletions(-)

Now, on the alternate branch, modify the same file differently. Whereas you made new commits to the master branch, the alternate branch has not progressed yet:

$ git checkout alternate Switched branch "alternate"

$ git show-branch

* [alternate] Add alternate's line 4 ! [master] Add line 5 and 6

+ [master] Add line 5 and 6

*+ [alternate] Add alternate's line 4

# In this branch, "file" left off with "Line 4 alternate stuff"

$ cat >> file

$ git commit -a -m"Add alternate line 5 and 6"

Created commit e306e1d: Add alternate line 5 and 6 1 files changed, 2 insertions(+), 0 deletions(-)

Let’s review the scenario. The current branch history looks like this:

$ git show-branch

* [alternate] Add alternate line 5 and 6 ! [master] Add line 5 and 6

Merge Examples | 123

--* [alternate] Add alternate line 5 and 6 + [master] Add line 5 and 6

*+ [alternate^] Add alternate's line 4

To continue, check out the master branch and try to perform the merge:

$ git checkout master Switched to branch "master"

$ git merge alternate Auto-merged file

CONFLICT (content): Merge conflict in file

Automatic merge failed; fix conflicts and then commit the result.

When a merge conflict like this occurs, you should almost invariably investigate the extent of the conflict using the git diff command. Here, the single file named file has a conflict in its content:

Line 4 alternate stuff ++<<<<<<< HEAD:file

The git diff command shows the differences between the file in your working direc-tory and the index. In the traditional diff command output style, the changed content is presented between <<<<<<< and =======, with an alternate between ======= and

>>>>>>>. However, additional plus and minus signs are used in the combined diff format to indicate changes from multiple sources relative to the final resulting version.

The previous output shows that the conflict covers lines 5 and 6, where deliberately different changes were made in the two branches. It’s then up to you to resolve the conflict. For now, simply edit the file to mirror this content:

$ cat file

If you are happy with the conflict resolution, you should git add the file to the index and stage it for the merge commit:

$ git add file

After you have resolved conflicts and staged final versions of each file in the index using git add, it is finally time to commit the merge using git commit. Git places you in your favorite editor with a template message that looks like this:

Merge branch 'alternate' Conflicts:

file

#

# It looks like you may be committing a MERGE.

# If this is not correct, please remove the file

# .git/MERGE_HEAD

# and try again.

#

# Please enter the commit message for your changes.

# (Comment lines starting with '#' will not be included)

# On branch master

# Changes to be committed:

# (use "git reset HEAD <file>..." to unstage)

#

# modified: file

#

As usual, the lines beginning with the octothorp (#) are comments and meant solely for your information while you write a message. All comment lines are ultimately elided from the final commit log message. Feel free to alter or augment the commit message as you see fit, perhaps adding a note about how the conflict was resolved.

When you exit the editor, Git should indicate the successful creation of a new merge commit:

$ git commit

# Edit merge commit message

Created commit 7015896: Merge branch 'alternate'

$ git show-branch

! [alternate] Add alternate line 5 and 6 * [master] Merge branch 'alternate'

- [master] Merge branch 'alternate' +* [alternate] Add alternate line 5 and 6

You can see the resulting merge commit using:

$ git log

Merge Examples | 125

Dans le document Version Control with Git (Page 140-144)