Submitter | Simon Farnsworth |
---|---|
Date | Jan. 14, 2016, 9:09 p.m. |
Message ID | <c8180c721b341cbab9fc.1452805773@devvm148.ash3.facebook.com> |
Download | mbox | patch |
Permalink | /patch/12769/ |
State | Accepted |
Commit | d73a5ab18015f61ac61e6e77256512fd82b03818 |
Delegated to: | Pierre-Yves David |
Headers | show |
Comments
On 1/14/16 9:09 PM, Simon Farnsworth wrote: > diff --git a/hgext/shelve.py b/hgext/shelve.py > --- a/hgext/shelve.py > +++ b/hgext/shelve.py > @@ -304,6 +304,16 @@ > if name.startswith('.'): > raise error.Abort(_("shelved change names may not start with '.'")) > interactive = opts.get('interactive', False) > + includeunknown = (opts.get('includeunknown', False) and > + not opts.get('addremove', False)) This can be unexpected for people. We should check if they are both set and raise an error, to make it clear to people that they are incompatible. > + > + extra={} > + if includeunknown: > + s = repo.status(match=scmutil.match(repo[None], pats, opts), > + unknown=True) > + if s.unknown: > + extra['shelve_unknown'] = '\0'.join(s.unknown) > + repo[None].add(s.unknown) > > def commitfunc(ui, repo, message, match, opts): > hasmq = util.safehasattr(repo, 'mq') > @@ -315,7 +325,7 @@ > editor = cmdutil.getcommiteditor(editform='shelve.shelve', > **opts) > return repo.commit(message, user, opts.get('date'), match, > - editor=editor) > + editor=editor, extra=extra) If I understand cmdutil.commit (which will be called with commitfunc as a parameter) correctly, you should be able to hand in 'extra' as an opt and then use extra=opts.get('extra') to retrieve them. This should remove the locality problem of having to reference and external variable. > finally: > repo.ui.restoreconfig(backup) > if hasmq: > @@ -679,8 +689,10 @@ > # and shelvectx is the unshelved changes. Then we merge it all down > # to the original pctx. > > - # Store pending changes in a commit > + # Store pending changes in a commit and remember added in case a shelve > + # contains unknown files that are part of the pending change > s = repo.status() > + addedbefore = frozenset(s.added) > if s.modified or s.added or s.removed or s.deleted: > ui.status(_("temporarily committing pending changes " > "(restore with 'hg unshelve --abort')\n")) > @@ -745,6 +757,16 @@ > shelvectx = tmpwctx > > > -A --addremove mark new/missing files as added/removed before > shelving > + -u --unknown Store unknown files in the shelve > --cleanup delete all shelved changes > --date DATE shelve with the specified commit date > -d --delete delete the named shelved change(s) > @@ -1245,3 +1246,71 @@ > test 4:33f7f61e6c5e > > $ cd .. > + > +Shelve and unshelve unknown files. For the purposes of unshelve, a shelved > +unknown file is the same as a shelved added file, except that it will be in > +unknown state after unshelve if and only if it was either absent or unknown > +before the unshelve operation. Can you add a test for the incompatibility between --addremove and --unknown.
On Thu, 2016-01-14 at 13:09 -0800, Simon Farnsworth wrote: > # HG changeset patch > # User Simon Farnsworth <simonfar@fb.com> > # Date 1452794611 28800 > # Thu Jan 14 10:03:31 2016 -0800 > # Node ID c8180c721b341cbab9fc617e183d60003fc34c8b > # Parent 727b137e82bed8ac97cfa4d9ddaa29e92bf393f3 > shelve: Permit shelves to contain unknown files I've decided that this is good enough to go in as-is, thanks. Please consider making a follow-up with David's suggestions. -- Mathematics is the supreme nostalgia of our time.
On 15/01/2016, 11:25, "David Soria Parra" <dsp@experimentalworks.net> wrote: > > >On 1/14/16 9:09 PM, Simon Farnsworth wrote: >> diff --git a/hgext/shelve.py b/hgext/shelve.py >> --- a/hgext/shelve.py >> +++ b/hgext/shelve.py >> @@ -304,6 +304,16 @@ >> if name.startswith('.'): >> raise error.Abort(_("shelved change names may not start with '.'")) >> interactive = opts.get('interactive', False) >> + includeunknown = (opts.get('includeunknown', False) and >> + not opts.get('addremove', False)) > >This can be unexpected for people. We should check if they are both set >and raise an error, to make it clear to people that they are incompatible. Patch in preparation for this. I'm going to delay sending it out while the freeze for 3.7 is in place. > >> + >> + extra={} >> + if includeunknown: >> + s = repo.status(match=scmutil.match(repo[None], pats, opts), >> + unknown=True) >> + if s.unknown: >> + extra['shelve_unknown'] = '\0'.join(s.unknown) >> + repo[None].add(s.unknown) >> >> def commitfunc(ui, repo, message, match, opts): >> hasmq = util.safehasattr(repo, 'mq') >> @@ -315,7 +325,7 @@ >> editor = cmdutil.getcommiteditor(editform='shelve.shelve', >> **opts) >> return repo.commit(message, user, opts.get('date'), match, >> - editor=editor) >> + editor=editor, extra=extra) > >If I understand cmdutil.commit (which will be called with commitfunc as >a parameter) correctly, you should be able to hand in 'extra' as an opt >and then use extra=opts.get('extra') to retrieve them. >This should remove the locality problem of having to reference and >external variable. I marginally prefer this style - it means that if cmdutil.commit or cmdutil.dorecord (either of which can end up being called with this function) later learns to parse an opt called 'extra', I'll still do the right thing. And we've already used it, in as much as interactivecommitfunc depends on it working to get at the definition of commitfunc. > >> finally: >> repo.ui.restoreconfig(backup) >> if hasmq: >> @@ -679,8 +689,10 @@ >> # and shelvectx is the unshelved changes. Then we merge it all down >> # to the original pctx. >> >> - # Store pending changes in a commit >> + # Store pending changes in a commit and remember added in case a shelve >> + # contains unknown files that are part of the pending change >> s = repo.status() >> + addedbefore = frozenset(s.added) >> if s.modified or s.added or s.removed or s.deleted: >> ui.status(_("temporarily committing pending changes " >> "(restore with 'hg unshelve --abort')\n")) >> @@ -745,6 +757,16 @@ >> shelvectx = tmpwctx >> > > >> >> -A --addremove mark new/missing files as added/removed before >> shelving >> + -u --unknown Store unknown files in the shelve >> --cleanup delete all shelved changes >> --date DATE shelve with the specified commit date >> -d --delete delete the named shelved change(s) >> @@ -1245,3 +1246,71 @@ >> test 4:33f7f61e6c5e >> >> $ cd .. >> + >> +Shelve and unshelve unknown files. For the purposes of unshelve, a shelved >> +unknown file is the same as a shelved added file, except that it will be in >> +unknown state after unshelve if and only if it was either absent or unknown >> +before the unshelve operation. > >Can you add a test for the incompatibility between --addremove and >--unknown. Will do. -- Simon Farnsworth
Patch
diff --git a/hgext/shelve.py b/hgext/shelve.py --- a/hgext/shelve.py +++ b/hgext/shelve.py @@ -304,6 +304,16 @@ if name.startswith('.'): raise error.Abort(_("shelved change names may not start with '.'")) interactive = opts.get('interactive', False) + includeunknown = (opts.get('includeunknown', False) and + not opts.get('addremove', False)) + + extra={} + if includeunknown: + s = repo.status(match=scmutil.match(repo[None], pats, opts), + unknown=True) + if s.unknown: + extra['shelve_unknown'] = '\0'.join(s.unknown) + repo[None].add(s.unknown) def commitfunc(ui, repo, message, match, opts): hasmq = util.safehasattr(repo, 'mq') @@ -315,7 +325,7 @@ editor = cmdutil.getcommiteditor(editform='shelve.shelve', **opts) return repo.commit(message, user, opts.get('date'), match, - editor=editor) + editor=editor, extra=extra) finally: repo.ui.restoreconfig(backup) if hasmq: @@ -679,8 +689,10 @@ # and shelvectx is the unshelved changes. Then we merge it all down # to the original pctx. - # Store pending changes in a commit + # Store pending changes in a commit and remember added in case a shelve + # contains unknown files that are part of the pending change s = repo.status() + addedbefore = frozenset(s.added) if s.modified or s.added or s.removed or s.deleted: ui.status(_("temporarily committing pending changes " "(restore with 'hg unshelve --abort')\n")) @@ -745,6 +757,16 @@ shelvectx = tmpwctx mergefiles(ui, repo, pctx, shelvectx) + + # Forget any files that were unknown before the shelve, unknown before + # unshelve started, but are now added. + shelveunknown = shelvectx.extra().get('shelve_unknown') + if shelveunknown: + shelveunknown = frozenset(shelveunknown.split('\0')) + addedafter = frozenset(repo.status().added) + toforget = (addedafter & shelveunknown) - addedbefore + repo[None].forget(toforget) + shelvedstate.clear(repo) # The transaction aborting will strip all the commits for us, @@ -766,6 +788,8 @@ @command('shelve', [('A', 'addremove', None, _('mark new/missing files as added/removed before shelving')), + ('u', 'unknown', None, + _('Store unknown files in the shelve')), ('', 'cleanup', None, _('delete all shelved changes')), ('', 'date', '', @@ -816,6 +840,7 @@ ''' allowables = [ ('addremove', set(['create'])), # 'create' is pseudo action + ('includeunknown', set(['create'])), ('cleanup', set(['cleanup'])), # ('date', set(['create'])), # ignored for passing '--date "0 0"' in tests ('delete', set(['delete'])), diff --git a/tests/test-shelve.t b/tests/test-shelve.t --- a/tests/test-shelve.t +++ b/tests/test-shelve.t @@ -54,6 +54,7 @@ -A --addremove mark new/missing files as added/removed before shelving + -u --unknown Store unknown files in the shelve --cleanup delete all shelved changes --date DATE shelve with the specified commit date -d --delete delete the named shelved change(s) @@ -1245,3 +1246,71 @@ test 4:33f7f61e6c5e $ cd .. + +Shelve and unshelve unknown files. For the purposes of unshelve, a shelved +unknown file is the same as a shelved added file, except that it will be in +unknown state after unshelve if and only if it was either absent or unknown +before the unshelve operation. + + $ hg init unknowns + $ cd unknowns + +The simplest case is if I simply have an unknown file that I shelve and unshelve + + $ echo unknown > unknown + $ hg status + ? unknown + $ hg shelve --unknown + shelved as default + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg status + $ hg unshelve + unshelving change 'default' + $ hg status + ? unknown + $ rm unknown + +If I shelve, add the file, and unshelve, does it stay added? + + $ echo unknown > unknown + $ hg shelve -u + shelved as default + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg status + $ touch unknown + $ hg add unknown + $ hg status + A unknown + $ hg unshelve + unshelving change 'default' + temporarily committing pending changes (restore with 'hg unshelve --abort') + rebasing shelved changes + rebasing 1:098df96e7410 "(changes in empty repository)" (tip) + merging unknown + $ hg status + A unknown + $ hg forget unknown + $ rm unknown + +And if I shelve, commit, then unshelve, does it become modified? + + $ echo unknown > unknown + $ hg shelve -u + shelved as default + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg status + $ touch unknown + $ hg add unknown + $ hg commit -qm "Add unknown" + $ hg status + $ hg unshelve + unshelving change 'default' + rebasing shelved changes + rebasing 1:098df96e7410 "(changes in empty repository)" (tip) + merging unknown + $ hg status + M unknown + $ hg remove --force unknown + $ hg commit -qm "Remove unknown" + + $ cd ..