Commit 137eff8e authored by skarlage's avatar skarlage

revert: don't backup if no files reverted in interactive mode (issue4793)

When reverting interactively, we always backup files before prompting the user
to find out if they actually want to revert them. This can create spurious
*.orig files if a user enters an interactive revert session and then doesn't
revert any files. Instead, we should only backup files that are actually being
parent ee2027195847
......@@ -3143,11 +3143,17 @@ def revert(ui, repo, ctx, parents, *pats, **opts):
# All set to `discard` if `no-backup` is set do avoid checking
# no_backup lower in the code.
# These values are ordered for comparison purposes
backupinteractive = 3 # do backup if interactively modified
backup = 2 # unconditionally do backup
check = 1 # check if the existing file differs from target
discard = 0 # never do backup
if opts.get('no_backup'):
backup = check = discard
backupinteractive = backup = check = discard
if interactive:
dsmodifiedbackup = backupinteractive
dsmodifiedbackup = backup
tobackup = set()
backupanddel = actions['remove']
if not opts.get('no_backup'):
......@@ -3165,7 +3171,7 @@ def revert(ui, repo, ctx, parents, *pats, **opts):
# Modified compared to target, but local file is deleted
(deleted, actions['revert'], discard),
# Modified compared to target, local change
(dsmodified, actions['revert'], backup),
(dsmodified, actions['revert'], dsmodifiedbackup),
# Added since target
(added, actions['remove'], discard),
# Added in working directory
......@@ -3200,8 +3206,12 @@ def revert(ui, repo, ctx, parents, *pats, **opts):
if xlist is not None:
if dobackup and (backup <= dobackup
or wctx[abs].cmp(ctx[abs])):
if dobackup:
# If in interactive mode, don't automatically create
# .orig files (issue4793)
if dobackup == backupinteractive:
elif (backup <= dobackup or wctx[abs].cmp(ctx[abs])):
bakname = scmutil.origpath(ui, repo, rel)
ui.note(_('saving current version of %s as %s\n') %
(rel, bakname))
......@@ -3221,7 +3231,7 @@ def revert(ui, repo, ctx, parents, *pats, **opts):
if not opts.get('dry_run'):
needdata = ('revert', 'add', 'undelete')
_revertprefetch(repo, ctx, *[actions[name][0] for name in needdata])
_performrevert(repo, parents, ctx, actions, interactive)
_performrevert(repo, parents, ctx, actions, interactive, tobackup)
if targetsubs:
# Revert the subrepos on the revert list
......@@ -3236,7 +3246,8 @@ def _revertprefetch(repo, ctx, *files):
"""Let extension changing the storage layer prefetch content"""
def _performrevert(repo, parents, ctx, actions, interactive=False):
def _performrevert(repo, parents, ctx, actions, interactive=False,
"""function that actually perform all the actions computed for revert
This is an independent function to let extension to plug in and react to
......@@ -3316,9 +3327,18 @@ def _performrevert(repo, parents, ctx, actions, interactive=False):
raise error.Abort(_('error parsing patch: %s') % err)
newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
if tobackup is None:
tobackup = set()
# Apply changes
fp = stringio()
for c in chunks:
# Create a backup file only if this hunk should be backed up
if ishunk(c) and c.header.filename() in tobackup:
abs = c.header.filename()
target = repo.wjoin(abs)
bakname = scmutil.origpath(repo.ui, repo, m.rel(abs))
util.copyfile(target, bakname)
dopatch = fp.tell()
......@@ -134,7 +134,41 @@ Test that --interactive lift the need for --all
abort: user quit
$ rm folder1/g.orig
$ ls folder1/
Test that a noop revert doesn't do an unecessary backup
$ (echo y; echo n) | hg revert -i -r 2 folder1/g
diff --git a/folder1/g b/folder1/g
1 hunks, 1 lines changed
examine changes to 'folder1/g'? [Ynesfdaq?] y
@@ -3,3 +3,4 @@
revert this change to 'folder1/g'? [Ynesfdaq?] n
$ ls folder1/
Test --no-backup
$ (echo y; echo y) | hg revert -i -C -r 2 folder1/g
diff --git a/folder1/g b/folder1/g
1 hunks, 1 lines changed
examine changes to 'folder1/g'? [Ynesfdaq?] y
@@ -3,3 +3,4 @@
revert this change to 'folder1/g'? [Ynesfdaq?] y
$ ls folder1/
>>> open('folder1/g', 'wb').write("1\n2\n3\n4\n5\nd\n")
$ hg update -C 6
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment