2017-06-17 00:11:43 +03:00
|
|
|
$ cat >> $HGRCPATH <<EOF
|
|
|
|
> [defaults]
|
|
|
|
> fold=--date "0 0"
|
|
|
|
> metaedit=--date "0 0"
|
|
|
|
> [web]
|
|
|
|
> push_ssl = false
|
|
|
|
> allow_push = *
|
|
|
|
> [phases]
|
|
|
|
> publish = False
|
|
|
|
> [alias]
|
|
|
|
> qlog = log --template='{rev} - {node|short} {desc} ({phase})\n'
|
|
|
|
> [diff]
|
|
|
|
> git = 1
|
|
|
|
> unified = 0
|
|
|
|
> [extensions]
|
2018-10-11 16:55:19 +03:00
|
|
|
> amend=
|
2017-06-17 00:11:43 +03:00
|
|
|
> rebase=
|
|
|
|
> [experimental]
|
|
|
|
> evolution=createmarkers, allowunstable
|
|
|
|
> EOF
|
|
|
|
$ mkcommit() {
|
|
|
|
> echo "$1" > "$1"
|
|
|
|
> hg add "$1"
|
|
|
|
> hg ci -m "$1"
|
|
|
|
> }
|
|
|
|
|
|
|
|
$ mkstack() {
|
|
|
|
> # Creates a stack of commit based on $1 with messages from $2, $3 ..
|
|
|
|
> hg update $1 -C
|
|
|
|
> shift
|
|
|
|
> mkcommits $*
|
|
|
|
> }
|
|
|
|
|
|
|
|
$ glog() {
|
|
|
|
> hg log -G -T '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
|
|
|
|
> }
|
|
|
|
|
|
|
|
$ shaof() {
|
|
|
|
> hg log -T {node} -r "first(desc($1))"
|
|
|
|
> }
|
|
|
|
|
|
|
|
$ mkcommits() {
|
|
|
|
> for i in $@; do mkcommit $i ; done
|
|
|
|
> }
|
|
|
|
|
|
|
|
##########################
|
|
|
|
importing Parren test
|
|
|
|
##########################
|
|
|
|
|
|
|
|
$ cat << EOF >> $HGRCPATH
|
|
|
|
> [ui]
|
|
|
|
> logtemplate = "{rev}\t{bookmarks}: {desc|firstline} - {author|user}\n"
|
|
|
|
> EOF
|
|
|
|
|
|
|
|
HG METAEDIT
|
|
|
|
===============================
|
|
|
|
|
|
|
|
Setup the Base Repo
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
We start with a plain base repo::
|
|
|
|
|
|
|
|
$ hg init $TESTTMP/metaedit; cd $TESTTMP/metaedit
|
|
|
|
$ mkcommit "ROOT"
|
|
|
|
$ hg phase --public "desc(ROOT)"
|
|
|
|
$ mkcommit "A"
|
|
|
|
$ mkcommit "B"
|
|
|
|
$ hg up "desc(A)"
|
|
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
|
|
$ mkcommit "C"
|
|
|
|
$ mkcommit "D"
|
|
|
|
$ echo "D'" > D
|
|
|
|
$ hg commit --amend -m "D2"
|
|
|
|
$ hg up "desc(C)"
|
|
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
|
|
$ mkcommit "E"
|
|
|
|
$ mkcommit "F"
|
|
|
|
|
|
|
|
Test
|
|
|
|
----
|
|
|
|
|
|
|
|
$ hg log -G
|
2017-09-08 19:58:14 +03:00
|
|
|
@ 7 : F - test
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
2017-09-08 19:58:14 +03:00
|
|
|
o 6 : E - test
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
2017-09-08 19:58:14 +03:00
|
|
|
| o 5 : D2 - test
|
2017-06-17 00:11:43 +03:00
|
|
|
|/
|
|
|
|
o 3 : C - test
|
|
|
|
|
|
|
|
|
| o 2 : B - test
|
|
|
|
|/
|
|
|
|
o 1 : A - test
|
|
|
|
|
|
|
|
|
o 0 : ROOT - test
|
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
2017-06-17 00:11:43 +03:00
|
|
|
$ hg update --clean .
|
|
|
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
$ hg metaedit -r 0
|
|
|
|
abort: cannot edit commit information for public revisions
|
|
|
|
[255]
|
|
|
|
$ hg metaedit --fold
|
|
|
|
abort: revisions must be specified with --fold
|
|
|
|
[255]
|
|
|
|
$ hg metaedit -r 0 --fold
|
|
|
|
abort: cannot fold public revisions
|
|
|
|
[255]
|
|
|
|
$ hg metaedit 'desc(C) + desc(F)' --fold
|
|
|
|
abort: cannot fold non-linear revisions (multiple roots given)
|
|
|
|
[255]
|
|
|
|
$ hg metaedit "desc(C)::desc(D2) + desc(E)" --fold
|
|
|
|
abort: cannot fold non-linear revisions (multiple heads given)
|
|
|
|
[255]
|
|
|
|
|
2018-06-12 17:51:22 +03:00
|
|
|
$ hg metaedit --user foobar -T "{nodechanges|json}\n"
|
|
|
|
{"587528abfffe33d49f94f9d6223dbbd58d6197c6": ["212b2a2b87cdbae992f001e9baba64db389fbce7"]}
|
2017-06-17 00:11:43 +03:00
|
|
|
$ hg log --template '{rev}: {author}\n' -r 'desc(F):' --hidden
|
|
|
|
7: test
|
2017-09-08 19:58:14 +03:00
|
|
|
8: foobar
|
2017-06-17 00:11:43 +03:00
|
|
|
$ hg log --template '{rev}: {author}\n' -r .
|
2017-09-08 19:58:14 +03:00
|
|
|
8: foobar
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
|
|
$ HGEDITOR=cat hg metaedit '.^::.' --fold
|
|
|
|
HG: This is a fold of 2 changesets.
|
2017-09-08 19:58:14 +03:00
|
|
|
HG: Commit message of changeset 6.
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
|
|
E
|
|
|
|
|
2017-09-08 19:58:14 +03:00
|
|
|
HG: Commit message of changeset 8.
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
|
|
F
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HG: Enter commit message. Lines beginning with 'HG:' are removed.
|
|
|
|
HG: Leave message empty to abort commit.
|
|
|
|
HG: --
|
|
|
|
HG: user: test
|
|
|
|
HG: branch 'default'
|
|
|
|
HG: added E
|
|
|
|
HG: added F
|
|
|
|
2 changesets folded
|
|
|
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-17 00:11:43 +03:00
|
|
|
$ glog -r .
|
2017-09-08 19:58:14 +03:00
|
|
|
@ 9:a08d35fd7d9d@default(draft) E
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
|
|
|
~
|
|
|
|
|
|
|
|
no new commit is created here because the date is the same
|
|
|
|
$ HGEDITOR=cat hg metaedit
|
2017-06-17 00:12:32 +03:00
|
|
|
HG: Commit message of changeset a08d35fd7d9d
|
2017-06-17 00:11:43 +03:00
|
|
|
E
|
|
|
|
|
|
|
|
|
|
|
|
F
|
|
|
|
|
|
|
|
|
|
|
|
HG: Enter commit message. Lines beginning with 'HG:' are removed.
|
|
|
|
HG: Leave message empty to abort commit.
|
|
|
|
HG: --
|
|
|
|
HG: user: test
|
|
|
|
HG: branch 'default'
|
|
|
|
HG: added E
|
|
|
|
HG: added F
|
|
|
|
nothing changed
|
|
|
|
[1]
|
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-17 00:11:43 +03:00
|
|
|
$ glog -r '.^::.'
|
2017-09-08 19:58:14 +03:00
|
|
|
@ 9:a08d35fd7d9d@default(draft) E
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
|
|
|
o 3:3260958f1169@default(draft) C
|
|
|
|
|
|
|
|
|
~
|
|
|
|
|
|
|
|
TODO: don't create a new commit in this case, we should take the date of the
|
|
|
|
old commit (we add a default date with a value to show that metaedit is taking
|
|
|
|
the current date to generate the hash, this way we still have a stable hash
|
|
|
|
but highlight the bug)
|
|
|
|
$ hg metaedit --config defaults.metaedit= --config devel.default-date="42 0"
|
|
|
|
$ hg log -r '.^::.' --template '{rev}: {desc|firstline}\n'
|
|
|
|
3: C
|
2017-09-08 19:58:14 +03:00
|
|
|
10: E
|
2017-06-17 00:11:43 +03:00
|
|
|
|
|
|
|
$ hg up '.^'
|
|
|
|
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
|
|
|
|
$ hg metaedit --user foobar2 tip
|
|
|
|
$ hg log --template '{rev}: {author}\n' -r "user(foobar):" --hidden
|
2017-09-08 19:58:14 +03:00
|
|
|
8: foobar
|
|
|
|
9: test
|
2017-06-17 00:11:43 +03:00
|
|
|
10: test
|
2017-09-08 19:58:14 +03:00
|
|
|
11: foobar2
|
2017-06-17 00:11:43 +03:00
|
|
|
$ hg diff -r "10" -r "11" --hidden
|
|
|
|
|
|
|
|
'fold' one commit
|
|
|
|
$ hg metaedit "desc(D2)" --fold --user foobar3
|
|
|
|
1 changesets folded
|
|
|
|
$ hg log -r "tip" --template '{rev}: {author}\n'
|
2017-09-08 19:58:14 +03:00
|
|
|
12: foobar3
|
2017-06-17 00:12:32 +03:00
|
|
|
|
|
|
|
metaedit a commit in the middle of the stack:
|
|
|
|
|
|
|
|
$ cd $TESTTMP
|
|
|
|
$ hg init metaedit2
|
|
|
|
$ cd metaedit2
|
|
|
|
$ hg debugbuilddag '+5'
|
|
|
|
$ hg update tip
|
|
|
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 4:bebd167eb94d@default(draft) r4
|
|
|
|
|
|
|
|
|
o 3:2dc09a01254d@default(draft) r3
|
|
|
|
|
|
|
|
|
o 2:01241442b3c2@default(draft) r2
|
|
|
|
|
|
|
|
|
o 1:66f7d451a68b@default(draft) r1
|
|
|
|
|
|
|
|
|
o 0:1ea73414a91b@default(draft) r0
|
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
2017-06-17 00:12:32 +03:00
|
|
|
$ hg metaedit -m "metaedit" -r 2
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 7:8c1f124031e7@default(draft) r4
|
|
|
|
|
|
|
|
|
o 6:af1447d6a312@default(draft) r3
|
|
|
|
|
|
|
|
|
o 5:1aed0f31debd@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 1:66f7d451a68b@default(draft) r1
|
|
|
|
|
|
|
|
|
o 0:1ea73414a91b@default(draft) r0
|
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
2017-06-17 00:12:32 +03:00
|
|
|
$ hg metaedit -m "metaedit" -r 1aed0f31debd
|
|
|
|
nothing changed
|
|
|
|
[1]
|
2017-06-19 18:03:17 +03:00
|
|
|
|
|
|
|
metaedit more than one commit at once without --fold
|
|
|
|
$ hg metaedit -m "metaedit" -r 5::
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 9:972f190d63f3@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 8:a1c80e4c2636@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 5:1aed0f31debd@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 1:66f7d451a68b@default(draft) r1
|
|
|
|
|
|
|
|
|
o 0:1ea73414a91b@default(draft) r0
|
|
|
|
|
2017-09-21 15:33:54 +03:00
|
|
|
|
|
|
|
make the top commit non-empty
|
|
|
|
$ echo xx > xx
|
|
|
|
$ hg add xx
|
|
|
|
$ hg amend
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 10:90ef4d40a825@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 8:a1c80e4c2636@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 5:1aed0f31debd@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 1:66f7d451a68b@default(draft) r1
|
|
|
|
|
|
|
|
|
o 0:1ea73414a91b@default(draft) r0
|
|
|
|
|
|
|
|
|
|
|
|
test histedit compat
|
|
|
|
|
|
|
|
$ echo '[extensions]' >> $HGRCPATH
|
2018-01-09 14:06:09 +03:00
|
|
|
$ echo "fbhistedit=" >> $HGRCPATH
|
2017-09-21 15:33:54 +03:00
|
|
|
$ echo "histedit=" >> $HGRCPATH
|
|
|
|
|
|
|
|
$ hg export -r .
|
|
|
|
# HG changeset patch
|
|
|
|
# User debugbuilddag
|
|
|
|
# Date 0 0
|
|
|
|
# Thu Jan 01 00:00:00 1970 +0000
|
|
|
|
# Node ID 90ef4d40a82572a220d8329eefb1d96a1fac3597
|
|
|
|
# Parent a1c80e4c26360f913ae3bdc5c70d6f29d465bfb0
|
|
|
|
metaedit
|
|
|
|
|
|
|
|
diff --git a/xx b/xx
|
|
|
|
new file mode 100644
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/xx
|
|
|
|
@@ -0,0 +1,1 @@
|
|
|
|
+xx
|
2018-06-26 16:09:38 +03:00
|
|
|
|
|
|
|
|
2017-09-21 15:33:54 +03:00
|
|
|
$ hg histedit ".^^" --commands - <<EOF
|
|
|
|
> pick 1aed0f31debd
|
|
|
|
> x hg metaedit -m "histedit test"
|
|
|
|
> x hg commit --amend -m 'message from exec'
|
|
|
|
> pick a1c80e4c2636
|
|
|
|
> pick 90ef4d40a825
|
|
|
|
> EOF
|
|
|
|
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
|
|
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
a1c80e4c2636: skipping changeset (no changes)
|
|
|
|
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 13:942d79297adf@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 12:b5e5d076151f@default(draft) message from exec
|
|
|
|
|
|
|
|
|
o 1:66f7d451a68b@default(draft) r1
|
|
|
|
|
|
|
|
|
o 0:1ea73414a91b@default(draft) r0
|
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
|
|
|
metaedit noncontinuous set of commits in the stack:
|
|
|
|
|
|
|
|
$ cd $TESTTMP
|
|
|
|
$ hg init metaeditnoncontinues
|
|
|
|
$ cd metaeditnoncontinues
|
|
|
|
$ hg debugbuilddag '+5'
|
|
|
|
$ hg update tip
|
|
|
|
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
|
|
|
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 4:bebd167eb94d@default(draft) r4
|
|
|
|
|
|
|
|
|
o 3:2dc09a01254d@default(draft) r3
|
|
|
|
|
|
|
|
|
o 2:01241442b3c2@default(draft) r2
|
|
|
|
|
|
|
|
|
o 1:66f7d451a68b@default(draft) r1
|
|
|
|
|
|
|
|
|
o 0:1ea73414a91b@default(draft) r0
|
|
|
|
|
|
|
|
|
|
|
|
$ hg metaedit -m "metaedit" 0 2 4
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 9:2b037168acb5@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 8:1a9c34db0e76@default(draft) r3
|
|
|
|
|
|
|
|
|
o 7:4d7251aa2bec@default(draft) metaedit
|
|
|
|
|
|
|
|
|
o 6:16ad2130f633@default(draft) r1
|
|
|
|
|
|
|
|
|
o 5:e37e0d87697f@default(draft) metaedit
|
|
|
|
|
|
|
|
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
Test copying obsmarkers
|
2018-02-23 22:49:37 +03:00
|
|
|
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
$ hg init $TESTTMP/autorel
|
|
|
|
$ cd $TESTTMP/autorel
|
|
|
|
$ hg debugdrawdag<<'EOS'
|
|
|
|
> D
|
|
|
|
> |
|
|
|
|
> C C1 # amend: C -> C1
|
|
|
|
> |/
|
|
|
|
> B
|
|
|
|
> |
|
|
|
|
> A
|
|
|
|
> EOS
|
|
|
|
$ hg metaedit -r B -m B1
|
|
|
|
$ rm .hg/localtags
|
2018-02-23 22:49:37 +03:00
|
|
|
$ glog -r 'all()'
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
o 8:52bc6136aa97@default(draft) D
|
2018-02-23 22:49:37 +03:00
|
|
|
|
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
| o 7:1be7301b35ae@default(draft) C1
|
2018-02-23 22:49:37 +03:00
|
|
|
| |
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
x | 6:19437442f9e4@default(draft) C
|
2018-02-23 22:49:37 +03:00
|
|
|
|/
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
o 5:888bb4818188@default(draft) B1
|
2018-02-23 22:49:37 +03:00
|
|
|
|
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
o 0:426bada5c675@default(draft) A
|
2018-02-23 22:49:37 +03:00
|
|
|
|
2018-06-26 16:09:38 +03:00
|
|
|
|
obsolete: copy obsmarkers from old commits automatically
Summary:
Rewriting a set of commits where there are replacement relationship among the
commits do not have an optimal UX today. For example, `rebase -s A -d Z` or
`metaedit A` in the below graph. B1, B2, C will all be replaced. But the new B1
and B2 replacement won't have the B1 -> B2 relationship, and the "new B1"
appears to be revived.
```
o C
|
x B1 (amended as B2)
|
| o B2
|/
o A o Z
```
One solution is to avoid rebasing `obsolete()::`, as implemented in D7067121
for metaedit. That would result in
```
o C
|
x B1 (amended as B2) o new B2
| |
x A o new A
```
The stack of A, B1, C is forced to break into two parts. This is fine for
power users. But n00b users would wonder why C is left behind. Per discussion
with simpkins at an internal post about the metaedit case, we think a more
linear history is more user-friendly. That is:
```
o new C
|
x new B1 (amended as *new* B2)
|
| o new B2
|/
o new A
```
The stack stays in a same shape.
This diff implements the "copying obsmarkers" behavior at the "createmarkers"
level so everything using that API would get the feature for free, including
metaedit and rebase.
D7067121 is reverted since the new UX is preferred. The test added is for
`metaedit` command, changes to rebase will be added in a later patch.
Differential Revision: D7121487
fbshipit-source-id: fd3c8a96ab434b131fb86d9882ccbdff8f63f05e
2018-03-07 23:12:58 +03:00
|
|
|
$ hg log -r 'successors(19437442f9e4)-19437442f9e4' -T '{node}\n'
|
|
|
|
1be7301b35ae8ac3543a07a5d0ce5ca615be709f
|
|
|
|
|
|
|
|
$ hg log -r 'precursors(19437442f9e4)-19437442f9e4' -T '{desc} {node}\n' --hidden
|
|
|
|
C 26805aba1e600a82e93661149f2313866a221a7b
|
2018-07-27 12:40:24 +03:00
|
|
|
|
|
|
|
Test empty commit
|
|
|
|
$ hg co -q 1be7301b35ae
|
|
|
|
$ hg commit --config ui.allowemptycommit=true -m empty
|
context: fix sanity check in metadataonlyctx
Summary:
Previously, this check was subtly wrong, causing it to fail for empty
commits (which have the same manifest as their parents). Update the check to
ensure the actual thing we want to ensure -- that the caller isn't creating
incorrect commits.
The failure would happen in this case:
```
B empty commit (manifest Am)
|
A draft commit (manifest Am)
/
M master (manifest Mm)
```
When metaediting `A`, `metaedit` would then "rebase" `B` onto `A'` to create
`B'`, with both `A'` and `B'` reusing `Am` as their manifest. The old check
would fail here because the parent of `Am` is `Mm`, but the manifest of `A'`
(the parent of `B'`) is `Am`, so when checking the manifest of the parent
against the parent of the manifest, we would find that `Am != Mm` and fail.
The actual check we wanted was that the manifest of the parent of `B'` is the
same as the manifest of the parent of `B` -- which the old check approximated
as long as no manifests were reused in the stack. As this is not sufficient
with empty commits, we instead want to check that the manifest of the old
parent matches the manifest of the new parent, which we now do.
By avoid reading `manifest.parents`, this would also avoid some lazy tree
fetches, therefore speed up metaedit in certain cases.
Reviewed By: quark-zju
Differential Revision: D9013995
fbshipit-source-id: 4d0b05fc9bb81d115cd87ba2bf98aa253ae6f88b
2018-07-27 12:40:25 +03:00
|
|
|
$ hg metaedit -r ".^" -m "parent of empty commit"
|
|
|
|
$ glog -r 'all()'
|
|
|
|
@ 11:e582f22eefc0@default(draft) empty
|
|
|
|
|
|
|
|
|
o 10:539393debc47@default(draft) parent of empty commit
|
|
|
|
|
|
|
|
|
| o 8:52bc6136aa97@default(draft) D
|
|
|
|
| |
|
|
|
|
| x 6:19437442f9e4@default(draft) C
|
|
|
|
|/
|
|
|
|
o 5:888bb4818188@default(draft) B1
|
|
|
|
|
|
|
|
|
o 0:426bada5c675@default(draft) A
|
|
|
|
|