Apply git merge stategy for only one file?

When merging a branch into another, you can define a merge strategy, for example

git merge release -X ours 

This will apply the β€œours” strategy worldwide when merging material with an output branch into the current branch. Is it possible to apply this strategy to only one specific file, for example,

 git merge release -X docs/release-notes.md ours 

so that the "ours" strategy is used only when merging the docs / release-notes.md file? Or does anyone know of another option to achieve this?

+4
source share
3 answers

I do not think it is possible if you look for help

  ours This option forces conflicting hunks to be auto-resolved cleanly by favoring our version. Changes from the other tree that do not conflict with our side are reflected to the merge result. For a binary file, the entire contents are taken from our side. This should not be confused with the ours merge strategy, which does not even look at what the other tree contains at all. It discards everything the other tree did, declaring our history contains all that happened in it. 

you can see that there are no options available, instead of the subtree strategy, where possible

  subtree[=<path>] This option is a more advanced form of subtree strategy, where the strategy makes a guess on how two trees must be shifted to match with each other when merging. Instead, the specified path is prefixed (or stripped from the beginning) to make the shape of two trees to match. 
+1
source

git merges work with different states of the content being tracked, and not with individual files. To paraphrase, git does not see a fundamental difference between a commit involving two files or a commit involving one file.

Therefore, there is an expectation in git workflow that there is a thematic consistency in commit and branch strategies. More specifically, it is more "gitty" to create a commit that commits a "subject" than a commit that commits a specific file. It is more "gitty" to have branches that contain work performed on specific "topics" rather than branches aimed at developing specific files.

Referring back to your question, without knowing too much about your code or git strategy, it is possible that the need to merge a particular branch in different ways depending on the state of individual files indicates that the branching model may need a little polishing.

If you need changes to the release branches, but not changes to the README.md file in the release branch, it is possible that the changes to README.md from the release may need to be split so that you can merge the release without merging the changes to README.md . However, given that the branch is called release, I assume that you do not want to hit it hard.

If you need to merge with the release, but ignore the README.md changes, this is a repeat, you might consider creating a parallel branch for the release, for example release-noreadme. You can then hack everything you want into release-noreadme, including massaging the README.md file according to your needs, so that you can merge with release-noreadme without worrying about tiptoe exchanging specific changes in certain files.

tl; dr: consider synchronizing a branch where you can smooth out unwanted changes, then merge from that branch instead of releasing.

+1
source

I answered a very similar problem in this answer

Using the wrapper around git-merge-file that I suggested there, you can do what you want,

 git merge release git-resolve-conflict --ours docs/release-notes.md 

Here is the bash shell that I wrote:

 git-resolve-conflict() { STRATEGY="$1" FILE_PATH="$2" if [ -z "$FILE_PATH" ] || [ -z "$STRATEGY" ]; then echo "Usage: git-resolve-conflict <strategy> <file>" echo "" echo "Example: git-resolve-conflict --ours package.json" echo "Example: git-resolve-conflict --union package.json" echo "Example: git-resolve-conflict --theirs package.json" return fi git show :1:"$FILE_PATH" > ./tmp.common git show :2:"$FILE_PATH" > ./tmp.ours git show :3:"$FILE_PATH" > ./tmp.theirs git merge-file "$STRATEGY" -p ./tmp.ours ./tmp.common ./tmp.theirs > "$FILE_PATH" git add "$FILE_PATH" rm ./tmp.common rm ./tmp.ours rm ./tmp.theirs } 
0
source

All Articles