comparison hgext/uncommit.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 576fd1c8b20b
children 687b865b95ad
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
40 command = registrar.command(cmdtable) 40 command = registrar.command(cmdtable)
41 41
42 configtable = {} 42 configtable = {}
43 configitem = registrar.configitem(configtable) 43 configitem = registrar.configitem(configtable)
44 44
45 configitem('experimental', 'uncommitondirtywdir', 45 configitem(
46 default=False, 46 'experimental', 'uncommitondirtywdir', default=False,
47 ) 47 )
48 configitem('experimental', 'uncommit.keep', 48 configitem(
49 default=False, 49 'experimental', 'uncommit.keep', default=False,
50 ) 50 )
51 51
52 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for 52 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
53 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should 53 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
54 # be specifying the version(s) of Mercurial they are tested with, or 54 # be specifying the version(s) of Mercurial they are tested with, or
55 # leave the attribute unspecified. 55 # leave the attribute unspecified.
56 testedwith = 'ships-with-hg-core' 56 testedwith = 'ships-with-hg-core'
57 57
58 def _commitfiltered(repo, ctx, match, keepcommit, message=None, user=None, 58
59 date=None): 59 def _commitfiltered(
60 repo, ctx, match, keepcommit, message=None, user=None, date=None
61 ):
60 """Recommit ctx with changed files not in match. Return the new 62 """Recommit ctx with changed files not in match. Return the new
61 node identifier, or None if nothing changed. 63 node identifier, or None if nothing changed.
62 """ 64 """
63 base = ctx.p1() 65 base = ctx.p1()
64 # ctx 66 # ctx
71 73
72 # return the p1 so that we don't create an obsmarker later 74 # return the p1 so that we don't create an obsmarker later
73 if not keepcommit: 75 if not keepcommit:
74 return ctx.p1().node() 76 return ctx.p1().node()
75 77
76 files = (initialfiles - exclude) 78 files = initialfiles - exclude
77 # Filter copies 79 # Filter copies
78 copied = copiesmod.pathcopies(base, ctx) 80 copied = copiesmod.pathcopies(base, ctx)
79 copied = dict((dst, src) for dst, src in copied.iteritems() 81 copied = dict((dst, src) for dst, src in copied.iteritems() if dst in files)
80 if dst in files) 82
81 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()): 83 def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
82 if path not in contentctx: 84 if path not in contentctx:
83 return None 85 return None
84 fctx = contentctx[path] 86 fctx = contentctx[path]
85 mctx = context.memfilectx(repo, memctx, fctx.path(), fctx.data(), 87 mctx = context.memfilectx(
86 fctx.islink(), 88 repo,
87 fctx.isexec(), 89 memctx,
88 copysource=copied.get(path)) 90 fctx.path(),
91 fctx.data(),
92 fctx.islink(),
93 fctx.isexec(),
94 copysource=copied.get(path),
95 )
89 return mctx 96 return mctx
90 97
91 if not files: 98 if not files:
92 repo.ui.status(_("note: keeping empty commit\n")) 99 repo.ui.status(_("note: keeping empty commit\n"))
93 100
96 if not user: 103 if not user:
97 user = ctx.user() 104 user = ctx.user()
98 if not date: 105 if not date:
99 date = ctx.date() 106 date = ctx.date()
100 107
101 new = context.memctx(repo, 108 new = context.memctx(
102 parents=[base.node(), node.nullid], 109 repo,
103 text=message, 110 parents=[base.node(), node.nullid],
104 files=files, 111 text=message,
105 filectxfn=filectxfn, 112 files=files,
106 user=user, 113 filectxfn=filectxfn,
107 date=date, 114 user=user,
108 extra=ctx.extra()) 115 date=date,
116 extra=ctx.extra(),
117 )
109 return repo.commitctx(new) 118 return repo.commitctx(new)
110 119
111 @command('uncommit', 120
112 [('', 'keep', None, _('allow an empty commit after uncommitting')), 121 @command(
113 ('', 'allow-dirty-working-copy', False, 122 'uncommit',
114 _('allow uncommit with outstanding changes')), 123 [
115 (b'n', b'note', b'', _(b'store a note on uncommit'), _(b'TEXT')) 124 ('', 'keep', None, _('allow an empty commit after uncommitting')),
116 ] + commands.walkopts + commands.commitopts + commands.commitopts2 125 (
126 '',
127 'allow-dirty-working-copy',
128 False,
129 _('allow uncommit with outstanding changes'),
130 ),
131 (b'n', b'note', b'', _(b'store a note on uncommit'), _(b'TEXT')),
132 ]
133 + commands.walkopts
134 + commands.commitopts
135 + commands.commitopts2
117 + commands.commitopts3, 136 + commands.commitopts3,
118 _('[OPTION]... [FILE]...'), 137 _('[OPTION]... [FILE]...'),
119 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT) 138 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
139 )
120 def uncommit(ui, repo, *pats, **opts): 140 def uncommit(ui, repo, *pats, **opts):
121 """uncommit part or all of a local changeset 141 """uncommit part or all of a local changeset
122 142
123 This command undoes the effect of a local commit, returning the affected 143 This command undoes the effect of a local commit, returning the affected
124 files to their uncommitted state. This means that files modified or 144 files to their uncommitted state. This means that files modified or
135 155
136 with repo.wlock(), repo.lock(): 156 with repo.wlock(), repo.lock():
137 157
138 m, a, r, d = repo.status()[:4] 158 m, a, r, d = repo.status()[:4]
139 isdirtypath = any(set(m + a + r + d) & set(pats)) 159 isdirtypath = any(set(m + a + r + d) & set(pats))
140 allowdirtywcopy = (opts['allow_dirty_working_copy'] or 160 allowdirtywcopy = opts[
141 repo.ui.configbool('experimental', 'uncommitondirtywdir')) 161 'allow_dirty_working_copy'
162 ] or repo.ui.configbool('experimental', 'uncommitondirtywdir')
142 if not allowdirtywcopy and (not pats or isdirtypath): 163 if not allowdirtywcopy and (not pats or isdirtypath):
143 cmdutil.bailifchanged(repo, hint=_('requires ' 164 cmdutil.bailifchanged(
144 '--allow-dirty-working-copy to uncommit')) 165 repo,
166 hint=_('requires ' '--allow-dirty-working-copy to uncommit'),
167 )
145 old = repo['.'] 168 old = repo['.']
146 rewriteutil.precheck(repo, [old.rev()], 'uncommit') 169 rewriteutil.precheck(repo, [old.rev()], 'uncommit')
147 if len(old.parents()) > 1: 170 if len(old.parents()) > 1:
148 raise error.Abort(_("cannot uncommit merge changeset")) 171 raise error.Abort(_("cannot uncommit merge changeset"))
149 172
162 if badfiles: 185 if badfiles:
163 badfiles -= {f for f in util.dirs(eligible)} 186 badfiles -= {f for f in util.dirs(eligible)}
164 187
165 for f in sorted(badfiles): 188 for f in sorted(badfiles):
166 if f in s.clean: 189 if f in s.clean:
167 hint = _(b"file was not changed in working directory " 190 hint = _(
168 b"parent") 191 b"file was not changed in working directory " b"parent"
192 )
169 elif repo.wvfs.exists(f): 193 elif repo.wvfs.exists(f):
170 hint = _(b"file was untracked in working directory parent") 194 hint = _(b"file was untracked in working directory parent")
171 else: 195 else:
172 hint = _(b"file does not exist") 196 hint = _(b"file does not exist")
173 197
174 raise error.Abort(_(b'cannot uncommit "%s"') 198 raise error.Abort(
175 % scmutil.getuipathfn(repo)(f), hint=hint) 199 _(b'cannot uncommit "%s"') % scmutil.getuipathfn(repo)(f),
200 hint=hint,
201 )
176 202
177 with repo.transaction('uncommit'): 203 with repo.transaction('uncommit'):
178 if not (opts[b'message'] or opts[b'logfile']): 204 if not (opts[b'message'] or opts[b'logfile']):
179 opts[b'message'] = old.description() 205 opts[b'message'] = old.description()
180 message = cmdutil.logmessage(ui, opts) 206 message = cmdutil.logmessage(ui, opts)
183 if not keepcommit: 209 if not keepcommit:
184 if opts.get('keep') is not None: 210 if opts.get('keep') is not None:
185 keepcommit = opts.get('keep') 211 keepcommit = opts.get('keep')
186 else: 212 else:
187 keepcommit = ui.configbool('experimental', 'uncommit.keep') 213 keepcommit = ui.configbool('experimental', 'uncommit.keep')
188 newid = _commitfiltered(repo, old, match, keepcommit, 214 newid = _commitfiltered(
189 message=message, user=opts.get(b'user'), 215 repo,
190 date=opts.get(b'date')) 216 old,
217 match,
218 keepcommit,
219 message=message,
220 user=opts.get(b'user'),
221 date=opts.get(b'date'),
222 )
191 if newid is None: 223 if newid is None:
192 ui.status(_("nothing to uncommit\n")) 224 ui.status(_("nothing to uncommit\n"))
193 return 1 225 return 1
194 226
195 mapping = {} 227 mapping = {}
203 with repo.dirstate.parentchange(): 235 with repo.dirstate.parentchange():
204 scmutil.movedirstate(repo, repo[newid], match) 236 scmutil.movedirstate(repo, repo[newid], match)
205 237
206 scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True) 238 scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True)
207 239
240
208 def predecessormarkers(ctx): 241 def predecessormarkers(ctx):
209 """yields the obsolete markers marking the given changeset as a successor""" 242 """yields the obsolete markers marking the given changeset as a successor"""
210 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()): 243 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()):
211 yield obsutil.marker(ctx.repo(), data) 244 yield obsutil.marker(ctx.repo(), data)
212 245
213 @command('unamend', [], helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, 246
214 helpbasic=True) 247 @command(
248 'unamend',
249 [],
250 helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
251 helpbasic=True,
252 )
215 def unamend(ui, repo, **opts): 253 def unamend(ui, repo, **opts):
216 """undo the most recent amend operation on a current changeset 254 """undo the most recent amend operation on a current changeset
217 255
218 This command will roll back to the previous version of a changeset, 256 This command will roll back to the previous version of a changeset,
219 leaving working directory in state in which it was before running 257 leaving working directory in state in which it was before running
248 return predctx.filectx(path) 286 return predctx.filectx(path)
249 except KeyError: 287 except KeyError:
250 return None 288 return None
251 289
252 # Make a new commit same as predctx 290 # Make a new commit same as predctx
253 newctx = context.memctx(repo, 291 newctx = context.memctx(
254 parents=(predctx.p1(), predctx.p2()), 292 repo,
255 text=predctx.description(), 293 parents=(predctx.p1(), predctx.p2()),
256 files=predctx.files(), 294 text=predctx.description(),
257 filectxfn=filectxfn, 295 files=predctx.files(),
258 user=predctx.user(), 296 filectxfn=filectxfn,
259 date=predctx.date(), 297 user=predctx.user(),
260 extra=extras) 298 date=predctx.date(),
299 extra=extras,
300 )
261 newprednode = repo.commitctx(newctx) 301 newprednode = repo.commitctx(newctx)
262 newpredctx = repo[newprednode] 302 newpredctx = repo[newprednode]
263 dirstate = repo.dirstate 303 dirstate = repo.dirstate
264 304
265 with dirstate.parentchange(): 305 with dirstate.parentchange():