mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 15:27:13 +03:00
mq: introduce qpush --check
qpush --check let you qpush with uncommitted files not overlapping patched files.
This commit is contained in:
parent
55a575b59a
commit
b9c8ba9be4
54
hgext/mq.py
54
hgext/mq.py
@ -280,6 +280,9 @@ def newcommit(repo, phase, *args, **kwargs):
|
||||
if phase is not None:
|
||||
repo.ui.restoreconfig(backup)
|
||||
|
||||
class AbortNoCleanup(error.Abort):
|
||||
pass
|
||||
|
||||
class queue(object):
|
||||
def __init__(self, ui, path, patchdir=None):
|
||||
self.basepath = path
|
||||
@ -681,7 +684,7 @@ class queue(object):
|
||||
|
||||
def apply(self, repo, series, list=False, update_status=True,
|
||||
strict=False, patchdir=None, merge=None, all_files=None,
|
||||
tobackup=None):
|
||||
tobackup=None, check=False):
|
||||
wlock = lock = tr = None
|
||||
try:
|
||||
wlock = repo.wlock()
|
||||
@ -690,10 +693,14 @@ class queue(object):
|
||||
try:
|
||||
ret = self._apply(repo, series, list, update_status,
|
||||
strict, patchdir, merge, all_files=all_files,
|
||||
tobackup=tobackup)
|
||||
tobackup=tobackup, check=check)
|
||||
tr.close()
|
||||
self.savedirty()
|
||||
return ret
|
||||
except AbortNoCleanup:
|
||||
tr.close()
|
||||
self.savedirty()
|
||||
return 2, repo.dirstate.p1()
|
||||
except:
|
||||
try:
|
||||
tr.abort()
|
||||
@ -708,7 +715,7 @@ class queue(object):
|
||||
|
||||
def _apply(self, repo, series, list=False, update_status=True,
|
||||
strict=False, patchdir=None, merge=None, all_files=None,
|
||||
tobackup=None):
|
||||
tobackup=None, check=False):
|
||||
"""returns (error, hash)
|
||||
|
||||
error = 1 for unable to read, 2 for patch failed, 3 for patch
|
||||
@ -749,6 +756,9 @@ class queue(object):
|
||||
if tobackup:
|
||||
touched = patchmod.changedfiles(self.ui, repo, pf)
|
||||
touched = set(touched) & tobackup
|
||||
if touched and check:
|
||||
raise AbortNoCleanup(
|
||||
_("local changes found, refresh first"))
|
||||
self.backup(repo, touched, copy=True)
|
||||
tobackup = tobackup - touched
|
||||
(patcherr, files, fuzz) = self.patch(repo, pf)
|
||||
@ -959,6 +969,10 @@ class queue(object):
|
||||
else:
|
||||
raise util.Abort(_('patch "%s" already exists') % name)
|
||||
|
||||
def checkforcecheck(self, check, force):
|
||||
if force and check:
|
||||
raise util.Abort(_('cannot use both --force and --check'))
|
||||
|
||||
def new(self, repo, patchfn, *pats, **opts):
|
||||
"""options:
|
||||
msg: a string or a no-argument function returning a string
|
||||
@ -1156,8 +1170,9 @@ class queue(object):
|
||||
return self.series[i + off]
|
||||
raise util.Abort(_("patch %s not in series") % patch)
|
||||
|
||||
def push(self, repo, patch=None, force=False, list=False,
|
||||
mergeq=None, all=False, move=False, exact=False, nobackup=False):
|
||||
def push(self, repo, patch=None, force=False, list=False, mergeq=None,
|
||||
all=False, move=False, exact=False, nobackup=False, check=False):
|
||||
self.checkforcecheck(check, force)
|
||||
diffopts = self.diffopts()
|
||||
wlock = repo.wlock()
|
||||
try:
|
||||
@ -1212,10 +1227,13 @@ class queue(object):
|
||||
if start == len(self.series):
|
||||
self.ui.warn(_('patch series already fully applied\n'))
|
||||
return 1
|
||||
if not force:
|
||||
if not force and not check:
|
||||
self.checklocalchanges(repo, refresh=self.applied)
|
||||
|
||||
if exact:
|
||||
if check:
|
||||
raise util.Abort(
|
||||
_("cannot use --exact and --check together"))
|
||||
if move:
|
||||
raise util.Abort(_("cannot use --exact and --move together"))
|
||||
if self.applied:
|
||||
@ -1257,9 +1275,12 @@ class queue(object):
|
||||
end = self.series.index(patch, start) + 1
|
||||
|
||||
tobackup = set()
|
||||
if not nobackup and force:
|
||||
if (not nobackup and force) or check:
|
||||
m, a, r, d = self.checklocalchanges(repo, force=True)
|
||||
tobackup.update(m + a)
|
||||
if check:
|
||||
tobackup.update(m + a + r + d)
|
||||
else:
|
||||
tobackup.update(m + a)
|
||||
|
||||
s = self.series[start:end]
|
||||
all_files = set()
|
||||
@ -1268,7 +1289,7 @@ class queue(object):
|
||||
ret = self.mergepatch(repo, mergeq, s, diffopts)
|
||||
else:
|
||||
ret = self.apply(repo, s, list, all_files=all_files,
|
||||
tobackup=tobackup)
|
||||
tobackup=tobackup, check=check)
|
||||
except:
|
||||
self.ui.warn(_('cleaning up working directory...'))
|
||||
node = repo.dirstate.p1()
|
||||
@ -1300,8 +1321,7 @@ class queue(object):
|
||||
|
||||
def pop(self, repo, patch=None, force=False, update=True, all=False,
|
||||
nobackup=False, check=False):
|
||||
if force and check:
|
||||
raise util.Abort(_('cannot use both --force and --check'))
|
||||
self.checkforcecheck(check, force)
|
||||
wlock = repo.wlock()
|
||||
try:
|
||||
if patch:
|
||||
@ -2638,7 +2658,8 @@ def savename(path):
|
||||
return newpath
|
||||
|
||||
@command("^qpush",
|
||||
[('f', 'force', None, _('apply on top of local changes')),
|
||||
[('c', 'check', None, _('tolerate non-conflicting local changes')),
|
||||
('f', 'force', None, _('apply on top of local changes')),
|
||||
('e', 'exact', None, _('apply the target patch to its recorded parent')),
|
||||
('l', 'list', None, _('list patch name in commit text')),
|
||||
('a', 'all', None, _('apply all patches')),
|
||||
@ -2652,8 +2673,10 @@ def savename(path):
|
||||
def push(ui, repo, patch=None, **opts):
|
||||
"""push the next patch onto the stack
|
||||
|
||||
When -f/--force is applied, all local changes in patched files
|
||||
will be lost.
|
||||
By default, abort if the working directory contains uncommitted
|
||||
changes. With -c/--check, abort only if the uncommitted files
|
||||
overlap with patched files. With -f/--force, backup and patch over
|
||||
uncommitted changes.
|
||||
|
||||
Return 0 on success.
|
||||
"""
|
||||
@ -2672,7 +2695,8 @@ def push(ui, repo, patch=None, **opts):
|
||||
ui.warn(_("merging with queue at: %s\n") % mergeq.path)
|
||||
ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
|
||||
mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
|
||||
exact=opts.get('exact'), nobackup=opts.get('no_backup'))
|
||||
exact=opts.get('exact'), nobackup=opts.get('no_backup'),
|
||||
check=opts.get('check'))
|
||||
return ret
|
||||
|
||||
@command("^qpop",
|
||||
|
@ -317,3 +317,54 @@ test qgoto --force --no-backup
|
||||
now at: p2
|
||||
$ test -f a.orig && echo 'error: backup with --no-backup'
|
||||
[1]
|
||||
|
||||
test qpush --check
|
||||
|
||||
$ hg qpush --check --force
|
||||
abort: cannot use both --force and --check
|
||||
[255]
|
||||
$ hg qpush --check --exact
|
||||
abort: cannot use --exact and --check together
|
||||
[255]
|
||||
$ echo b >> b
|
||||
$ hg qpush --check
|
||||
applying p3
|
||||
errors during apply, please fix and refresh p2
|
||||
[2]
|
||||
$ rm b
|
||||
$ hg qpush --check
|
||||
applying p3
|
||||
errors during apply, please fix and refresh p2
|
||||
[2]
|
||||
$ hg rm -A b
|
||||
$ hg qpush --check
|
||||
applying p3
|
||||
errors during apply, please fix and refresh p2
|
||||
[2]
|
||||
$ hg revert -aq b
|
||||
$ echo d > d
|
||||
$ hg add d
|
||||
$ hg qpush --check
|
||||
applying p3
|
||||
errors during apply, please fix and refresh p2
|
||||
[2]
|
||||
$ hg forget d
|
||||
$ rm d
|
||||
$ hg qpop
|
||||
popping p2
|
||||
patch queue now empty
|
||||
$ echo b >> b
|
||||
$ hg qpush -a --check
|
||||
applying p2
|
||||
applying p3
|
||||
errors during apply, please fix and refresh p2
|
||||
[2]
|
||||
$ hg qtop
|
||||
p2
|
||||
$ hg parents --template "{rev} {desc}\n"
|
||||
2 imported patch p2
|
||||
$ hg st b
|
||||
M b
|
||||
$ cat b
|
||||
b
|
||||
b
|
||||
|
Loading…
Reference in New Issue
Block a user