summaryrefslogtreecommitdiff
path: root/.hgext
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2009-11-12 01:07:29 +0100
committerRené 'Necoro' Neumann <necoro@necoro.net>2009-11-12 01:07:29 +0100
commit6cc703479f7af518534a33de8a7c1c1bf01af6d2 (patch)
tree07399362f8d0abb3908504d3e432f929dc43969c /.hgext
parent9b0560257247887d716fbed36c43a32a97ed6ffd (diff)
downloaddotfiles-6cc703479f7af518534a33de8a7c1c1bf01af6d2.tar.gz
dotfiles-6cc703479f7af518534a33de8a7c1c1bf01af6d2.tar.bz2
dotfiles-6cc703479f7af518534a33de8a7c1c1bf01af6d2.zip
Update hgshelve extension for hg 1.3.1
Diffstat (limited to '.hgext')
-rw-r--r--.hgext/hgshelve.py206
1 files changed, 163 insertions, 43 deletions
diff --git a/.hgext/hgshelve.py b/.hgext/hgshelve.py
index cd159c9..4e0c121 100644
--- a/.hgext/hgshelve.py
+++ b/.hgext/hgshelve.py
@@ -10,7 +10,7 @@
from mercurial.i18n import _
from mercurial import cmdutil, commands, cmdutil, hg, mdiff, patch, revlog
-from mercurial import util, fancyopts
+from mercurial import util, fancyopts, extensions
import copy, cStringIO, errno, operator, os, re, shutil, tempfile
lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
@@ -21,6 +21,13 @@ def internalpatch(patchobj, ui, strip, cwd, reverse=False, files={}):
Adapted from patch.internalpatch() to support reverse patching.
"""
+
+ eolmode = ui.config('patch', 'eol', 'strict')
+ try:
+ eol = {'strict': None, 'crlf': '\r\n', 'lf': '\n'}[eolmode.lower()]
+ except KeyError:
+ raise util.Abort(_('Unsupported line endings type: %s') % eolmode)
+
try:
fp = file(patchobj, 'rb')
except TypeError:
@@ -29,8 +36,7 @@ def internalpatch(patchobj, ui, strip, cwd, reverse=False, files={}):
curdir = os.getcwd()
os.chdir(cwd)
try:
- ret = patch.applydiff(ui, fp, files, strip=strip,
- reverse=reverse)
+ ret = patch.applydiff(ui, fp, files, strip=strip, eol=eol)
finally:
if cwd:
os.chdir(curdir)
@@ -160,8 +166,27 @@ class hunk(object):
self.hunk = hunk
self.added, self.removed = countchanges(self.hunk)
+ def __cmp__(self, rhs):
+ # since the hunk().toline needs to be adjusted when hunks are
+ # removed/added, we can't take it into account when we cmp
+ attrs = ['header', 'fromline', 'proc', 'hunk', 'added', 'removed']
+ for attr in attrs:
+ selfattr = getattr(self, attr, None)
+ rhsattr = getattr(rhs, attr, None)
+
+ if selfattr is None or rhsattr is None:
+ raise util.Abort(_('non-existant attribute %s') % attr)
+
+ rv = cmp(selfattr, rhsattr)
+ if rv != 0:
+ return rv
+ return rv
+
+
def write(self, fp):
delta = len(self.before) + len(self.after)
+ if self.after and self.after[-1] == '\\ No newline at end of file\n':
+ delta -= 1
fromlen = delta + self.removed
tolen = delta + self.added
fp.write('@@ -%d,%d +%d,%d @@%s\n' %
@@ -211,7 +236,7 @@ def parsepatch(fp):
if self.context:
self.before = self.context
self.context = []
- self.hunk = data
+ self.hunk = hunk
def newfile(self, hdr):
self.addcontext([])
@@ -250,7 +275,7 @@ def parsepatch(fp):
state = newstate
return p.finished()
-def filterpatch(ui, chunks):
+def filterpatch(ui, chunks, shouldprompt=True):
chunks = list(chunks)
chunks.reverse()
seen = {}
@@ -262,7 +287,14 @@ def filterpatch(ui, chunks):
else:
consumed.append(chunks.pop())
return consumed
+
resp_all = [None]
+
+ """ If we're not to prompt (i.e. they specified the --all flag)
+ we pre-emptively set the 'all' flag """
+ if shouldprompt == False:
+ resp_all = ['y']
+
resp_file = [None]
applied = {}
def prompt(query):
@@ -271,24 +303,36 @@ def filterpatch(ui, chunks):
if resp_file[0] is not None:
return resp_file[0]
while True:
- r = (ui.prompt(query + _(' [Ynsfdaq?] '), '(?i)[Ynsfdaq?]?$')
- or 'y').lower()
- if r == '?':
+ resps = _('[Ynsfdaq?]')
+ choices = (_('&Yes, shelve this change'),
+ _('&No, skip this change'),
+ _('&Skip remaining changes to this file'),
+ _('Shelve remaining changes to this &file'),
+ _('&Done, skip remaining changes and files'),
+ _('Shelve &all changes to all remaining files'),
+ _('&Quit, shelving no changes'),
+ _('&?'))
+ r = ui.promptchoice("%s %s " % (query, resps), choices)
+ if r == 7:
c = shelve.__doc__.find('y - shelve this change')
for l in shelve.__doc__[c:].splitlines():
- if l: ui.write(_(l.strip()), '\n')
+ if l: ui.write(_(l.strip()) + '\n')
continue
- elif r == 's':
- r = resp_file[0] = 'n'
- elif r == 'f':
- r = resp_file[0] = 'y'
- elif r == 'd':
- r = resp_all[0] = 'n'
- elif r == 'a':
- r = resp_all[0] = 'y'
- elif r == 'q':
+ elif r == 0: # yes
+ ret = 'y'
+ elif r == 1: # no
+ ret = 'n'
+ elif r == 2: # Skip
+ ret = resp_file[0] = 'n'
+ elif r == 3: # file (shelve remaining)
+ ret = resp_file[0] = 'y'
+ elif r == 4: # done, skip remaining
+ ret = resp_all[0] = 'n'
+ elif r == 5: # all
+ ret = resp_all[0] = 'y'
+ elif r == 6: # quit
raise util.Abort(_('user quit'))
- return r
+ return ret
while chunks:
chunk = chunks.pop()
if isinstance(chunk, header):
@@ -301,8 +345,12 @@ def filterpatch(ui, chunks):
seen[hdr] = True
if resp_all[0] is None:
chunk.pretty(ui)
- r = prompt(_('shelve changes to %s?') %
+ if shouldprompt == True:
+ r = prompt(_('shelve changes to %s?') %
_(' and ').join(map(repr, chunk.files())))
+ else:
+ r = 'y'
+
if r == 'y':
applied[chunk.filename()] = [chunk]
if chunk.allhunks():
@@ -357,34 +405,60 @@ def makebackup(ui, repo, dir, files):
return backups
+def getshelfpath(repo, name):
+ if name:
+ shelfpath = "shelves/" + name
+ else:
+ # Check if a shelf from an older version exists
+ if os.path.isfile(repo.join('shelve')):
+ shelfpath = 'shelve'
+ else:
+ shelfpath = "shelves/default"
+
+ return shelfpath
+
def shelve(ui, repo, *pats, **opts):
'''interactively select changes to set aside
If a list of files is omitted, all changes reported by "hg status"
- will be candidates for shelveing.
+ will be candidates for shelving.
You will be prompted for whether to shelve changes to each
modified file, and for files with multiple changes, for each
- change to use. For each query, the following responses are
- possible:
+ change to use.
+
+ The shelve command works with the Color extension to display
+ diffs in color.
- y - shelve this change
- n - skip this change
+ On each prompt, the following responses are possible:
- s - skip remaining changes to this file
- f - shelve remaining changes to this file
+ y - shelve this change
+ n - skip this change
- d - done, skip remaining changes and files
- a - shelve all changes to all remaining files
- q - quit, shelveing no changes
+ s - skip remaining changes to this file
+ f - shelve remaining changes to this file
- ? - display help'''
+ d - done, skip remaining changes and files
+ a - shelve all changes to all remaining files
+ q - quit, shelving no changes
+
+ ? - display help'''
if not ui.interactive:
raise util.Abort(_('shelve can only be run interactively'))
+ # List all the active shelves by name and return '
+ if opts['list']:
+ listshelves(ui,repo)
+ return
+
forced = opts['force'] or opts['append']
- if os.path.exists(repo.join('shelve')) and not forced:
+
+ # Shelf name and path
+ shelfname = opts.get('name')
+ shelfpath = getshelfpath(repo, shelfname)
+
+ if os.path.exists(repo.join(shelfpath)) and not forced:
raise util.Abort(_('shelve data already exists'))
def shelvefunc(ui, repo, message, match, opts):
@@ -398,7 +472,8 @@ def shelve(ui, repo, *pats, **opts):
fp = cStringIO.StringIO(patch_diff)
ac = parsepatch(fp)
fp.close()
- chunks = filterpatch(ui, ac)
+
+ chunks = filterpatch(ui, ac, not opts['all'])
rc = refilterpatch(ac, chunks)
contenders = {}
@@ -452,9 +527,9 @@ def shelve(ui, repo, *pats, **opts):
if doshelve:
ui.debug("saving patch to shelve\n")
if opts['append']:
- f = repo.opener('shelve', "a")
+ f = repo.opener(shelfpath, "a")
else:
- f = repo.opener('shelve', "w")
+ f = repo.opener(shelfpath, "w")
f.write(sp.getvalue())
del f
del sp
@@ -464,7 +539,7 @@ def shelve(ui, repo, *pats, **opts):
ui.debug('restoring %r to %r\n' % (tmpname, realname))
util.copyfile(tmpname, repo.wjoin(realname))
ui.debug('removing shelve file\n')
- os.unlink(repo.join('shelve'))
+ os.unlink(repo.join(shelfpath))
except OSError:
pass
@@ -480,18 +555,38 @@ def shelve(ui, repo, *pats, **opts):
fancyopts.fancyopts([], commands.commitopts, opts)
return cmdutil.commit(ui, repo, shelvefunc, pats, opts)
-
-def unshelve(ui, repo, *pats, **opts):
+def listshelves(ui, repo):
+ # Check for shelve file at old location first
+ if os.path.isfile(repo.join('shelve')):
+ ui.status('default\n')
+
+ # Now go through all the files in the shelves folder and list them out
+ dirname = repo.join('shelves')
+ if os.path.isdir(dirname):
+ for filename in os.listdir(repo.join('shelves')):
+ ui.status(filename + '\n')
+
+def unshelve(ui, repo, **opts):
'''restore shelved changes'''
+ # Shelf name and path
+ shelfname = opts.get('name')
+ shelfpath = getshelfpath(repo, shelfname)
+
+ # List all the active shelves by name and return '
+ if opts['list']:
+ listshelves(ui,repo)
+ return
+
try:
- fp = cStringIO.StringIO()
- fp.write(repo.opener('shelve').read())
+ patch_diff = repo.opener(shelfpath).read()
+ fp = cStringIO.StringIO(patch_diff)
if opts['inspect']:
ui.status(fp.getvalue())
else:
files = []
- for chunk in parsepatch(fp):
+ ac = parsepatch(fp)
+ for chunk in ac:
if isinstance(chunk, header):
files += chunk.files()
backupdir = repo.join('shelve-backups')
@@ -522,11 +617,28 @@ def unshelve(ui, repo, *pats, **opts):
if patchdone:
ui.debug("removing shelved patches\n")
- os.unlink(repo.join('shelve'))
+ os.unlink(repo.join(shelfpath))
ui.status("unshelve completed\n")
except IOError:
ui.warn('nothing to unshelve\n')
+_ui = None
+
+def uisetup(ui):
+ # FIXME: no ui object passed to extsetup()?
+ global _ui
+ _ui = ui
+
+
+def extsetup():
+ try:
+ # enable color diff in shelve command via Color extension
+ color = extensions.find('color')
+ color._setupcmd(_ui, 'shelve', cmdtable, color.colordiff,
+ color._diff_effects)
+ except KeyError:
+ pass
+
cmdtable = {
"shelve":
(shelve,
@@ -536,6 +648,11 @@ cmdtable = {
_('overwrite existing shelve data')),
('a', 'append', None,
_('append to existing shelve data')),
+ ('', 'all', None,
+ _('shelve all changes')),
+ ('n', 'name', '',
+ _('shelve changes to specified shelf name')),
+ ('l', 'list', None, _('list active shelves')),
] + commands.walkopts,
_('hg shelve [OPTION]... [FILE]...')),
"unshelve":
@@ -543,6 +660,9 @@ cmdtable = {
[('i', 'inspect', None, _('inspect shelved changes only')),
('f', 'force', None,
_('proceed even if patches do not unshelve cleanly')),
+ ('n', 'name', '',
+ _('unshelve changes from specified shelf name')),
+ ('l', 'list', None, _('list active shelves')),
],
- _('hg unshelve [OPTION]... [FILE]...')),
+ _('hg unshelve [OPTION]...')),
}