Git rebase with renamed files
You can rebase your branch while detecting renames like so:
git rebase --strategy-option="rename-threshold=10" master
Edit: Since Git 2.8.0, the term 'rename-threshold' has been deprecated in favor of 'find-renames'.
At the moment I'm using Git 2.7.4, and so I could only actually verify that the above command worked in my case — you may need to use the term 'find-renames' if the above command doesn't work in your case on your newer version of Git...
In this example,
- the current branch is rebased onto
master
- the rename threshold of
10%
is specified - changes in
master
to the original files will be placed in the new (renamed) files (as opposed to running merelygit rebase master
). - note how the syntax is different compared to similar rename-detection functionality found in the
git diff
,git log
, andgit merge
commands
The git rebase documentation isn't very clear about this rename-detection aspect in particular.. I thought I read in another command somewhere, that the term "rename-threshold" was deprecated, though in this context find-renames
did not seem to work as a synonym -- so if anybody knows about a better way to run this same command, please mention so :)
In addition of the find-rename
rebase/merge strategy, with Git 2.29 (Q4 2020), the commit labels used to explain each side of conflicted hunks placed by the sequencer machinery have been made more readable by humans.
See commit 7d056de (12 Aug 2020) by Elijah Newren (newren
).
(Merged by Junio C Hamano -- gitster
-- in commit 6cceea1, 19 Aug 2020)
sequencer
: avoid garbled merge machinery messages due to commit labelsSigned-off-by: Elijah Newren
Reviewed-by: Taylor Blau
Acked-by: Johannes Schindelin
sequencer's
get_message()
exists to provide good labels on conflict hunks;
see commits
- d68565402a ("revert: clarify label on conflict hunks", 2010-03-20, Git v1.7.1-rc0)
- bf975d379d ("cherry-pick, revert: add a label for ancestor", 2010-03-20, Git v1.7.1-rc0)
- 043a4492b3 ("sequencer: factor code out of revert builtin", 2012-01-11, Git v1.7.1-rc0).
for background on this function.These labels are of the form ... or parent of ...
These labels are then passed as branch names to the merge machinery.
However, these labels, as formatted, often also serve to confuse.
For example, if we have a rename involved in a content merge, then it results in text such as the following:
<<<<<<<< HEAD:foo.c int j; ======== int counter; >>>>>>>> b01dface... Removed unnecessary stuff:bar.c
Or in various conflict messages, it can make it very difficult to read:
CONFLICT (rename/delete): foo.c deleted in b01dface... Removed unnecessary stuff and renamed in HEAD. Version HEAD of foo.c left in tree. CONFLICT (file location): dir1/foo.c added in b01dface... Removed unnecessary stuff inside a directory that was renamed in HEAD, suggesting it should perhaps be moved to dir2/foo.c.
Make a minor change to remove the ellipses and add parentheses around the commit summary; this makes all three examples much easier to read:
<<<<<<<< HEAD:foo.c int j; ======== int counter; >>>>>>>> b01dface (Removed unnecessary stuff):bar.c CONFLICT (rename/delete): foo.c deleted in b01dface (Removed unnecessary stuff) and renamed in HEAD. Version HEAD of foo.c left in tree. CONFLICT (file location): dir1/foo.c added in b01dface (Removed unnecessary stuff) inside a directory that was renamed in HEAD, suggesting it should perhaps be moved to dir2/foo.c.