diff -r ee2027195847 -r 1b38cfde9530 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Tue Jul 05 07:25:51 2016 +0900 +++ b/mercurial/cmdutil.py Thu Jun 30 08:38:19 2016 -0700 @@ -3143,11 +3143,17 @@ # 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 + else: + dsmodifiedbackup = backup + tobackup = set() backupanddel = actions['remove'] if not opts.get('no_backup'): @@ -3165,7 +3171,7 @@ # 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 @@ continue if xlist is not None: xlist.append(abs) - 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: + tobackup.add(abs) + 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 @@ 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 @@ """Let extension changing the storage layer prefetch content""" pass -def _performrevert(repo, parents, ctx, actions, interactive=False): +def _performrevert(repo, parents, ctx, actions, interactive=False, + tobackup=None): """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 @@ 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) + tobackup.remove(abs) c.write(fp) dopatch = fp.tell() fp.seek(0)