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

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.

主站蜘蛛池模板: 福泉市| 聊城市| 哈密市| 屯门区| 隆安县| 广平县| 开远市| 玉树县| 石台县| 亚东县| 象山县| 石渠县| 桃园县| 正定县| 东明县| 醴陵市| 湾仔区| 东港市| 柘荣县| 滨海县| 莒南县| 游戏| 安国市| 游戏| 泽普县| 乐都县| 镇坪县| 石城县| 永寿县| 楚雄市| 万宁市| 襄汾县| 共和县| 齐河县| 西藏| 广州市| 民县| 达拉特旗| 湄潭县| 林甸县| 丽江市|