git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steven Grimm <koreth@midwinter.com>
To: Theodore Tso <tytso@mit.edu>
Cc: Martin Langhoff <martin.langhoff@gmail.com>,
	Git Mailing List <git@vger.kernel.org>
Subject: Directory renames (was Re: blame follows renames, but log doesn't)
Date: Tue, 19 Jun 2007 11:28:28 -0700	[thread overview]
Message-ID: <4678204C.6050409@midwinter.com> (raw)
In-Reply-To: <4677A7EF.500@midwinter.com>

Directory renames can break in more cases than just adding new files. 
Here's a demonstration based on a situation I ran into a few minutes ago 
on a real-world project.

$ git init
$ mkdir a
$ echo some contents > a/file1
$ echo other contents > a/file2
$ git add a
$ git commit -m "initial commit"

So far so good. Now there's a revision where the files happen to be 
identical. (On a new branch for later convenience.)

$ git checkout -b modifybranch
$ echo other contents > a/file1
$ git commit -a -m "commit that makes both files identical"

Now we rename the directory. (Again, the new branch will be used later.)

$ git checkout -b renamebranch
$ git mv a b
$ git commit -m "rename directory"

Make a change to file2.

$ echo more contents from renamebranch >> b/file2
$ git commit -a -m "add contents to file2"

Where did file2's contents come from?

$ git blame b/file2
a7dbcfdc a/file1 (Steven Grimm 2007-06-19 10:36:20 -0700 1) other contents
69a87194 b/file2 (Steven Grimm 2007-06-19 10:43:29 -0700 2) more contents

Which is wrong. The history of file2 has nothing to do with the history 
of file1, but git blame thinks it does. However, that's not what blew up 
on me in my real-world test; it gets better. Let's say one of the files 
changed in a different branch.

$ git checkout master
$ echo a change to file2 in master >> a/file2
$ git commit -a -m "file2 changed"

$ git merge renamebranch
Removed a/file1
Merge made by recursive.
 a/file1            |    1 -
 a/file2 => b/file1 |    0
 b/file2            |    2 ++
 3 files changed, 2 insertions(+), 1 deletions(-)
 delete mode 100644 a/file1
 rename a/file2 => b/file1 (100%)
 create mode 100644 b/file2

And this is just completely broken. What it *should* do is give me 
b/file1 with "other contents" from renamebranch, and b/file2 with a 
merge conflict since I added a different line to it in each branch. 
Instead, the merge succeeds with no conflict and applies the change in 
my current branch to the wrong file:

$ cat b/file1
other contents
a change to file2 in master
$ cat b/file2
other contents
more contents from renamebranch

There's one more variation on this theme that's broken in a similar but 
not identical way (this didn't happen in my real-world scenario but I 
ran into it while coming up with the above test case):

$ git checkout modifybranch
$ echo a change to file2 in modifybranch >> a/file2
$ git commit -a -m "a change in modifybranch"
$ git merge renamebranch
CONFLICT (delete/modify): a/file2 deleted in renamebranch and modified 
in HEAD. Version HEAD of a/file2 left in tree.
Automatic merge failed; fix conflicts and then commit the result.

This should definitely be a merge conflict, but it shouldn't be *this* 
merge conflict. What I'd expect here would be b/file1 == "other 
contents" and b/file2 with conflict markers.

$ ls a b
a:
file2

b:
file1   file2
$ cat a/file2
other contents
a change to file2 in modifybranch
$ cat b/file1
other contents
$ cat b/file2
other contents
more contents from renamebranch

In other words, no conflict markers at all, and I still have the old 
directory "a" with one of its two files in original form, but not the 
other file.

Hope that's illuminating or at least interesting to someone.

-Steve

  reply	other threads:[~2007-06-19 18:28 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-19  1:10 blame follows renames, but log doesn't Martin Langhoff
2007-06-19  1:34 ` Sam Vilain
2007-06-19  7:19 ` Theodore Tso
2007-06-19  8:31   ` Martin Langhoff
2007-06-19  8:39   ` Junio C Hamano
2007-06-19  9:54   ` Steven Grimm
2007-06-19 18:28     ` Steven Grimm [this message]
2007-06-20 20:18       ` Directory renames (was Re: blame follows renames, but log doesn't) Sam Vilain
2007-06-20 20:59         ` Steven Grimm
2007-06-20 22:11     ` blame follows renames, but log doesn't Jakub Narebski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4678204C.6050409@midwinter.com \
    --to=koreth@midwinter.com \
    --cc=git@vger.kernel.org \
    --cc=martin.langhoff@gmail.com \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).