Is it possible to exclude specific commits when doing a git merge?

Let's say that I want to merge from a release branch to the master branch and there are some commits in the release branch that I don't want to include in the master branch. Is there a way to do the merge so that one or more of those commits will not be merged?

My strategy so far is to do the following (in master):

git merge --no-commit release-branch
# Resolve conflicts and apply reverse patch of the commits that I don't want included
git commit # Edit commit message so that it lists the commits that have been reverse-patched

Is there a better way to do this?


Create a new branch, rebase the branch interactively and drop commits you don't want, and then merge that.

You can't take changes out of the middle of a branch without rehashing, but the right thing will happen when it sees the same changes in a later merge (eg from cherry-picking and what-not).


I've found a solution that works for me in the Pro Git book.

Let's say you want to exclude the file config.php .

On branch A:

  • Create a file named .gitattributes in the same dir, with this line: config.php merge=ours . This tells git what strategy to use when merging the file. In this case it always keep your version, ie. the version on the branch you are merging into.

  • Add the .gitattributes file and commit

  • On branch B: repeat steps 1-2

    Try merging now. Your file should be left untouched.


    If you have a support branch where you fix bugs and build new versions. On master you have the next version where you also build new versions frequently.

    Every time you build a new version you change the version in some file, commit that new file, create a tag and push. Now merges from support to master will always have conflicts in the file containing the version info.

    If the file containing the version information only contains the version information, you can go with the answer of fcurella. But if it does indeed may also contain mergeable information (pom.xml, gradle.properties, MANIFEST.MF, ...), you must perform some extra action.

    Lets use the following example

          C---D*---E---F* support
         /
    A---B---G---H*---I master
    

    where commits with stars contain only changes due to version changes that should be ignored during merge.

    To merge support into master without merge-conflicts due to the version builds, you can do either of the following:

    Multiple merge commits

    git checkout master
    git merge C
    git merge D -s ours
    git merge E
    git merge F -s ours
    

    With the -s ours argument we are telling git to only record a merge without altering the workspace. This is comparable to the --record-only option of svn.

    The above will result in the following layout

          -------------C---D*---E---F* support
         /                        
    A---B---G---H*---I---J---K----L---M master
    

    One merge commit using cherry-pick

    git checkout master
    git merge support -s ours --no-commit
    git cherry-pick C E --no-commit
    git commit -m 'merged support into master'
    

    first we are starting a merge but only record that we are merging, without altering the workspace and without doing the merge commit. Then we are cherry-picking the commits to merge, again without commit. Finally we are committing the merge.

    The above will result in the following layout

          C---D*---E---F* support
         /              
    A---B---G---H*---I---J master
    

    One could even automate the cherry-picking.

    git checkout master
    git merge support -s ours --no-commit
    for id in `git log support --reverse --not HEAD --format="%H [%an] %s" |
      grep -v "bump version" |
      sed "s/(w*)s.*/1/g"`
    do
      git cherry-pick --no-commit $id
    done
    git commit -m 'merged support into master'
    
    链接地址: http://www.djcxy.com/p/44832.html

    上一篇: 我可以在不包含它的情况下调用Ruby模块上的实例方法吗?

    下一篇: 执行git合并时可以排除特定的提交吗?