tech-repository archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: irt: Re: Core statement on version control systems
On Wed, Dec 03, 2025 at 05:07:02PM -0600, Constantine A. Murenin wrote:
> If renames in Git are so problematic, how would the Git to Mercurial bridge
> be able to handle the situation?
Easily. It can:
- take the git commit, and apply git's rename detection heuristics
to it to create the rename metadata for an hg commit;
- take the git commit, and feed it to hg using hg's rename detection
heuristics.
It appears to be doing the first rather than the second.
As I just said in the other message, there's two parts to the rename
question; one is handling renames during development, the other is
recording the metadata at commit time. It's the latter we really care
about.
You can still get hosed by git's rename heuristics if you mass-rename
a lot of small and very similar files in one commit, but the real
problems are caused by the _later_ behavior being unreliable.
Try the following:
% git init
% echo 'xyzzy' > xyzzy
% git add xyzzy
% git commit -m 'create a file'
% git mv xyzzy zzyzx
% git commit -m 'rename the file'
% echo 'zzyzx' > zzyzx
% git commit -m 'change the file' .
Now use git log to retrieve the commit hash of the add commit,
which for me right now is 922d2395d9550d4df628492830c0457004effe52,
and do the following:
% git checkout -b foo 922d2395d9550d4df628492830c0457004effe52
% echo 'zzyzx' > xyzzy
% git commit -m 'change the file before the rename' .
Now try to rebase on main:
% git rebase main
You get
CONFLICT (modify/delete): xyzzy deleted in HEAD and modified in 941d87a (change the file before the rename). Version 941d87a (change the file before the rename) of xyzzy left in tree.
error: could not apply 941d87a... change the file before the rename
because the rename detection fails, and now you're left in a state
where it's quite easy to mess up and lose changes:
% git status
interactive rebase in progress; onto 46e6d14
Last command done (1 command done):
pick 941d87a # change the file before the rename
No commands remaining.
You are currently rebasing branch 'foo' on '46e6d14'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add/rm <file>..." as appropriate to mark resolution)
deleted by us: xyzzy
no changes added to commit (use "git add" and/or "git commit -a")
%
Note that the only merge state is that there's a change in a file
that's been deleted. It's completely lost track of the rename.
Furthermore, by virtue of the way rebasing replays commits, git is
claiming that we deleted xyzzy (actually it was upstream), so a naive
user is very likely to just git rm the file and lose the changes.
(This is less broken for merges, where it'll say "xyzzy deleted in
main and modified in HEAD". But y'all always argue against ever using
merge.)
If the files and changes are more complex than one-liners, it's pretty
easy to accidentally lose the changes even for non-naive users. This
goes double for when it's someone else's rename changes you may not
have even been particularly aware of -- unless you are quite on top of
what's happening in the tree there's no obvious cues to tell you where
to find the file you're supposed to merge the changes into. (It can
obviously be dug out, but the digging required will likely be beyond a
lot of casual users.)
> I haven't heard of any upcoming restrictions on the use of Git as the
> front-end to the final and true master in Mercurial, yet your message may
> imply that Mercurial and only the Mercurial CLI, `hg rename`, would have to
> be used for file renames?
No, that is not the case.
Although we should recommend people use the hg side for renames,
and probably demand it for anything that can reasonably be called a
mass-rename.
--
David A. Holland
dholland%netbsd.org@localhost
Home |
Main Index |
Thread Index |
Old Index