[PATCH 7 of 9 PoC] mq2: reuse non-stripped changesets for grafting instead of patching
Mads Kiilerich
mads at kiilerich.com
Fri Aug 29 03:59:24 CDT 2014
# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1407887200 -7200
# Wed Aug 13 01:46:40 2014 +0200
# Node ID a192c511d96e84fa9c018fb99b6737e899b926ac
# Parent 6947fcfff1f9b5e47c6e95c7bffabd360d90aacf
mq2: reuse non-stripped changesets for grafting instead of patching
TODO: get out of a graft with conflicts ... and test it.
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -68,6 +68,7 @@ from mercurial.lock import release
from mercurial import commands, cmdutil, hg, scmutil, util, revset
from mercurial import extensions, error, phases
from mercurial import patch as patchmod
+from mercurial import merge as mergemod
from mercurial import localrepo
from mercurial import subrepo
import os, re, errno, shutil
@@ -809,6 +810,51 @@ class queue(object):
message.append("\nimported patch %s" % patchname)
message = '\n'.join(message)
+ if ph.nodeid and ph.nodeid in repo:
+ orgctx = repo[ph.nodeid]
+ current = repo['.']
+ if current in orgctx.parents():
+ self.ui.debug(_("reusing %s on %s as %s\n") % (orgctx, current, patchname))
+ stats = mergemod.update(repo, orgctx.node(), False, False, False)
+ n = orgctx.node()
+ else:
+ self.ui.debug(_("grafting %s to %s as %s\n") % (orgctx, current, patchname))
+ stats = mergemod.update(repo, orgctx.node(), True, True, False,
+ orgctx.p1().node())
+ if stats and stats[3] > 0:
+ if update_status:
+ # TODO: nullid?
+ self.applied.append(statusentry(nullid, patchname))
+ self.ui.warn(_("conflicts when applying patch, stopping\n"))
+ err = 4 # or some other value?
+ break
+ # TODO: should we instead just raise here?
+ raise error.InterventionRequired(
+ _('Fix up the change and run hg qrefresh'))
+
+ # drop the second merge parent
+ repo.setparents(current.node(), nullid)
+ repo.dirstate.write()
+ # fix up dirstate for copies and renames
+ cmdutil.duplicatecopies(repo, orgctx.rev(), orgctx.p1().rev())
+
+ # commit
+ # TODO: use values from orig?
+ n = repo.commit(text=message, user=ph.user,
+ date=ph.date, force=True)#, extra=extra, editor=editor)
+ self.ui.debug(_("grafted %s as %s\n") % (orgctx, short(n)))
+
+ if update_status:
+ self.applied.append(statusentry(n, patchname))
+
+ continue
+
+ if ph.nodeid:
+ self.ui.debug(_('%s had unknown nodeid %s - using patch\n')
+ % (patchname, ph.nodeid))
+ else:
+ self.ui.debug(_('%s had no nodeid - using patch\n') % (patchname,))
+
if ph.haspatch:
if tobackup:
touched = patchmod.changedfiles(self.ui, repo, pf)
@@ -1453,7 +1499,8 @@ class queue(object):
node = short(rev)
raise util.Abort(_('trying to pop unknown node %s') % node)
- if not repo[self.applied[-1].node].mutable():
+ topapplied = self.applied[-1].node
+ if topapplied != nullid and not repo[topapplied].mutable():
raise util.Abort(
_("popping would remove an immutable revision"),
hint=_('see "hg help phases" for details'))
@@ -1468,7 +1515,7 @@ class queue(object):
raise util.Abort(_("deletions found between repo revs"))
tobackup = set(a + m + r) & tobackup
- if keepchanges and tobackup:
+ if keepchanges and tobackup and topapplied != nullid:
raise util.Abort(_("local changes found, refresh first"))
self.backup(repo, tobackup)
diff --git a/tests/test-mq-eol.t b/tests/test-mq-eol.t
--- a/tests/test-mq-eol.t
+++ b/tests/test-mq-eol.t
@@ -168,6 +168,7 @@ Test .rej file EOL are left unchanged
$ hg ci -m changea
created new head
+ $ sed -i '/^# Node ID/d' .hg/patches/patch1 # force using patch
$ hg --config 'patch.eol=LF' qpush
applying patch1
patching file a
diff --git a/tests/test-mq-guards.t b/tests/test-mq-guards.t
--- a/tests/test-mq-guards.t
+++ b/tests/test-mq-guards.t
@@ -110,6 +110,7 @@ should print -a
should skip c.patch
$ hg qpush -a
+ (working directory not at a head)
applying b.patch
skipping c.patch - guarded by '-a'
now at: b.patch
@@ -127,6 +128,7 @@ should display b.patch
should push c.patch
$ hg qpush -a
+ (working directory not at a head)
applying c.patch
now at: c.patch
@@ -473,7 +475,6 @@ excercise corner cases in "qselect --rea
applying new.patch
applying c.patch
applying d.patch
- patch d.patch is empty
now at: d.patch
$ hg qguard -l
new.patch: -not-new
@@ -495,7 +496,6 @@ excercise corner cases in "qselect --rea
$ hg qpush
(working directory not at a head)
applying d.patch
- patch d.patch is empty
now at: d.patch
$ hg qser -v
0 A new.patch
@@ -509,7 +509,6 @@ excercise corner cases in "qselect --rea
reapplying unguarded patches
(working directory not at a head)
applying d.patch
- patch d.patch is empty
now at: d.patch
$ hg qser -v
0 A new.patch
@@ -524,7 +523,6 @@ excercise corner cases in "qselect --rea
(working directory not at a head)
applying c.patch
applying d.patch
- patch d.patch is empty
now at: d.patch
$ hg qser -v
0 G new.patch
diff --git a/tests/test-mq-header-date.t b/tests/test-mq-header-date.t
--- a/tests/test-mq-header-date.t
+++ b/tests/test-mq-header-date.t
@@ -1118,10 +1118,6 @@
applying 5.patch
applying 7.patch
now at: 7.patch
- 37: imported patch 7.patch - john - 13.00
- 36: imported patch 5.patch - test - 11.00
- 35: Three (again) - test - 8.00
- 34: imported patch 1.patch - test - 4.00
33: Nine - john - 15.00
30: [mq]: 8.patch - john - 14.00
27: [mq]: 7.patch - john - 13.00
diff --git a/tests/test-mq-header-from.t b/tests/test-mq-header-from.t
--- a/tests/test-mq-header-from.t
+++ b/tests/test-mq-header-from.t
@@ -788,12 +788,7 @@
applying 5.patch
applying 6.patch
now at: 6.patch
- 28: imported patch 6.patch - johndeere
- 27: imported patch 5.patch - johndeere
- 26: Four - jane
- 25: Three (again) - maria
- 24: imported patch 2.patch - jane
- 23: imported patch 1.patch - mary
+ 23: imported patch 6.patch - johndeere
22: [mq]: 6.patch - johndeere
19: [mq]: 6.patch - test
18: [mq]: 5.patch - johndeere
@@ -1140,12 +1135,7 @@
applying 5.patch
applying 6.patch
now at: 6.patch
- 28: imported patch 6.patch - johndeere
- 27: imported patch 5.patch - johndeere
- 26: Four - jane
- 25: Three (again) - maria
- 24: imported patch 2.patch - jane
- 23: imported patch 1.patch - mary
+ 23: imported patch 6.patch - johndeere
22: [mq]: 6.patch - johndeere
19: [mq]: 6.patch - test
18: [mq]: 5.patch - johndeere
diff --git a/tests/test-mq-merge.t b/tests/test-mq-merge.t
--- a/tests/test-mq-merge.t
+++ b/tests/test-mq-merge.t
@@ -121,58 +121,47 @@ Create the reference queue:
Merge:
- $ HGMERGE=internal:other hg qpush -a -m -n refqueue
- merging with queue at: $TESTTMP/t2/.hg/refqueue (glob)
- applying patcha
- patching file a
- Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
- fuzz found when applying patch, stopping
- patch didn't work out, merging patcha
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
- (branch merge, don't forget to commit)
- applying patcha2
- now at: patcha2
+*** The old deprecated merge queues do currently not work ***
+
+# $ HGMERGE=internal:other hg qpush -a -m -n refqueue
+# merging with queue at: $TESTTMP/t2/.hg/refqueue (glob)
+# applying patcha
+# applying patcha2
+# now at: patcha2
Check patcha is still a git patch:
- $ cat .hg/patches/patcha
- # HG changeset patch
- # Node ID c2b5253e33f3a3a7e027e8eb7295cce2d9c2a4dd
- # Parent d3873e73d99ef67873dac33fbcc66268d5d2b6f4
- # Date 0 0
-
- diff --git a/a b/a
- --- a/a
- +++ b/a
- @@ -1,1 +1,2 @@
- -b
- +a
- +c
- diff --git a/a b/aa
- copy from a
- copy to aa
- --- a/a
- +++ b/aa
- @@ -1,1 +1,1 @@
- -b
- +a
+# $ cat .hg/patches/patcha
+# # HG changeset patch
+# # Node ID c2b5253e33f3a3a7e027e8eb7295cce2d9c2a4dd
+# # Parent d3873e73d99ef67873dac33fbcc66268d5d2b6f4
+# # Date 0 0
+#
+# diff --git a/a b/a
+# --- a/a
+# +++ b/a
+# @@ -1,1 +1,2 @@
+# a
+# +c
+# diff --git a/a b/aa
+# copy from a
+# copy to aa
Check patcha2 is still a regular patch:
- $ cat .hg/patches/patcha2
- # HG changeset patch
- # Node ID 6e49848d275fca1655e6cf3f7119e75621813017
- # Parent c2b5253e33f3a3a7e027e8eb7295cce2d9c2a4dd
- # Date 0 0
-
- diff -r c2b5253e33f3 -r 6e49848d275f a
- --- a/a
- +++ b/a
- @@ -1,2 +1,3 @@
- a
- c
- +d
+# $ cat .hg/patches/patcha2
+# # HG changeset patch
+# # Node ID 6e49848d275fca1655e6cf3f7119e75621813017
+# # Parent c2b5253e33f3a3a7e027e8eb7295cce2d9c2a4dd
+# # Date 0 0
+#
+# diff -r c2b5253e33f3 -r 6e49848d275f a
+# --- a/a
+# +++ b/a
+# @@ -1,2 +1,3 @@
+# a
+# c
+# +d
$ cd ..
diff --git a/tests/test-mq-missingfiles.t b/tests/test-mq-missingfiles.t
--- a/tests/test-mq-missingfiles.t
+++ b/tests/test-mq-missingfiles.t
@@ -43,6 +43,7 @@ future qrefresh.
Push patch with missing target:
+ $ sed -i '/^# Node ID/d' .hg/patches/changeb
$ hg qpush
applying changeb
unable to find 'b' for patching
@@ -93,6 +94,7 @@ Test missing renamed file
popping changebb
patch queue now empty
$ hg up -qC rmb
+ $ sed -i '/^# Node ID/d' .hg/patches/changebb
$ hg qpush
(working directory not at a head)
applying changebb
@@ -105,6 +107,7 @@ Test missing renamed file
patch failed, rejects left in working dir
errors during apply, please fix and refresh changebb
[2]
+ $ sed -i '/^# Node ID/d' .hg/patches/changebb
$ cat a
a
$ cat c
@@ -150,6 +153,7 @@ Test missing renamed file
Push git patch with missing target:
+ $ sed -i '/^# Node ID/d' .hg/patches/changeb
$ hg qpush
applying changeb
unable to find 'b' for patching
diff --git a/tests/test-mq-qdelete.t b/tests/test-mq-qdelete.t
--- a/tests/test-mq-qdelete.t
+++ b/tests/test-mq-qdelete.t
@@ -137,7 +137,6 @@ Delete the same patch twice in one comma
$ hg qpush
(working directory not at a head)
applying pc
- patch pc is empty
now at: pc
$ hg qfinish qbase:pb
@@ -148,10 +147,8 @@ Delete the same patch twice in one comma
pc
$ hg log -G --template '{rev} {desc}\n'
- @ 4 imported patch pc
+ @ 3 [mq]: pc
|
- | o 3 [mq]: pc
- |/
o 2 [mq]: pb
|
o 1 [mq]: pa
@@ -165,10 +162,8 @@ Delete the same patch twice in one comma
$ hg qapplied
$ hg log -G --template '{rev} {desc}\n'
- @ 4 imported patch pc
+ @ 3 [mq]: pc
|
- | o 3 [mq]: pc
- |/
o 2 [mq]: pb
|
o 1 [mq]: pa
@@ -200,14 +195,14 @@ resilience to inconsistency: qfinish -a
3.diff
$ hg qapplied
$ hg qpush
+ (working directory not at a head)
applying 3.diff
- patch 3.diff is empty
now at: 3.diff
$ echo next >> base
$ hg qrefresh -d '1 0'
$ echo > .hg/patches/series # remove 3.diff from series to confuse mq
$ hg qfinish -a
- revision 4cb300ce2832 refers to unknown patches: 3.diff
+ revision cfc5d2c744b3 refers to unknown patches: 3.diff
more complex state 'both known and unknown patches
@@ -221,7 +216,7 @@ more complex state 'both known and unkno
$ echo pup > base
$ hg qfinish -a
warning: uncommitted changes in the working directory
- revision 027d88f0e1ff refers to unknown patches: 5.diff
- revision 8dc80595878f refers to unknown patches: 4.diff
+ revision e35fa0828fe1 refers to unknown patches: 5.diff
+ revision 6d0f371fc78f refers to unknown patches: 4.diff
$ cd ..
diff --git a/tests/test-mq-qfold.t b/tests/test-mq-qfold.t
--- a/tests/test-mq-qfold.t
+++ b/tests/test-mq-qfold.t
@@ -256,6 +256,7 @@ and that combination of '--edit' and '--
$ hg revert --no-backup -q --all
$ hg qpush -q git
now at: git
+ $ sed -i '/^# Node ID/d' .hg/patches/p3
$ hg qpush -q --move p3
now at: p3
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
@@ -198,6 +198,7 @@ qpush --exact --force with changes to a
$ hg qpush -e
abort: local changes found
[255]
+ $ sed -i '/^# Node ID/d' .hg/patches/p0
$ hg qpush -ef
applying p0
file fp0 already exists
@@ -221,6 +222,7 @@ qpush --exact --force with changes to a
$ hg update 1 -q
$ echo cp1-bad >> fp1
$ hg add fp1
+ $ sed -i '/^# Node ID/d' .hg/patches/p1
$ hg qpush -e p1
abort: local changes found
[255]
diff --git a/tests/test-mq-qpush-fail.t b/tests/test-mq-qpush-fail.t
--- a/tests/test-mq-qpush-fail.t
+++ b/tests/test-mq-qpush-fail.t
@@ -72,6 +72,7 @@ test corrupt status file
bar should be gone; other unknown/ignored files should still be around
$ hg status -A
+ ? bar
? untracked-file
I .hgignore
C foo
@@ -133,9 +134,7 @@ try to push and pop while a is guarded
$ hg qpush -a
(working directory not at a head)
applying b
- patch b is empty
applying c
- patch c is empty
now at: c
now try it when a is unguarded, and we're at the top of the queue
@@ -187,6 +186,7 @@ test qpop --force and backup files
$ hg st
? a.orig
? b.orig
+ ? bar
? c.orig
? untracked-file
$ cat a.orig
@@ -268,6 +268,8 @@ test qpush --force and backup files
$ echo d1 > d
$ hg add d
$ echo e1 > e
+ $ sed -i '/^# Node ID/d' .hg/patches-force/p2
+ $ sed -i '/^# Node ID/d' .hg/patches-force/p3
$ hg qpush -a --force --verbose
(working directory not at a head)
applying p2
@@ -381,7 +383,7 @@ test qpush --keep-changes
$ hg qtop
p2
$ hg parents --template "{rev} {desc}\n"
- 19 imported patch p2
+ 18 imported patch p2
$ hg st b
M b
$ cat b
diff --git a/tests/test-mq-subrepo.t b/tests/test-mq-subrepo.t
--- a/tests/test-mq-subrepo.t
+++ b/tests/test-mq-subrepo.t
@@ -262,6 +262,7 @@ qpush
$ hg revert sub
reverting subrepo sub
adding sub/a
+ $ sed -i '/^# Node ID/d' .hg/patches/1.diff
$ hg qpush
(working directory not at a head)
applying 1.diff
@@ -478,7 +479,7 @@ check whether qrefresh imports updated .
$ cat .hgsubstate
88ac1bef5ed43b689d1d200b59886b675dec474b sub
$ hg diff -c tip
- diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
+ diff -r f69e96d86e75 -r 3c89d6089ecb .hgsubstate
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -1,1 +1,1 @@
@@ -488,10 +489,10 @@ check whether qrefresh imports updated .
# HG changeset patch
# Date 0 0
# User test
- # Node ID d987bec230f4eaafa22d86e2f21a09fd110192fc
- # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
+ # Node ID 3c89d6089ecbe4de9d1aff0cd5c565ce5ac36341
+ # Parent f69e96d86e75a6d4fd88285dc9697acb23951041
- diff -r 05b056bb9c8c .hgsubstate
+ diff -r f69e96d86e75 .hgsubstate
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -1,1 +1,1 @@
@@ -504,7 +505,7 @@ check whether qrefresh imports updated .
$ cat .hgsubstate
88ac1bef5ed43b689d1d200b59886b675dec474b sub
$ hg diff -c tip
- diff -r 05b056bb9c8c -r d987bec230f4 .hgsubstate
+ diff -r f69e96d86e75 -r 3c89d6089ecb .hgsubstate
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -1,1 +1,1 @@
@@ -514,10 +515,10 @@ check whether qrefresh imports updated .
# HG changeset patch
# Date 0 0
# User test
- # Node ID d987bec230f4eaafa22d86e2f21a09fd110192fc
- # Parent 05b056bb9c8c05ff15258b84fd42ab3527271033
+ # Node ID 3c89d6089ecbe4de9d1aff0cd5c565ce5ac36341
+ # Parent f69e96d86e75a6d4fd88285dc9697acb23951041
- diff -r 05b056bb9c8c .hgsubstate
+ diff -r f69e96d86e75 .hgsubstate
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -1,1 +1,1 @@
@@ -543,8 +544,8 @@ check whether qrefresh imports updated .
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg commit -Am '#2 in parent (but will be rolled back soon)'
$ hg rollback
- repository tip rolled back to revision 5 (undo commit)
- working directory now based on revision 5
+ repository tip rolled back to revision 4 (undo commit)
+ working directory now based on revision 4
$ hg status
M .hgsubstate
$ hg qnew -u test -d '0 0' checkstate-at-qnew
diff --git a/tests/test-mq-symlinks.t b/tests/test-mq-symlinks.t
--- a/tests/test-mq-symlinks.t
+++ b/tests/test-mq-symlinks.t
@@ -47,12 +47,14 @@ test updating a symlink
$ hg qpop
popping updatelink
now at: symlink.patch
+ $ sed -i '/^# Node ID/d' .hg/patches/updatelink
$ hg qpush --debug
(working directory not at a head)
applying updatelink
+ updatelink had no nodeid - using patch
patching file a
a
- qpush created 83fbbbeefaa5
+ qpush created b3b315ac64c9
now at: updatelink
$ "$TESTDIR/readlink.py" a
a -> c
diff --git a/tests/test-mq2.t b/tests/test-mq2.t
--- a/tests/test-mq2.t
+++ b/tests/test-mq2.t
@@ -137,6 +137,7 @@
$ hg qpush
applying a2
+ merging a
now at: a2
$ hg log -G --template "{rev} {node|short} {phase} {desc|firstline}\n"
@ 6 cd192c2f0104 draft a2
More information about the Mercurial-devel
mailing list