mq: allow to qpop/push with a dirty working copy (issue2780)
It's safe to do so if the sets of changed files in the
working copy and patches are disjoint.
--- a/hgext/mq.py Fri May 06 19:03:41 2011 +0300
+++ b/hgext/mq.py Fri May 06 19:55:46 2011 +0300
@@ -844,13 +844,16 @@
inclsubs.append(s)
return inclsubs
+ def localchangesfound(self, refresh=True):
+ if refresh:
+ raise util.Abort(_("local changes found, refresh first"))
+ else:
+ raise util.Abort(_("local changes found"))
+
def check_localchanges(self, repo, force=False, refresh=True):
m, a, r, d = repo.status()[:4]
if (m or a or r or d) and not force:
- if refresh:
- raise util.Abort(_("local changes found, refresh first"))
- else:
- raise util.Abort(_("local changes found"))
+ self.localchangesfound(refresh)
return m, a, r, d
_reserved = ('series', 'status', 'guards', '.', '..')
@@ -1127,8 +1130,6 @@
if start == len(self.series):
self.ui.warn(_('patch series already fully applied\n'))
return 1
- if not force:
- self.check_localchanges(repo, refresh=self.applied)
if exact:
if move:
@@ -1167,6 +1168,19 @@
end = self.series.index(patch, start) + 1
s = self.series[start:end]
+
+ if not force:
+ mm, aa, rr, dd = repo.status()[:4]
+ wcfiles = set(mm + aa + rr + dd)
+ if wcfiles:
+ for patchname in s:
+ pf = os.path.join(self.path, patchname)
+ patchfiles = patchmod.changedfiles(pf, strip=1)
+ if not wcfiles.isdisjoint(patchfiles):
+ self.localchangesfound(self.applied)
+ elif mergeq:
+ self.check_localchanges(refresh=self.applied)
+
all_files = set()
try:
if mergeq:
@@ -1247,9 +1261,6 @@
break
update = needupdate
- if not force and update:
- self.check_localchanges(repo)
-
self.applied_dirty = 1
end = len(self.applied)
rev = self.applied[start].node
@@ -1272,6 +1283,12 @@
qp = self.qparents(repo, rev)
ctx = repo[qp]
m, a, r, d = repo.status(qp, top)[:4]
+ parentfiles = set(m + a + r + d)
+ if not force and parentfiles:
+ mm, aa, rr, dd = repo.status()[:4]
+ wcfiles = set(mm + aa + rr + dd)
+ if not wcfiles.isdisjoint(parentfiles):
+ self.localchangesfound()
if d:
raise util.Abort(_("deletions found between repo revs"))
for f in a:
--- a/tests/test-mq-qpush-exact.t Fri May 06 19:03:41 2011 +0300
+++ b/tests/test-mq-qpush-exact.t Fri May 06 19:55:46 2011 +0300
@@ -163,8 +163,12 @@
$ hg update 1 -q
$ echo c0 >> f0
$ hg qpush -e
- abort: local changes found
- [255]
+ applying p0
+ now at: p0
+ $ cat f0
+ c0
+ $ hg qpop -aq
+ patch queue now empty
$ hg qpush -ef
applying p0
now at: p0
@@ -178,8 +182,13 @@
$ hg update 1 -q
$ echo c0 >> f0
$ hg qpush -e p1
- abort: local changes found
- [255]
+ applying p0
+ applying p1
+ now at: p1
+ $ cat f0
+ c0
+ $ hg qpop -aq
+ patch queue now empty
$ hg qpush -e p1 -f
applying p0
applying p1
--- a/tests/test-mq.t Fri May 06 19:03:41 2011 +0300
+++ b/tests/test-mq.t Fri May 06 19:55:46 2011 +0300
@@ -1259,6 +1259,47 @@
now at: changea
$ cd ..
+test qpop with local changes, issue2780
+
+ $ hg init forcepop
+ $ cd forcepop
+ $ echo 1 > 1
+ $ hg ci -Am 1
+ adding 1
+ $ hg qnew foo
+ $ echo 2 > 2
+ $ hg add
+ adding 2
+
+unrelated changes
+
+ $ hg qpop
+ popping foo
+ patch queue now empty
+
+related changes
+
+ $ hg forget 2
+ $ rm 2
+ $ hg qpush
+ applying foo
+ patch foo is empty
+ now at: foo
+ $ echo 2 >> 1
+ $ hg qrefresh
+ $ echo 2 >> 1
+ $ hg qpop
+ abort: local changes found, refresh first
+ [255]
+ $ hg st
+ M 1
+
+related changes with force
+ $ hg qpop --force
+ popping foo
+ patch queue now empty
+ $ hg st
+ $ cd ..
test qpush with --force, issue1087
@@ -1276,16 +1317,9 @@
$ echo world >> hello.txt
-qpush should fail, local changes
+apply, should not discard changes with empty patch
$ hg qpush
- abort: local changes found
- [255]
-
-
-apply force, should not discard changes with empty patch
-
- $ hg qpush -f
applying empty
patch empty is empty
now at: empty