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

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.

主站蜘蛛池模板: 肇东市| 北票市| 阳西县| 徐州市| 赣榆县| 石门县| 江北区| 永兴县| 大余县| 佛山市| 瑞金市| 双辽市| 禄劝| 丘北县| 漳州市| 滦平县| 宿州市| 马公市| 云南省| 扎赉特旗| 青海省| 县级市| 榆中县| 农安县| 望谟县| 朝阳区| 石城县| 津市市| 凤山市| 石台县| 宝鸡市| 赤城县| 宜阳县| 梅州市| 增城市| 和硕县| 左权县| 西乡县| 若羌县| 罗平县| 河池市|