5

In another question it is recommended to use .gitattributes in order to keep the file tracked but not merged in different branch, but my use case below seems not working..

mkdir git
cd git
git init
echo "B" > b.txt
git add b.txt 
git commit -m 'Initial commit'

echo "b.txt merge=keepMine" > .gitattributes
git add .gitattributes 
git config merge.keepMine.name "always keep mine during merge"
git config merge.keepMine.driver "keepMine.sh %O %A %B"
git commit -m 'Ignore b.txt'

git checkout -b test # Create a branch
git checkout master # Back to master and make change
echo "Only in master" > b.txt
git commit -a -m 'In master'

git checkout test
git merge master # The change in b.txt is being merged...

Any idea? Thanks..

Community
  • 1
  • 1
Ryan
  • 9,231
  • 23
  • 77
  • 133
  • This looks like a strange desire to merge everything but one file. It's against git ideology when all the content is maintained as a whole. Could you explain the use case? Why do you need it? – Ilya Ivanov Jun 06 '12 at 14:26

2 Answers2

1

I suspect that it did not work because there were no merge conflicts.

However, I can confirm that git merge master --strategy=ours works as expected.

This might be what you're looking for: How to tell Git to always select my local version

If you want to specify a specific merge strategy for a specific file, what you really need to do is to write a custom merge driver and specify in your repository configuration that you want that merge driver to be used as the default. See the link above on how to use it.

In short, the reason it does not work in your use case is because your use case is not a merge. It only portrays a bunch of changes on master with a temporary branch called test being created and then moved up to master later on. You never actually introduce a commit while you're on the test branch.

Community
  • 1
  • 1
Carl
  • 39,407
  • 10
  • 74
  • 99
  • git merge master --strategy=ours work expected, but sometimes we just need to apply this strategy for a particular file, not the whole tree. Seems it is a bug? – Ryan May 28 '12 at 04:34
  • 1
    No it's not a bug. In your question, the merge is too easy, which is why Git does not try an alternate merge strategy. Here's a simple experiment - introduce different changes to the same line on each branch and then try and merge. This would create a conflict and then git would use the attributes file to select yours. – Carl May 28 '12 at 21:51
  • so is it possible to stop the auto merge (only per file, not global) – Ryan May 29 '12 at 01:45
  • You need to use a custom merge driver. – Carl May 29 '12 at 22:30
  • I think the method you're looking for is: introduce a conflict. This would force git to fall back on the .gitattributes file. It would then use your version. This behavior would continue every time there is a conflict, thereby making sure your version is the one that is in master. – Carl Jun 04 '12 at 20:31
  • I should probably also mention that in your use case, all changes are being made in master. You create test and then switch away from it without making any changes. Therefore, from git's point of view, test is nothing but a pointer to a series of commits that were created on master. Therefore, when you merge, the pointer is moved up and b is changed, as it should be, because all changes were made in master. If you really want to check, you need to introduce a conflict - check in a change to test before you switch back to master. – Carl Jun 07 '12 at 03:04
0

The custom merge driver mentioned by carleeto is illustrated in "Tell git not to merge binary files but to choose":

You can declare in a .gitattributes file the kind of merge you want:

echo yourConfigFile merge=keepMine > parentDirectory\.gitattributes
Community
  • 1
  • 1
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • I have updated my command logs above, still not working. At least git should prompt me for the missing `keepMine.sh` but seems it just simply ignored.. – Ryan May 30 '12 at 09:53
  • @Yoga: right, it would not work in your case where there is no conflict (only new modifications from `master` branch) – VonC May 30 '12 at 10:52
  • yes, so seems the only way is to use `git merge master --strategy=ours` – Ryan May 30 '12 at 13:25