diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -844,13 +844,16 @@ class queue(object): 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 @@ class queue(object): 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 @@ class queue(object): 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 @@ class queue(object): 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 @@ class queue(object): 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: diff --git a/tests/test-mq-qpush-exact.t b/tests/test-mq-qpush-exact.t --- a/tests/test-mq-qpush-exact.t +++ b/tests/test-mq-qpush-exact.t @@ -163,8 +163,12 @@ qpush --exact --force with changes to an $ 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 @@ qpush --exact --force with changes to an $ 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 diff --git a/tests/test-mq.t b/tests/test-mq.t --- a/tests/test-mq.t +++ b/tests/test-mq.t @@ -1259,6 +1259,47 @@ Issue1033: test applying on an empty fil 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 @@ test qpush with --force, issue1087 $ 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