mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
fb390f5f84
stripping of applied mq patches leads to wrong state recorded in status file. find all mq patches that will be affected and clean up status file before strip.
643 lines
14 KiB
Plaintext
643 lines
14 KiB
Plaintext
% help
|
||
mq extension - manage a stack of patches
|
||
|
||
This extension lets you work with a stack of patches in a Mercurial
|
||
repository. It manages two stacks of patches - all known patches, and applied
|
||
patches (subset of known patches).
|
||
|
||
Known patches are represented as patch files in the .hg/patches directory.
|
||
Applied patches are both patch files and changesets.
|
||
|
||
Common tasks (use "hg help command" for more details):
|
||
|
||
create new patch qnew
|
||
import existing patch qimport
|
||
|
||
print patch series qseries
|
||
print applied patches qapplied
|
||
|
||
add known patch to applied stack qpush
|
||
remove patch from applied stack qpop
|
||
refresh contents of top applied patch qrefresh
|
||
|
||
By default, mq will automatically use git patches when required to avoid
|
||
losing file mode changes, copy records, binary files or empty files creations
|
||
or deletions. This behaviour can be configured with:
|
||
|
||
[mq]
|
||
git = auto/keep/yes/no
|
||
|
||
If set to 'keep', mq will obey the [diff] section configuration while
|
||
preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq
|
||
will override the [diff] section and always generate git or regular patches,
|
||
possibly losing data in the second case.
|
||
|
||
You will by default be managing a patch queue named "patches". You can create
|
||
other, independent patch queues with the "hg qqueue" command.
|
||
|
||
list of commands:
|
||
|
||
qapplied print the patches already applied
|
||
qclone clone main and patch repository at same time
|
||
qdelete remove patches from queue
|
||
qdiff diff of the current patch and subsequent modifications
|
||
qfinish move applied patches into repository history
|
||
qfold fold the named patches into the current patch
|
||
qgoto push or pop patches until named patch is at top of stack
|
||
qguard set or print guards for a patch
|
||
qheader print the header of the topmost or specified patch
|
||
qimport import a patch
|
||
qnew create a new patch
|
||
qnext print the name of the next patch
|
||
qpop pop the current patch off the stack
|
||
qprev print the name of the previous patch
|
||
qpush push the next patch onto the stack
|
||
qqueue manage multiple patch queues
|
||
qrefresh update the current patch
|
||
qrename rename a patch
|
||
qselect set or print guarded patches to push
|
||
qseries print the entire series file
|
||
qtop print the name of the current patch
|
||
qunapplied print the patches not yet applied
|
||
strip strip a changeset and all its descendants from the repository
|
||
|
||
use "hg -v help mq" to show aliases and global options
|
||
adding a
|
||
updating to branch default
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
adding b/z
|
||
% qinit
|
||
% -R qinit
|
||
% qinit -c
|
||
A .hgignore
|
||
A series
|
||
% qinit; qinit -c
|
||
.hgignore:
|
||
^\.hg
|
||
^\.mq
|
||
syntax: glob
|
||
status
|
||
guards
|
||
series:
|
||
abort: repository already exists!
|
||
% qinit; <stuff>; qinit -c
|
||
adding .hg/patches/A
|
||
adding .hg/patches/B
|
||
A .hgignore
|
||
A A
|
||
A B
|
||
A series
|
||
.hgignore:
|
||
status
|
||
bleh
|
||
series:
|
||
A
|
||
B
|
||
% status --mq with color (issue2096)
|
||
[0;32;1mA .hgignore[0m
|
||
[0;32;1mA A[0m
|
||
[0;32;1mA B[0m
|
||
[0;32;1mA series[0m
|
||
% init --mq without repo
|
||
abort: There is no Mercurial repository here (.hg not found)
|
||
% init --mq with repo path
|
||
ok
|
||
% init --mq with nonexistent directory
|
||
abort: repository nonexistentdir not found!
|
||
% init --mq with bundle (non "local")
|
||
abort: only a local queue repository may be initialized
|
||
% qrefresh
|
||
foo bar
|
||
|
||
diff -r xa
|
||
--- a/a
|
||
+++ b/a
|
||
@@ -1,1 +1,2 @@
|
||
a
|
||
+a
|
||
% empty qrefresh
|
||
revision:
|
||
patch:
|
||
foo bar
|
||
|
||
working dir diff:
|
||
--- a/a
|
||
+++ b/a
|
||
@@ -1,1 +1,2 @@
|
||
a
|
||
+a
|
||
% qpop
|
||
popping test.patch
|
||
patch queue now empty
|
||
% qpush with dump of tag cache
|
||
.hg/tags.cache (pre qpush):
|
||
1
|
||
|
||
applying test.patch
|
||
now at: test.patch
|
||
.hg/tags.cache (post qpush):
|
||
2
|
||
|
||
% pop/push outside repo
|
||
popping test.patch
|
||
patch queue now empty
|
||
applying test.patch
|
||
now at: test.patch
|
||
% qrefresh in subdir
|
||
% pop/push -a in subdir
|
||
popping test2.patch
|
||
popping test.patch
|
||
patch queue now empty
|
||
applying test.patch
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
% qseries
|
||
test.patch
|
||
test2.patch
|
||
0 A test.patch: f...
|
||
1 A test2.patch:
|
||
popping test2.patch
|
||
now at: test.patch
|
||
0 A test.patch: foo bar
|
||
1 U test2.patch:
|
||
mq: 1 applied, 1 unapplied
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
mq: 2 applied
|
||
% qapplied
|
||
test.patch
|
||
test2.patch
|
||
% qtop
|
||
test2.patch
|
||
% prev
|
||
test.patch
|
||
% next
|
||
all patches applied
|
||
popping test2.patch
|
||
now at: test.patch
|
||
% commit should fail
|
||
abort: cannot commit over an applied mq patch
|
||
% push should fail
|
||
pushing to ../../k
|
||
abort: source has mq patches applied
|
||
% import should fail
|
||
abort: cannot import over an applied patch
|
||
% import --no-commit should succeed
|
||
applying ../../import.diff
|
||
M a
|
||
% qunapplied
|
||
test2.patch
|
||
% qpush/qpop with index
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
popping test2.patch
|
||
popping test1b.patch
|
||
now at: test.patch
|
||
applying test1b.patch
|
||
now at: test1b.patch
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
popping test2.patch
|
||
now at: test1b.patch
|
||
popping test1b.patch
|
||
now at: test.patch
|
||
applying test1b.patch
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
% qpush --move
|
||
popping test2.patch
|
||
popping test1b.patch
|
||
popping test.patch
|
||
patch queue now empty
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
applying test1b.patch
|
||
now at: test1b.patch
|
||
applying test.patch
|
||
now at: test.patch
|
||
0 A test2.patch
|
||
1 A test1b.patch
|
||
2 A test.patch
|
||
popping test.patch
|
||
popping test1b.patch
|
||
popping test2.patch
|
||
patch queue now empty
|
||
applying test.patch
|
||
now at: test.patch
|
||
applying test1b.patch
|
||
now at: test1b.patch
|
||
abort: patch bogus not in series
|
||
abort: cannot push to a previous patch: test.patch
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
% pop, qapplied, qunapplied
|
||
0 A test.patch
|
||
1 A test1b.patch
|
||
2 A test2.patch
|
||
% qapplied -1 test.patch
|
||
only one patch applied
|
||
% qapplied -1 test1b.patch
|
||
test.patch
|
||
% qapplied -1 test2.patch
|
||
test1b.patch
|
||
% qapplied -1
|
||
test1b.patch
|
||
% qapplied
|
||
test.patch
|
||
test1b.patch
|
||
test2.patch
|
||
% qapplied test1b.patch
|
||
test.patch
|
||
test1b.patch
|
||
% qunapplied -1
|
||
all patches applied
|
||
% qunapplied
|
||
% popping
|
||
popping test2.patch
|
||
now at: test1b.patch
|
||
% qunapplied -1
|
||
test2.patch
|
||
% qunapplied
|
||
test2.patch
|
||
% qunapplied test2.patch
|
||
% qunapplied -1 test2.patch
|
||
all patches applied
|
||
% popping -a
|
||
popping test1b.patch
|
||
popping test.patch
|
||
patch queue now empty
|
||
% qapplied
|
||
% qapplied -1
|
||
no patches applied
|
||
applying test.patch
|
||
now at: test.patch
|
||
% push should succeed
|
||
popping test.patch
|
||
patch queue now empty
|
||
pushing to ../../k
|
||
searching for changes
|
||
adding changesets
|
||
adding manifests
|
||
adding file changes
|
||
added 1 changesets with 1 changes to 1 files
|
||
% qpush/qpop error codes
|
||
applying test.patch
|
||
applying test1b.patch
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
% pops all patches and succeeds
|
||
popping test2.patch
|
||
popping test1b.patch
|
||
popping test.patch
|
||
patch queue now empty
|
||
qpop -a succeeds
|
||
% does nothing and succeeds
|
||
no patches applied
|
||
qpop -a succeeds
|
||
% fails - nothing else to pop
|
||
no patches applied
|
||
qpop fails
|
||
% pushes a patch and succeeds
|
||
applying test.patch
|
||
now at: test.patch
|
||
qpush succeeds
|
||
% pops a patch and succeeds
|
||
popping test.patch
|
||
patch queue now empty
|
||
qpop succeeds
|
||
% pushes up to test1b.patch and succeeds
|
||
applying test.patch
|
||
applying test1b.patch
|
||
now at: test1b.patch
|
||
qpush test1b.patch succeeds
|
||
% does nothing and succeeds
|
||
qpush: test1b.patch is already at the top
|
||
qpush test1b.patch succeeds
|
||
% does nothing and succeeds
|
||
qpop: test1b.patch is already at the top
|
||
qpop test1b.patch succeeds
|
||
% fails - can't push to this patch
|
||
abort: cannot push to a previous patch: test.patch
|
||
qpush test.patch fails
|
||
% fails - can't pop to this patch
|
||
abort: patch test2.patch is not applied
|
||
qpop test2.patch fails
|
||
% pops up to test.patch and succeeds
|
||
popping test1b.patch
|
||
now at: test.patch
|
||
qpop test.patch succeeds
|
||
% pushes all patches and succeeds
|
||
applying test1b.patch
|
||
applying test2.patch
|
||
now at: test2.patch
|
||
qpush -a succeeds
|
||
% does nothing and succeeds
|
||
all patches are currently applied
|
||
qpush -a succeeds
|
||
% fails - nothing else to push
|
||
patch series already fully applied
|
||
qpush fails
|
||
% does nothing and succeeds
|
||
qpush: test2.patch is already at the top
|
||
qpush test2.patch succeeds
|
||
% strip
|
||
adding x
|
||
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||
saved backup bundle to
|
||
adding changesets
|
||
adding manifests
|
||
adding file changes
|
||
added 1 changesets with 1 changes to 1 files
|
||
(run 'hg update' to get a working copy)
|
||
% strip with local changes, should complain
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
abort: local changes found
|
||
% --force strip with local changes
|
||
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||
saved backup bundle to
|
||
% cd b; hg qrefresh
|
||
adding a
|
||
foo
|
||
|
||
diff -r cb9a9f314b8b a
|
||
--- a/a
|
||
+++ b/a
|
||
@@ -1,1 +1,2 @@
|
||
a
|
||
+a
|
||
diff -r cb9a9f314b8b b/f
|
||
--- /dev/null
|
||
+++ b/b/f
|
||
@@ -0,0 +1,1 @@
|
||
+f
|
||
% hg qrefresh .
|
||
foo
|
||
|
||
diff -r cb9a9f314b8b b/f
|
||
--- /dev/null
|
||
+++ b/b/f
|
||
@@ -0,0 +1,1 @@
|
||
+f
|
||
M a
|
||
% qpush failure
|
||
popping bar
|
||
popping foo
|
||
patch queue now empty
|
||
applying foo
|
||
applying bar
|
||
file foo already exists
|
||
1 out of 1 hunks FAILED -- saving rejects to file foo.rej
|
||
patch failed, unable to continue (try -v)
|
||
patch failed, rejects left in working dir
|
||
errors during apply, please fix and refresh bar
|
||
? foo
|
||
? foo.rej
|
||
% mq tags
|
||
0 qparent
|
||
1 foo qbase
|
||
2 bar qtip tip
|
||
% bad node in status
|
||
popping bar
|
||
now at: foo
|
||
changeset: 0:cb9a9f314b8b
|
||
tag: tip
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: a
|
||
|
||
default 0:cb9a9f314b8b
|
||
no patches applied
|
||
new file
|
||
|
||
diff --git a/new b/new
|
||
new file mode 100755
|
||
--- /dev/null
|
||
+++ b/new
|
||
@@ -0,0 +1,1 @@
|
||
+foo
|
||
copy file
|
||
|
||
diff --git a/new b/copy
|
||
copy from new
|
||
copy to copy
|
||
popping copy
|
||
now at: new
|
||
applying copy
|
||
now at: copy
|
||
diff --git a/new b/copy
|
||
copy from new
|
||
copy to copy
|
||
diff --git a/new b/copy
|
||
copy from new
|
||
copy to copy
|
||
% test file addition in slow path
|
||
1 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
||
created new head
|
||
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||
diff --git a/bar b/bar
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/bar
|
||
@@ -0,0 +1,1 @@
|
||
+bar
|
||
diff --git a/foo b/baz
|
||
rename from foo
|
||
rename to baz
|
||
2 baz (foo)
|
||
diff --git a/bar b/bar
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/bar
|
||
@@ -0,0 +1,1 @@
|
||
+bar
|
||
diff --git a/foo b/baz
|
||
rename from foo
|
||
rename to baz
|
||
2 baz (foo)
|
||
diff --git a/bar b/bar
|
||
diff --git a/foo b/baz
|
||
% test file move chains in the slow path
|
||
1 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
||
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||
diff --git a/foo b/bleh
|
||
rename from foo
|
||
rename to bleh
|
||
diff --git a/quux b/quux
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/quux
|
||
@@ -0,0 +1,1 @@
|
||
+bar
|
||
3 bleh (foo)
|
||
diff --git a/foo b/barney
|
||
rename from foo
|
||
rename to barney
|
||
diff --git a/fred b/fred
|
||
new file mode 100644
|
||
--- /dev/null
|
||
+++ b/fred
|
||
@@ -0,0 +1,1 @@
|
||
+bar
|
||
3 barney (foo)
|
||
% refresh omitting an added file
|
||
C newfile
|
||
A newfile
|
||
popping baz
|
||
now at: bar
|
||
% create a git patch
|
||
diff --git a/alexander b/alexander
|
||
% create a git binary patch
|
||
8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
|
||
diff --git a/bucephalus b/bucephalus
|
||
% check binary patches can be popped and pushed
|
||
popping addbucephalus
|
||
now at: addalexander
|
||
applying addbucephalus
|
||
now at: addbucephalus
|
||
8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
|
||
% strip again
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
created new head
|
||
merging foo
|
||
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
|
||
(branch merge, don't forget to commit)
|
||
changeset: 3:99615015637b
|
||
tag: tip
|
||
parent: 2:20cbbe65cff7
|
||
parent: 1:d2871fc282d4
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: merge
|
||
|
||
changeset: 2:20cbbe65cff7
|
||
parent: 0:53245c60e682
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: change foo 2
|
||
|
||
changeset: 1:d2871fc282d4
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: change foo 1
|
||
|
||
changeset: 0:53245c60e682
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: add foo
|
||
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
saved backup bundle to
|
||
changeset: 1:20cbbe65cff7
|
||
tag: tip
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: change foo 2
|
||
|
||
changeset: 0:53245c60e682
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: add foo
|
||
|
||
% qclone
|
||
abort: versioned patch repository not found (see init --mq)
|
||
adding .hg/patches/patch1
|
||
main repo:
|
||
rev 1: change foo
|
||
rev 0: add foo
|
||
patch repo:
|
||
rev 0: checkpoint
|
||
updating to branch default
|
||
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
main repo:
|
||
rev 0: add foo
|
||
patch repo:
|
||
rev 0: checkpoint
|
||
popping patch1
|
||
patch queue now empty
|
||
main repo:
|
||
rev 0: add foo
|
||
patch repo:
|
||
rev 0: checkpoint
|
||
updating to branch default
|
||
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
main repo:
|
||
rev 0: add foo
|
||
patch repo:
|
||
rev 0: checkpoint
|
||
% test applying on an empty file (issue 1033)
|
||
adding a
|
||
popping changea
|
||
patch queue now empty
|
||
applying changea
|
||
now at: changea
|
||
% test qpush with --force, issue1087
|
||
adding bye.txt
|
||
adding hello.txt
|
||
popping empty
|
||
patch queue now empty
|
||
% qpush should fail, local changes
|
||
abort: local changes found, refresh first
|
||
% apply force, should not discard changes with empty patch
|
||
applying empty
|
||
patch empty is empty
|
||
now at: empty
|
||
diff -r bf5fc3f07a0a hello.txt
|
||
--- a/hello.txt
|
||
+++ b/hello.txt
|
||
@@ -1,1 +1,2 @@
|
||
hello
|
||
+world
|
||
diff -r 9ecee4f634e3 hello.txt
|
||
--- a/hello.txt
|
||
+++ b/hello.txt
|
||
@@ -1,1 +1,2 @@
|
||
hello
|
||
+world
|
||
changeset: 1:bf5fc3f07a0a
|
||
tag: empty
|
||
tag: qbase
|
||
tag: qtip
|
||
tag: tip
|
||
user: test
|
||
date: Thu Jan 01 00:00:00 1970 +0000
|
||
summary: imported patch empty
|
||
|
||
|
||
popping empty
|
||
patch queue now empty
|
||
% qpush should fail, local changes
|
||
abort: local changes found, refresh first
|
||
% apply force, should discard changes in hello, but not bye
|
||
applying empty
|
||
now at: empty
|
||
M bye.txt
|
||
diff -r ba252371dbc1 bye.txt
|
||
--- a/bye.txt
|
||
+++ b/bye.txt
|
||
@@ -1,1 +1,2 @@
|
||
bye
|
||
+universe
|
||
diff -r 9ecee4f634e3 bye.txt
|
||
--- a/bye.txt
|
||
+++ b/bye.txt
|
||
@@ -1,1 +1,2 @@
|
||
bye
|
||
+universe
|
||
diff -r 9ecee4f634e3 hello.txt
|
||
--- a/hello.txt
|
||
+++ b/hello.txt
|
||
@@ -1,1 +1,3 @@
|
||
hello
|
||
+world
|
||
+universe
|
||
% test popping revisions not in working dir ancestry
|
||
0 A empty
|
||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||
popping empty
|
||
patch queue now empty
|
||
% test popping must remove files added in subdirectories first
|
||
popping rename-dir
|
||
patch queue now empty
|