3016 |
3016 |
3017 |
3017 |
3018 if not opts.get('dry_run'): |
3018 if not opts.get('dry_run'): |
3019 needdata = ('revert', 'add', 'undelete') |
3019 needdata = ('revert', 'add', 'undelete') |
3020 _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata]) |
3020 _revertprefetch(repo, ctx, *[actions[name][0] for name in needdata]) |
3021 |
3021 interactive = opts.get('interactive', False) |
3022 _performrevert(repo, parents, ctx, actions) |
3022 _performrevert(repo, parents, ctx, actions, interactive) |
3023 |
3023 |
3024 # get the list of subrepos that must be reverted |
3024 # get the list of subrepos that must be reverted |
3025 subrepomatch = scmutil.match(ctx, pats, opts) |
3025 subrepomatch = scmutil.match(ctx, pats, opts) |
3026 targetsubs = sorted(s for s in ctx.substate if subrepomatch(s)) |
3026 targetsubs = sorted(s for s in ctx.substate if subrepomatch(s)) |
3027 |
3027 |
3034 |
3034 |
3035 def _revertprefetch(repo, ctx, *files): |
3035 def _revertprefetch(repo, ctx, *files): |
3036 """Let extension changing the storage layer prefetch content""" |
3036 """Let extension changing the storage layer prefetch content""" |
3037 pass |
3037 pass |
3038 |
3038 |
3039 def _performrevert(repo, parents, ctx, actions): |
3039 def _performrevert(repo, parents, ctx, actions, interactive=False): |
3040 """function that actually perform all the actions computed for revert |
3040 """function that actually perform all the actions computed for revert |
3041 |
3041 |
3042 This is an independent function to let extension to plug in and react to |
3042 This is an independent function to let extension to plug in and react to |
3043 the imminent revert. |
3043 the imminent revert. |
3044 |
3044 |
3068 # merges to avoid losing information about merged/dirty files. |
3068 # merges to avoid losing information about merged/dirty files. |
3069 if p2 != nullid: |
3069 if p2 != nullid: |
3070 normal = repo.dirstate.normallookup |
3070 normal = repo.dirstate.normallookup |
3071 else: |
3071 else: |
3072 normal = repo.dirstate.normal |
3072 normal = repo.dirstate.normal |
3073 for f in actions['revert'][0]: |
3073 |
3074 checkout(f) |
3074 if interactive: |
3075 if normal: |
3075 # Prompt the user for changes to revert |
3076 normal(f) |
3076 torevert = [repo.wjoin(f) for f in actions['revert'][0]] |
|
3077 m = scmutil.match(ctx, torevert, {}) |
|
3078 diff = patch.diff(repo, None, ctx.node(), m) |
|
3079 originalchunks = patch.parsepatch(diff) |
|
3080 try: |
|
3081 chunks = recordfilter(repo.ui, originalchunks) |
|
3082 except patch.PatchError, err: |
|
3083 raise util.Abort(_('error parsing patch: %s') % err) |
|
3084 |
|
3085 # Apply changes |
|
3086 fp = cStringIO.StringIO() |
|
3087 for c in chunks: |
|
3088 c.write(fp) |
|
3089 dopatch = fp.tell() |
|
3090 fp.seek(0) |
|
3091 if dopatch: |
|
3092 try: |
|
3093 patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None) |
|
3094 except patch.PatchError, err: |
|
3095 raise util.Abort(str(err)) |
|
3096 del fp |
|
3097 |
|
3098 for f in actions['revert'][0]: |
|
3099 if normal: |
|
3100 normal(f) |
|
3101 |
|
3102 else: |
|
3103 for f in actions['revert'][0]: |
|
3104 checkout(f) |
|
3105 if normal: |
|
3106 normal(f) |
3077 |
3107 |
3078 for f in actions['add'][0]: |
3108 for f in actions['add'][0]: |
3079 checkout(f) |
3109 checkout(f) |
3080 repo.dirstate.add(f) |
3110 repo.dirstate.add(f) |
3081 |
3111 |