3.2 Git branch - new branch and merge

Original PathClick to open the link

3.2 Git branch - new branch and merge

Branch creation and merging

Let's look at a simple example of branch creation and branch merging. You may use a similar workflow in practice. You will go through the following steps:

  1. develop a website.

  2. To implement a new requirement, create a branch.

  3. Work on this branch.

At this point, you suddenly receive a call saying that there is a serious problem that needs to be fixed urgently. You will proceed as follows:

  1. Switch to your production branch.

  2. Create a new branch for this urgent task and fix it there.

  3. After the tests pass, switch back to the live branch, merge the patched branch, and finally push the changes to the live branch.

  4. Switch back to the branch you originally worked on and continue working.

new branch

First, we assume you are working on your project and already have some commits.

A simple commit history.
Figure 18. A simple commit history

Now, you've decided to fix issue #53 in the issue tracking system your company uses. To create a new branch and switch to that branch at the same time, you can run -ba git checkoutcommand with the parameter:

$ git checkout -b iss53
Switched to a new branch "iss53"

It is shorthand for the following two commands:

$ git branch iss53
$ git checkout iss53
Create a new branch pointer.
Figure 19. Create a new branch pointer

You continued to work on issue #53 and made some commits. During this process, the iss53branch is constantly advancing because you have already checked out to the branch (that is, your HEADpointer points to the iss53branch)

$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
The iss53 branch moves forward as the work progresses.
Figure 20. iss53 branch moving forward as work progresses

Now you get that call and there is an urgent issue waiting for you to resolve. With the help of Git, you don't have to mix this urgent problem with iss53the changes in , and you don't need to go to great lengths to revert the changes to the 53# problem, then add the changes to the urgent problem, and finally commit the changes to online branch. All you have to do is switch back to the masterbranch .

However, before you do this, keep an eye out for uncommitted changes in your working directory and staging area, which may conflict with the branch you are checking out and prevent Git from switching to that branch. The best way is to keep a clean state before you switch branches. There are a few ways to get around this (ie, stashing and commit amending), and we 'll see these two commands in stashing and cleaning. Now, let's say you've committed all your changes, you can switch back to the masterbranch :

$ git checkout master
Switched to branch 'master'

At this point, your working directory is exactly the same as it was before you started problem #53, and now you can focus on fixing urgent problems. Remember: when you switch branches, Git resets your working directory, making it look like it was back to the last commit you made on that branch. Git will automatically add, delete, and modify files to make sure your working directory looks exactly the same as when the branch was last committed.

Next, you want to fix this urgent problem. Let's create a hotfix branch for this urgent issue and work on that branch until the issue is resolved:

$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
 1 file changed, 2 insertions(+)
A hotfix branch based on the `master` branch.
Figure 21. Urgent problem branch based master on branch hotfix branch

You can run your tests, make sure your changes are correct, and then merge them back into your masterfork to deploy live. You can use the git mergecommand to achieve the above:

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)

When merging, you should have noticed the word "fast-forward". Since the commit pointed to by the current masterbranch is directly upstream of your current commit (the hotfix-related commit), Git simply moves the pointer forward. In other words, when you try to merge two branches, if you can go down one branch to reach the other branch, then when merging the two, Git will simply advance the pointer (move the pointer right), Because the merge operation in this case has no divergence to resolve - this is called "fast-forward".

Now that the latest changes are in the commit snapshot pointed to by the masterbranch , you can start publishing the fix.

`master` is fast-forwarded to `hotfix`.
Figure 22. master Fast forwarded to hotfix

After the solution to this urgent problem is released, you are ready to go back to the work you were doing before the interruption. However, you should delete the hotfixbranch , because you don't need it anymore - the masterbranch already points to the same location. You can use the command with -doptions git branchto delete branches:

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).

Now you can continue your work by switching back to the branch you were working on, which is the branch for issue #53 (the iss53 branch).

$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
Continue work on the `iss53` branch.
Figure 23. Continue work on iss53 branch

The work you did on the hotfixbranch was not included in the iss53branch. If you need to hotfixpull the changes made, you can use git merge masterthe command masterto merge the branch into the iss53branch, or you can wait until the iss53branch done its job before merging it back into the masterbranch.

