Mercurial > public > mercurial-scm > hg-stable
diff hgext/shelve.py @ 27908:d73a5ab18015
shelve: permit shelves to contain unknown files
If an emergency comes in while you're in the middle of an experimental
change, it can be useful to shelve not just files hg already tracks but
also your unknown files while you handle the emergency. This is
especially true if you have hooks intended to prevent you from
forgetting to add new code before you push.
Teach "hg shelve" to optionally shelve unknown files, not just tracked
files. This is functionally similar to --addremove, but with two
differences:
1) Deleted files are not removed.
2) Files added during shelve creation are tracked in extra so that they
can be forgotten by "hg unshelve".
When unshelving, we take care to only forget files if they've been
created during the unshelve operation; if you add a file that's being
tracked in a shelve as an unknown file, it should not become unknown
again when the shelve is unshelved.
author | Simon Farnsworth <simonfar@fb.com> |
---|---|
date | Thu, 14 Jan 2016 10:03:31 -0800 |
parents | 6c740218215d |
children | 158bdc896572 |
line wrap: on
line diff
--- a/hgext/shelve.py Sun Jan 17 14:14:15 2016 -0800 +++ b/hgext/shelve.py Thu Jan 14 10:03:31 2016 -0800 @@ -301,6 +301,16 @@ if name.startswith('.'): raise error.Abort(_("shelved change names may not start with '.'")) interactive = opts.get('interactive', False) + includeunknown = (opts.get('unknown', 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') @@ -312,7 +322,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: @@ -656,8 +666,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")) @@ -722,6 +734,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, @@ -743,6 +765,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', '', @@ -793,6 +817,7 @@ ''' allowables = [ ('addremove', set(['create'])), # 'create' is pseudo action + ('unknown', set(['create'])), ('cleanup', set(['cleanup'])), # ('date', set(['create'])), # ignored for passing '--date "0 0"' in tests ('delete', set(['delete'])),