This is part of the “Git While You Sit” series, a play on Google’s Testing on the Toilet. It’s intended to fit on a printed page. Currently Chrome doesn’t seem to correctly print columns, but Firefox does.
Sometimes, git does something unexpected while merging or rebasing. It might seem like git misunderstood a rename, but it’s far more likely that git did the “right” thing after all. Here are a couple of examples I’ve seen recently.
When rebasing, conflicts might occur before renames:
o---o---E---F---G (master) \ A---B---RENAME---C (feature *)
When the current branch is feature, and running
git rebase master, what happens is that the commits from
feature will be
G in order -
C. If a conflict occurs in
B, in a file that was later renamed (in
RENAME), conflict resolution will have to happen using the original name. If there was a massive reworking, it might be simpler and more sensible to merge in this case.
It wasn’t a rename, it was a copy.
--o---E----F [MODIFY]----G (master) \ \ A---B [COPY]---C---D---M (feature *)
In this case, the user thought he renamed
B [COPY]. Then, when he merged
feature, he expected that the modifications in
F [MODIFY] would, as part of the merge in
M, be applied to
dir2/file.xml. This would indeed have happened if
B had a move operation. However, it doesn’t make sense for git to merge the changes from a copy of a file, so it didn’t.
The fix here was to undo the merge:
$ git reset --hard D
…and then edit the commit:
$ git rebase -i A
edit instead of
pick. Amend the commit for
B so that it doesn’t just create
dir2/file.xml, but also deletes
dir1/file.xml. If it’s indeed the same file (or has very similar contents), this will be automatically detected as a rename during
It should be noted that git doesn’t track renames (or copies) at all during commits. It only figures out that they happened retroactively when it’s relevant (
diff…), by comparing the contents. This is why those operations have options like
find-copies and even