We recently did a hg copy
of a directory in our repository. We thought it
does something like cp -a
and hg add
and maybe flag somehow that
this file has been copied from another file inside the repo (so hg
annotate
shows the original committer). But it now seems that hg
copy
does more or different stuff than that. I couldn't really find
much on how exactly copy works. So:
- What exactly does
hg copy
do and what special treatment does this cause in the future? - If it turns out to do "the wrong thing(tm)" for our case, how do I unflag the file as beeing a copy of another file?
(This question was asked on the Mercurial mailinglist, you may want to follow the original thread too.)
If you revert a hg copy, the copied-to file remains in your working directory afterwards, untracked. You just have to add it normally. The copied-from file isn't affected at all.
Reference: Mercurial: The definitive guide
It adds new files and marks them as copies of the old files. Because they are copies, a change made in the original file will be merged into copy. Time flows from left to right:
This mechanism only kicks in when you merge. If
b.txt
is not present in the common ancestor revision (init in the above graph), then Mercurial will do a search backwards to see ifb.txt
is copied from somewhere else.Let us continue the above graph in abbreviated form:
The question is how the final merge is done. The common ancestor point is now the
copy a b
node and here botha
andb
are present. This means that there wont be any search for copies! So the second edit toa
wont be merged intob
.To double-check, I tried it out:
This was the copy,
b
now containsa
only.This was the first merge and the edit to
a
has been copied intob
:We now make changes in parallel:
There are no further copying done:
As for disabling this... you can't really explicitly disable the copy detection. But as I hope to have illustrated above, it wont "bother" you again after the first merge.
If the first merge is a problem, then you can use
hg resolve --tool internal:local
to reset the files back to their state before you started the merge. So withwe could have brought
b
back to just containing one line witha
.