merging of branches

Suppose you have fixed issue #53 and intend to merge your work into the masterbranch . To do this, you need to merge iss53branch into masterbranch, which is similar to what you did before merging hotfixbranches . You just need to checkout to the branch you want to merge into and run the git mergecommand :

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

This looks a little different than when you merged hotfixbranches earlier. In this case, your development history has diverged from an earlier point. Because masterthe commit the iss53branch a direct ancestor of the commit the branch is on, Git has to do some extra work. When this happens, Git will do a simple three-way merge using the snapshots ( C4and C5) pointed to by the ends of the two branches, and the working ancestors ( ) of those two branches.C2

The three snapshots used in a typical merge.
Figure 24. Three snapshots used in a typical merge

Instead of pushing the branch pointer forward, Git takes a new snapshot of the result of the three-way merge and automatically creates a new commit pointing to it. This is called a merge commit, and it's special in that it has more than one parent commit.

A merge commit.
Figure 25. A merge commit

It should be pointed out that Git will decide which commit to choose as the best common ancestor and use it as the basis for merging; this is different from older CVS systems or Subversion (before 1.5), where these ancient versions managed In the system, users need to choose the best merge basis by themselves. This advantage of Git makes merge operations much simpler than other systems.

Now that your changes have been merged in, you no longer need to iss53branch . You can now close this quest in the quest tracker and delete this branch.

$ git branch -d iss53

Branch merging when conflicts are encountered

Sometimes merge operations don't go so smoothly. If you make different changes to the same part of the same file in two different branches, Git won't be able to merge them cleanly. If your change to question #53 and hotfixrelated changes both refer to the same part of the same file, you will have a merge conflict when merging them:

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

At this point Git did the merge, but did not automatically create a new merge commit. Git will pause and wait for you to resolve the merge conflicts. You can use the git statuscommand to view files that are in an unmerged state because they contain a merge conflict:

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

Any files that are pending resolution because they contain merge conflicts are identified as unmerged. Git adds standard conflict resolution markers to conflicting files, so that you can open the conflicting files and resolve them manually. Conflicting files will contain special sections that look like this:

<<<<<<< HEAD:index.html
<div id="footer">contact : [email protected]</div>
=======
<div id="footer">
 please contact us at [email protected]
</div>
>>>>>>> iss53:index.html

This HEADmeans that the version indicated by (that is, masterwhere your branch is, since you checked out to this branch when you ran the merge command) is in the upper half of this section ( =======the upper half), and the iss53branch indicated by version is in =======the bottom half of . To resolve conflicts, you must choose to use one of the two parts =======split by , or you can merge the content yourself. For example, you can resolve the conflict by replacing this content with the following:

<div id="footer">
please contact us at [email protected]
</div>

The conflict resolution above preserves only the modifications of one of the branches, and <<<<<<<the , ,======= and lines are completely removed. >>>>>>>After you have resolved conflicts in all files, use the git addcommand to mark it as conflict resolved. Once these otherwise conflicting files are staged, Git marks them as conflict resolved.

If you want to use a graphical tool to resolve conflicts, you can run git mergetoolthis command, which will launch a suitable visual merge tool for you and walk you through the conflict resolution step by step:

$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):

If you want to use a merge tool other than the default one (here Git uses opendiffas the default merge tool, since the author runs the program on a Mac), you can do this in "one of the following tools" See all supported merge tools after the sentence. Then enter the name of the tool you like.

Note

If you need more advanced tools to resolve complex merge conflicts, we 'll cover more about branch merging in Advanced Merging.

After you exit the merge tool, Git will ask if the merge was successful. If you answer yes, Git will stage those files to show that the conflicts are resolved: you can run again git statusto confirm that all merge conflicts are resolved:

$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html

If you are satisfied with the result, and are sure that the conflicting files have been staged, you can enter git committo complete the merge commit. By default the commit message looks like this:

Merge branch 'iss53'

Conflicts:
    index.html
#
# 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. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#	modified:   index.html
#

If you feel that the above information is not sufficient to fully reflect the branch merge process, you can modify the above information to add some details to help future readers reviewing this merge, tell them how you resolved the merge conflict, and why. .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325596441&siteId=291194637