Handling changed/deleted conflicts with non-interactive terminals

Siddharth Agarwal sid0 at fb.com
Tue Oct 1 03:57:54 UTC 2013


One issue that's popped up here recently is handling changed/deleted 
conflicts (cdcs for short) during merges, when the terminal is 
non-interactive. cdcs occur when the file to be merged is changed on one 
side and deleted on the other.

Currently (in merge.py:manifestmerge) we always choose the default 
option, which is to keep the changed file. That's reasonably sensible, 
but there's no way for the process that's using hg non-interactively to 
figure that out, short of grepping for the string in hg's output. 
There's also no indication that something's gone wrong, nor a non-zero 
exit code.

Our use case is an automatic rebase-and-push done on a server -- it 
needs to fail and go back and ask the user to manually rebase in the c/d 
case. We've currently worked around it by grepping output, but it would 
be great to have a non-hacky solution for this.

mpm and I worked out a tentative solution today, which goes something like:
- for non-interactive terminals, treat cdcs as unresolved
- add a new status to the persistent merge state, for cdcs
- hg resolve <cdc path> shows the current prompt: either local changed 
remote deleted or local deleted remote changed.
- hg resolve --mark <cdc path> keeps the changed version
- hg rm <cdc path> && hg resolve --mark <cdc path> deletes the file

For backwards compatibility, we'll need to store the extra statuses in a 
separate file so that older hg won't barf at it. Figuring out when and 
how to invalidate that file is somewhat tricky.

Does the general idea make sense? Is there anything we're missing here 
that should be added?

mpm mentioned that this would be useful to TortoiseHg as well, so ccing 
Steve Borho.



More information about the Mercurial-devel mailing list