threads / bug / 22282

Branch merge bug

Subject: Branch merge bug

## tl;dr

5 messages between Jan 19, 2010 and Jan 19, 2010.

replies: 4people: 3as markdown or json

Ramkumar Ramachandra· Jan 19, 2010, 07:22 UTC · lore

A friend showed me this reduced test case. It seems to work fine with bzr and hg. Is this a git bug?

>: git --version
git version 1.6.3.1
>: git init
Initialized empty Git repository in /Users/lut4rp/Code/tester/.git/
>: echo asdjhaskd >fil
>: git add fil
>: git cm 'initial commit'
[master (root-commit) 9983161] initial commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 fil
>: git branch new
>: git branch
* master
  new
>: git mv fil fila
>: git status

# On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: fil -> fila #

>: git cm 'renamed to fila'
[master 9de0953] renamed to fila
 1 files changed, 0 insertions(+), 0 deletions(-)
 rename fil => fila (100%)
>: git co new
Switched to branch 'new'
>: git rm fil
rm 'fil'
>: echo asjhdajkhsdkajhs >fila
>: git add fila
>: git cm 'renamed, heavily modified'
[new 5914271] renamed, heavily modified
 2 files changed, 2 insertions(+), 1 deletions(-)
 delete mode 100644 fil
 create mode 100644 fila
>: git co master
Switched to branch 'master'
>: git merge new

CONFLICT (rename/delete): Rename fil->fila in HEAD and deleted in new Automatic merge failed; fix conflicts and then commit the result.

>: cat fila

asdjhaskd #### Still the master branch's content, `merge` apparently did nothing.

>: git show :2:fila
asdjhaskd
>: git show :3:fila

fatal: ambiguous argument ':3:fila': unknown revision or path not in the working tree. Use '--' to separate paths from revisions

>: git show new:fila

asjhdajkhsdkajhs ajksh askjdhaksdh kajshdk asd

Michael J Gruber· Jan 19, 2010, 12:07 UTC · re: Ramkumar Ramachandra · lore

Re: Branch merge bug

Ramkumar Ramachandra venit, vidit, dixit 19.01.2010 08:22:
> A friend showed me this reduced test case. It seems to work fine with
> bzr and hg. Is this a git bug?

It's not a bug, it's a feature. Git does not track renames. It tracks content and detects renames when necessary. Knowing that it is easy to construct examples on which git merge "fails", such as the one you present.

A file which is changed completely is not a renamed file, it's a new one under the same name. Whether the committer meant to create a new file (using the same name by accident or on purpose) or whether it is really a heavily modified and renamed version - who knows? Git doesn't, and cannot, and it leaves that decision up to you.

If you really mean to modify and rename an existing file, then tell Git so:

git mv fil fila git commit -m 'we need a new name'

instead of your 'git rm fil' will record your intentions (not only for Git, but also for everyone else reading your log, such as you a year from now) and will make the merge succeed.

Michael
Andreas Krey· Jan 19, 2010, 12:39 UTC · re: Michael J Gruber · lore

Re: Branch merge bug

On Tue, 19 Jan 2010 13:07:28 +0000, Michael J Gruber wrote: ...

Show 8 quoted lines
> If you really mean to modify and rename an existing file, then tell Git so:
> 
> git mv fil fila
> git commit -m 'we need a new name'
> 
> instead of your 'git rm fil' will record your intentions (not only for
> Git, but also for everyone else reading your log, such as you a year
> from now) and will make the merge succeed.

The intention would only be known informally in the commit message, as 'git mv' just removes the old and adds the new file, and still leave the work to the rename detection.

Indeed, changing
  >: git rm fil
  >: echo asjhdajkhsdkajhs >fila
  >: git add fila
to
  >: git mv fil fila
  >: echo asjhdajkhsdkajhs >fila
  >: git add fila
and even to
  >: git mv fil fila
  >: git cm 'other mv'
  >: echo asjhdajkhsdkajhs >fila
  >: git add fila
still gives the same rename/delete conflict because the rename
detection does not look at every single commit but only at
the total changes.
Which is actually good; when someone does
  cp prog.c prog.cpp
  git add prog.cpp && git commit
  vi prog.cpp --make-compile-again && git commit -a
  git rm prog.c && git commit

it is still seen as a rename prog.c->prog.cpp even though both existed in parallel for some commits.

Andreas
Michael J Gruber· Jan 19, 2010, 13:58 UTC · re: Andreas Krey · lore

Re: Branch merge bug

Andreas Krey venit, vidit, dixit 19.01.2010 13:39:
Show 31 quoted lines
> On Tue, 19 Jan 2010 13:07:28 +0000, Michael J Gruber wrote:
> ...
>> If you really mean to modify and rename an existing file, then tell Git so:
>>
>> git mv fil fila
>> git commit -m 'we need a new name'
>>
>> instead of your 'git rm fil' will record your intentions (not only for
>> Git, but also for everyone else reading your log, such as you a year
>> from now) and will make the merge succeed.
> 
> The intention would only be known informally in the commit message,
> as 'git mv' just removes the old and adds the new file, and still
> leave the work to the rename detection.
> 
> Indeed, changing
>   >: git rm fil
>   >: echo asjhdajkhsdkajhs >fila
>   >: git add fila
> to
>   >: git mv fil fila
>   >: echo asjhdajkhsdkajhs >fila
>   >: git add fila
> and even to
>   >: git mv fil fila
>   >: git cm 'other mv'
>   >: echo asjhdajkhsdkajhs >fila
>   >: git add fila
> still gives the same rename/delete conflict because the rename
> detection does not look at every single commit but only at
> the total changes.

Well, the solution I proposed (mv + commit rather than rm) certainly works for me, I tested it before. I have diff.renames=copies in my config but I don't think it should matter.

Michael

← back to recent threads