Mercurial > hg
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(): |