问题
I'm using a merge strategy in .gitattributes to preserve files during merges. I also used git config --global merge.ours.driver true;
to set the driver in my config (I checked the config for [merge "ours"] driver = true
and it is there).
My merge strategy is set correctly:
src/public/bundle.js merge=ours
src/public/main.min.css merge=ours
server/middlewares/https_redirect.js merge=ours
Yet when I merge, I am still getting the files from the branch being merged.
What could I be doing wrong?
回答1:
What you need is a custom "merge strategy"
See git: How do I add a custom merge strategy? (Edit to add: writing a merge strategy handler is much harder than writing a custom merge driver. But it's the only way to get the behavior I believe you want.)
What you have is a custom merge driver
Your setup does seem correct (albeit a bit "cheat-y", using /bin/true
or the shell built in equivalent to just leave the %A
file alone and exit successfully :-) ). But I suspect you're running afoul of the usual problem, which is:
Git only invokes a three-way merge driver if there are two diffs to combine.
That is, assume we're actually doing a three-way merge. This means there is a merge base version of some file, such as src/public/bundle.js
, since there is a merge-base commit that differs from the two branch tip commits. We're on some branch, whose tip commit is 1111111
, and we're merging some other commit whose hash ID is 2222222
and git merge-base 1111111 2222222
is bbbbbbb
. Hence Git has done git diff bbbbbbb 1111111
to get the change from base to ours, and git diff bbbbbbb 2222222
to get the change from base to theirs.
The base version of src/public/bundle.js
is the one in commit bbbbbbb
. But, maybe the diff from bbbbbbb:src/public/bundle.js
to 1111111:src/public/bundle.js
is empty, while the diff from bbbbbbb:src/public/bundle.js
to 2222222:src/public/bundle.js
is non-empty.
In this case, Git doesn't do a three-way merge of the file. It doesn't have to, so it doesn't bother. It never invokes your custom merge driver at all; it just grabs the 2222222
version of the file and says "I'm done, all merged!"
This is true whether you let Git use its own built-in merge code, or specify a custom driver: it never bothers invoking the merge code at all when it can—or thinks it can—get away without doing a merge at all. It just takes the one changed version and calls it good.
(Personally, I think this is wrong / a bug, but Git has done it this way for many years, and the Git folks seem not inclined to change it.)
来源:https://stackoverflow.com/questions/41640602/gitattributes-merge-strategy-not-working