If a file has had it's name and content changed, is it possible to mark the move after the commit has taken place?
e.g.
file1.txt
changed to file2.txt
and content changed.git commit
file1.txt
has been deleted and file2.txt
is an unrelated, new file.Is there a way to flag this as a rename after the commit has happened?
No, it isn't, because Git doesn't do rename tracking... but it does rename detection
(based on how similar is contents and name of files).
This means that
git log --follow file2.txt
would follow file history through rename (note: this unfortunately not always work correctly, as --follow
is a bit of hack), git blame -C -C file2.txt
would follow line-wise file history across file renames, content copying and moving across files and inside filegit show -C
would show that there was file rename (you can configure Git to always do rename and optionally even copy detection when displaying diffs).HTH
git won't detect the combination of a really substantial change and a simultaneous move as a rename, as you've discovered.
The thing to understand is that git detects the changes in a commit each time you look at the history, by comparing the commit's contents with its parent commit. That may seem too simple, but it turns out it's the good kind of simple.
So you need to insert a new commit, a rename that git log etc. can detect as such, followed by the rest of the history you've accumulated since then, and that means a new history for your branch, i.e. a rebase or cherry-pick.
So:
# make a new history with a rename that can be detected by comparing commits
# check out the glitched commit's ancestor by its sha,
# this work won't take enough time to bother inventing a transient name for it
git checkout commit-before-rename+bigchange
git mv file1.txt file2.txt
git commit
git checkout commit-with-rename+bigchange -- file2.txt
git commit
# Now add the rest of the changes, also detectable by comparing commits,
# by re-applying them on top of this new history:
git cherry-pick commit-before-rename+bigchange..branch-it\'s-on
# and force the old branch name to refer to this new history you just made
# the old history will be garbage-collected after 90 days or so if
# it's not part of the history of any other references
git checkout -B branch-it\'s-on
And you're done, except if any other repositories have acquired the messed-up history by fetch or push or clone, then you'll have to force a push or get those repo's owners to force a refetch (and any subsequent history they've built on top of that, which is why you really really don't wan't to publish too soon).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With