titi25
titi25

Reputation: 25

How does git-merge deal with binary files

Let's consider this situation:

      o---o---o      slave
     /         \
o---o---B---o---o    master

I have a bunch of binary files. Some of them did not change in either slave or master, some other changed on slave.

During the merge:

git checkout master
git merge slave

Git showed me this:

warning: Cannot merge binary files: foo.bin (HEAD vs. foo)
Auto-merging: foo.bin
CONFLICT (content): Merge conflict in foo.bin
Automatic merge failed; fix conflicts and then commit the result.

Analysis:

foo changed on both sides. I agree that Git ask me to solve the conflict. However, bar changed only on the master and Git didn't ask me anything. He decided to take the change from master while I wanted him to consider slave instead.

How can I have a better control on how git merge binary files?

Upvotes: 2

Views: 1102

Answers (1)

nowox
nowox

Reputation: 29066

Git did not ask anything because you made the change on foo and you should be aware that this change will goes straight after the merge if nobody changed this file on the slave branch.

Let's go trough this simple example:

  o-- slave
 /   \
o--o--o master
^ origin 

You can reproduce it with this:

git init
dd if=/dev/urandom of=foo bs=100k count=1
dd if=/dev/urandom of=bar bs=100k count=1
git add .
git commit -m "Added binary files foo and bar"
git branch origin

git checkout -b slave
dd if=/dev/urandom of=foo bs=100k count=1
git commit -m "Modified foo" .

git checkout master
dd if=/dev/urandom of=bar bs=100k count=1
git commit -m "Modified bar" .

Once you are read do do the merge, you will probably do:

git checkout master
git merge slave

Merge made by the 'recursive' strategy.
 foo | Bin 102400 -> 102400 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

You notice that git noticed the change about foo but nothing about bar. It's because bar did not change on the slave branch.

If you wish to keep the bar from slave. You need to prevent git concluding the merge for you. You can do this:

git checkout master
git merge slave --no-commit
git checkout slave bar # I want to keep bar from slave
git commit -m "Commit successuful"

Later you can check if everything is ok:

git diff --stat master~1 origin
git diff --stat slave origin
git diff --stat master slave

I hope it clarifies a bit...

Upvotes: 1

Related Questions