--- a/hgext3rd/evolve/cmdrewrite.py Sun Mar 18 23:48:06 2018 +0530
+++ b/hgext3rd/evolve/cmdrewrite.py Wed Apr 11 07:23:34 2018 +0200
@@ -168,24 +168,7 @@
match=matcher,
opts=diffopts):
fp.write(chunk)
-
- fp.seek(0)
- newpatch = ui.edit(fp.getvalue(), old.user(), action="diff")
-
- afp = stringio()
- afp.write(newpatch)
- if pats:
- # write rest of the files in the patch
- restmatcher = scmutil.match(old, [], opts={'exclude': pats})
- for chunk, label in patch.diffui(repo, p1.node(), old.node(),
- match=restmatcher,
- opts=diffopts):
- afp.write(chunk)
-
- afp.seek(0)
- # write the patch to repo and get the newnode
- newnode = _writepatch(ui, repo, old, afp)
-
+ newnode = _editandapply(ui, repo, pats, old, p1, fp, diffopts)
if newnode == old.node():
raise error.Abort(_("nothing changed"))
metadata = {}
@@ -201,6 +184,44 @@
tr.release()
lockmod.release(lock, wlock)
+def _editandapply(ui, repo, pats, old, p1, fp, diffopts):
+ RETRYCHOICE = _('try to fix the patch (yn)?$$ &Yes $$ &No')
+ newnode = None
+ while newnode is None:
+ fp.seek(0)
+ previous_patch = fp.getvalue()
+ newpatch = ui.edit(fp.getvalue(), old.user(), action="diff")
+
+ afp = stringio()
+ afp.write(newpatch)
+ if pats:
+ # write rest of the files in the patch
+ restmatcher = scmutil.match(old, [], opts={'exclude': pats})
+ for chunk, label in patch.diffui(repo, p1.node(), old.node(),
+ match=restmatcher,
+ opts=diffopts):
+ afp.write(chunk)
+
+ user_patch = afp.getvalue()
+ if user_patch == previous_patch:
+ raise error.Abort(_("patch unchanged"))
+ afp.seek(0)
+ # write the patch to repo and get the newnode
+ try:
+ newnode = _writepatch(ui, repo, old, afp)
+ except patch.PatchError as err:
+ ui.write_err(_("failed to apply edited patch: %s\n") % err)
+ defaultchoice = 0 # yes
+ if not ui.interactive:
+ defaultchoice = 1 # no
+ if ui.promptchoice(RETRYCHOICE, default=defaultchoice):
+ raise error.Abort(_("Could not apply amended path"))
+ else:
+ # consider a third choice where we restore the original patch
+ fp = stringio()
+ fp.write(user_patch)
+ return newnode
+
def _writepatch(ui, repo, old, fp):
"""utility function to use filestore and patchrepo to apply a patch to the
repository with metadata being extracted from the patch"""
@@ -219,14 +240,10 @@
fp.seek(0)
try:
files = set()
- try:
- patch.patchrepo(ui, repo, pold, store, fp, 1, '',
- files=files, eolmode=None)
- except patch.PatchError as err:
- raise error.Abort(str(err))
-
- finally:
- del fp
+ # beware: next line may raise a PatchError to be handled by the caller
+ # of this function
+ patch.patchrepo(ui, repo, pold, store, fp, 1, '',
+ files=files, eolmode=None)
memctx = context.memctx(repo, parents, message, files=files,
filectxfn=store,
--- a/tests/test-amend-patch.t Sun Mar 18 23:48:06 2018 +0530
+++ b/tests/test-amend-patch.t Wed Apr 11 07:23:34 2018 +0200
@@ -139,8 +139,10 @@
> EOF
$ HGEDITOR="sh ./editor.sh" hg amend --patch
- abort: bad hunk #1 @@ -0,0 +1,1 @@
+ failed to apply edited patch: bad hunk #1 @@ -0,0 +1,1 @@
(1 0 1 1)
+ try to fix the patch (yn)? y
+ abort: patch unchanged
[255]
Having deletions which dont exists
@@ -166,8 +168,10 @@
> EOF
$ HGEDITOR="sh ./editor.sh" hg amend --patch
- abort: bad hunk #1 @@ -0,0 +1,1 @@
+ failed to apply edited patch: bad hunk #1 @@ -0,0 +1,1 @@
(1 0 1 1)
+ try to fix the patch (yn)? y
+ abort: patch unchanged
[255]
Changing the file mode using amend --patch
@@ -325,7 +329,9 @@
$ HGEDITOR="sh ./editor.sh" hg amend --patch
patching file changedfile
Hunk #1 FAILED at 0
- abort: patch failed to apply
+ failed to apply edited patch: patch failed to apply
+ try to fix the patch (yn)? y
+ abort: patch unchanged
[255]
Add more addition to the patch
@@ -733,7 +739,7 @@
@@ -1,2 +0,0 @@
-foobar
-babar
- abort: nothing changed
+ abort: patch unchanged
[255]
$ HGEDITOR=cat hg amend --patch doesnotexists