Reputation: 28653
When merging a branch into another, it is possible to define the merge strategy like
git merge release -X ours
This applies the strategy "ours" globally when merging stuff from the release branch into the current branch. Is it possible to apply this strategy only on one specific file like
git merge release -X docs/release-notes.md ours
so that the "ours" strategy is only used when merging docs/release-notes.md file? Or is anybody aware of another option to achieve that?
Upvotes: 6
Views: 1290
Reputation: 41238
I answered a very similar problem in this answer
Using a wrapper around git-merge-file that I proposed there, you could do the thing you want with
git merge release
git-resolve-conflict --ours docs/release-notes.md
Here is the wrapper bash function 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
}
Upvotes: 1
Reputation: 4128
git merges operate on different states of the tracked content, not on individual files. Rephrasing, git does not see any fundamental difference between a commit touching two files or a commit touching one file.
There is therefore an expectation in a clean git workflow that there is a thematic coherence in commits and branching strategies. More specifically, it's more "gitty" to produce a commit that fixes a "subject" than a commit that fixes a specific file. It's more "gitty" to have branches that contain work done towards specific "topics" rather than branches addressing the development of specific files.
Relating this back to your question, without knowing too much about your codebase or git strategy, it's possible that the need to merge a specific branch differently according to the state of individual files indicates that the branching model might need a bit of polishing.
If you want the changes in the release branch but not the changes in the README.md file in the release branch then it's possible that the changes in README.md from release might need to be split out somehow so you can merge the release branch without merging changes to README.md. However given that the branch is called release I imagine you don't want to bang on it very hard at all.
If your need to merge from release but ignore README.md changes is recurrent, you might consider setting up a parallel branch to release like release-noreadme. Then you can bang on release-noreadme all you want, including massaging the README.md file to suit your needs, such that you can then merge from release-noreadme without worrying about tiptoeing around specific changes in specific files.
tl;dr: consider having a branch synced to release where you can iron out unwanted changes, then merge from that branch instead of release.
Upvotes: 1
Reputation: 2515
I don't think this is possible, if you look at the 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 there is no indication of options available, instead of subtree
strategy where it's 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.
Upvotes: 1