官术网_书友最值得收藏!

Forcing a merge commit

If you are reading this book, you might have seen a lot of basic examples of software delivery chains and branching models. It is very likely that you have been trying to use different strategies and found that none of them completely supports your scenario, which is perfectly fine as long as the tool can support your specific workflow.

Git supports almost any workflow. I have often encountered a situation that requires a merge commit while merging a feature, even though it can be done with a fast-forward merge. Those who requested it often use it to indicate that you have actually merged in a feature and want to store the information in the repository.

Tip

Git has fast and easy access to all the commit messages, so the repository should be used as a journal, not just a backup of the source code.

Getting ready

Start by checking out a local branch remoteOldbugFix that tracks origin/stable-3.1:

$ git checkout -b remoteOldBugFix --track origin/stable-3.1
Branch remoteOldBugFix set up to track remote branch stable-3.1 from Switched to a new branch 'remoteOldBugFix'

How to do it...

The following steps will show you how to force a merge commit:

  1. To force a merge commit, you need to use the --no-ff flag, no-ff is no fast forward. We will also use --quiet for minimizing the output and --edit to allow us to edit the commit message. Unless you have a merge conflict, Git will create the merge commit for you automatically:
    $ git merge origin/stable-3.2 --no-ff --edit --quiet
    Auto-merging 
    org.eclipse.jgit.test/tst/org/eclipse/jgit/test/resources/SampleDat
    Removing org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GCTe
    Auto-merging org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target
    
  2. The commit message editor will open, and you can write a commit message. Closing the editor creates the merge commit and we are done.
  3. To verify this, you can reset back to origin/stable-3.1 and perform the merge without the --no-ff flag:
    $ git reset --hard remotes/origin/stable-3.1
    HEAD is now at da6e87b Prepare post 3.1.0 builds
    
  4. Now, perform the merge with the following command:
    $ git merge origin/stable-3.2 --quiet
    
  5. You can see the difference using Gitk. The following screenshot shows the fast forward merge, as you can see our remoteOldBugFix branch points to origin/stable-3.2:
  6. The following screenshot shows the merge commit we forced Git to create. My branch remoteOldBugFix is ahead of remotes/origin/stable-3.2, and the I performed the commit:

There's more…

Although most branching scenarios expect you to completely merge branches, there are situations when while working in a real environment, you only need to merge specific pieces of one branch into another branch. Using the --no-commit option, Git will make the merge and stop before committing, allowing you to modify and add files to the merge commit before committing.

As in example, I have been working with projects where versions of strings have been updated in the feature branch but not in the master branch. So, an automatic merge into master would replace the current version string used on the master branch, which in my case was not the intention:

  1. Start by checking out a local remotePartlyMerge branch that tracks origin/stable-2.3:
    $ git checkout -b remotePartlyMerge --track origin/stable-2.3
    Branch remotePartlyMerge set up to track remote branch stable-2.3 from origin.
    Switched to a new branch 'remotePartlyMerge'
    
  2. Then, to create the merge and allow you to decide what will be part of the commit, you can use --no-commit:
    $ git merge origin/stable-3.1 --no-ff --no-commit
     a lot of output….
     Automatic merge went well; stopped before committing as requested
    
  3. Again, Git is very informative; you can see from the output that everything went well and Git stopped before committing as requested. To continue, let's pretend we didn't want the org.eclipse.jgit.test directory to be part of the merge commit. To achieve this, we reset the directory using the git reset <path> command:
    $ git reset ./org.eclipse.jgit.test
    Unstaged changes after reset:
    M org.eclipse.jgit.test/.gitignore
     A lot of output
    M org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoCRLFOutputStreamTest.java
    
  4. You can see from the output that you have unstaged changes after the reset; this is exactly what we want. You can check which unstaged changes you have by running git status. Now, we will just finish the merge:
    $ git commit -m "Merging stable-3.1 without org.eclipse.jgit.test"
    [remotePartlyMerge 396f32a] Merging stable-3.1 without 
    
  5. The merge commit is complete. If you run a git status command now, you will still have the unstaged changes in you work area. To verify whether the result is as expected, we can use diff for this with git diff to show that the file is as it is on the origin/stable-2.3 branch:
    $ git diff origin/stable-2.3 ./org.eclipse.jgit.test
    
  6. There is no output from diff; this is the expected result. We are telling the diff command to diff our current HEAD commit and branch origin/stable-2.3, and we only care about the diffs in ./org.eclipse.jgit.test:

    Tip

    If you don't specify HEAD, you will diff with your current WA, and the diff command will have a lot of output as you have unstaged changes.

主站蜘蛛池模板: 股票| 普宁市| 景洪市| 罗平县| 陆河县| 宝丰县| 汝南县| 旬阳县| 屏南县| 和林格尔县| 蚌埠市| 甘泉县| 铜陵市| 新乡县| 伽师县| 江山市| 阆中市| 麻城市| 白水县| 保定市| 闸北区| 桐梓县| 博客| 丰原市| 集安市| 双辽市| 洮南市| 镇远县| 成都市| 乐业县| 昌江| 阜康市| 福鼎市| 永丰县| 定陶县| 高青县| 芜湖县| 宁蒗| 民丰县| 崇义县| 镇沅|