D4353: bookflow: support shelve and enforce working directory pointing to the active bookmark
idlsoft (Sandu Turcan)
phabricator at mercurial-scm.org
Wed Aug 22 14:02:02 UTC 2018
idlsoft created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D4353
AFFECTED FILES
hgext/bookflow.py
tests/test-bookflow.t
CHANGE DETAILS
diff --git a/tests/test-bookflow.t b/tests/test-bookflow.t
--- a/tests/test-bookflow.t
+++ b/tests/test-bookflow.t
@@ -1,6 +1,5 @@
initialize
- $ alias hgg="hg --config extensions.bookflow=`dirname $TESTDIR`/hgext/bookflow.py"
- $ make_changes() { d=`pwd`; [ ! -z $1 ] && cd $1; echo "test $(basename `pwd`)" >> test; hgg commit -Am"${2:-test}"; r=$?; cd $d; return $r; }
+ $ make_changes() { d=`pwd`; [ ! -z $1 ] && cd $1; echo "test $(basename `pwd`)" >> test; hg commit -Am"${2:-test}"; r=$?; cd $d; return $r; }
$ assert_clean() { ls -1 $1 | grep -v "test$" | cat;}
$ ls -1a
.
@@ -17,29 +16,31 @@
$ hg clone ../a .
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hgg branch X
- abort: Branching should be done using bookmarks:
+ $ echo "[extensions]" >> .hg/hgrc
+ $ echo "bookflow=" >> .hg/hgrc
+ $ hg branch X
+ abort: branching should be done using bookmarks:
hg bookmark X
[255]
- $ hgg bookmark X
- $ hgg bookmarks
+ $ hg bookmark X
+ $ hg bookmarks
* X 0:* (glob)
$ make_changes
- $ hgg push ../a > /dev/null
+ $ hg push ../a > /dev/null
$ hg bookmarks
\* X 1:* (glob)
change a
$ cd ../a
- $ hgg up
+ $ hg up
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo 'test' >> test; hg commit -Am'test'
pull in b
$ cd ../b
- $ hgg pull -u
+ $ hg pull -u
pulling from $TESTTMP/a
searching for changes
adding changesets
@@ -54,62 +55,62 @@
X 1:* (glob)
check protection of @ bookmark
- $ hgg bookmark @
- $ hgg bookmarks
+ $ hg bookmark @
+ $ hg bookmarks
\* @ 2:* (glob)
X 1:* (glob)
$ make_changes
- abort: Can't commit, bookmark @ is protected
+ abort: can't commit, bookmark @ is protected
[255]
$ assert_clean
- $ hgg bookmarks
+ $ hg bookmarks
\* @ 2:* (glob)
X 1:* (glob)
- $ hgg --config bookflow.protect= commit -Am"Updated test"
+ $ hg --config bookflow.protect= commit -Am"Updated test"
- $ hgg bookmarks
+ $ hg bookmarks
\* @ 3:* (glob)
X 1:* (glob)
check requirement for an active bookmark
- $ hgg bookmark -i
- $ hgg bookmarks
+ $ hg bookmark -i
+ $ hg bookmarks
@ 3:* (glob)
X 1:* (glob)
$ make_changes
- abort: Can't commit without an active bookmark
+ abort: can't commit without an active bookmark
[255]
- $ hgg revert test
+ $ hg revert test
$ rm test.orig
$ assert_clean
make the bookmark move by updating it on a, and then pulling
# add a commit to a
$ cd ../a
$ hg bookmark X
- $ hgg bookmarks
+ $ hg bookmarks
\* X 2:* (glob)
$ make_changes
- $ hgg bookmarks
+ $ hg bookmarks
* X 3:81af7977fdb9
# go back to b, and check out X
$ cd ../b
- $ hgg up X
+ $ hg up X
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(activating bookmark X)
- $ hgg bookmarks
+ $ hg bookmarks
@ 3:* (glob)
\* X 1:* (glob)
# pull, this should move the bookmark forward, because it was changed remotely
- $ hgg pull -u | grep "updating to active bookmark X"
+ $ hg pull -u | grep "updating to active bookmark X"
updating to active bookmark X
- $ hgg bookmarks
+ $ hg bookmarks
@ 3:* (glob)
* X 4:81af7977fdb9
@@ -120,69 +121,160 @@
$ make_changes ../b
$ assert_clean ../a
$ assert_clean ../b
- $ hgg --cwd ../a bookmarks
+ $ hg --cwd ../a bookmarks
* X 4:238292f60a57
- $ hgg --cwd ../b bookmarks
+ $ hg --cwd ../b bookmarks
@ 3:* (glob)
* X 5:096f7e86892d
$ cd ../b
$ # make sure we can't push after bookmarks diverged
- $ hgg push -B X | grep abort
+ $ hg push -B X | grep abort
abort: push creates new remote head * with bookmark 'X'! (glob)
(pull and merge or see 'hg help push' for details about pushing new heads)
[1]
- $ hgg pull -u | grep divergent
+ $ hg pull -u | grep divergent
divergent bookmark X stored as X at default
1 other divergent bookmarks for "X"
- $ hgg bookmarks
+ $ hg bookmarks
@ 3:* (glob)
* X 5:096f7e86892d
X at default 6:238292f60a57
- $ hgg id -in
+ $ hg id -in
096f7e86892d 5
$ make_changes
$ assert_clean
- $ hgg bookmarks
+ $ hg bookmarks
@ 3:* (glob)
* X 7:227f941aeb07
X at default 6:238292f60a57
now merge with the remote bookmark
- $ hgg merge X at default --tool :local > /dev/null
+ $ hg merge X at default --tool :local > /dev/null
$ assert_clean
- $ hgg commit -m"Merged with X at default"
- $ hgg bookmarks
+ $ hg commit -m"Merged with X at default"
+ $ hg bookmarks
@ 3:* (glob)
* X 8:26fed9bb3219
- $ hgg push -B X | grep bookmark
+ $ hg push -B X | grep bookmark
pushing to $TESTTMP/a (?)
updating bookmark X
$ cd ../a
- $ hgg up > /dev/null
- $ hgg bookmarks
+ $ hg up > /dev/null
+ $ hg bookmarks
* X 7:26fed9bb3219
test hg pull when there is more than one descendant
$ cd ../a
- $ hgg bookmark Z
- $ hgg bookmark Y
+ $ hg bookmark Z
+ $ hg bookmark Y
$ make_changes . YY
- $ hgg up Z > /dev/null
+ $ hg up Z > /dev/null
$ make_changes . ZZ
created new head
- $ hgg bookmarks
+ $ hg bookmarks
X 7:26fed9bb3219
Y 8:131e663dbd2a
* Z 9:b74a4149df25
$ hg log -r 'p1(Y)' -r 'p1(Z)' -T '{rev}\n' # prove that Y and Z share the same parent
7
- $ hgg log -r 'Y%Z' -T '{rev}\n' # revs in Y but not in Z
+ $ hg log -r 'Y%Z' -T '{rev}\n' # revs in Y but not in Z
8
- $ hgg log -r 'Z%Y' -T '{rev}\n' # revs in Z but not in Y
+ $ hg log -r 'Z%Y' -T '{rev}\n' # revs in Z but not in Y
9
$ cd ../b
- $ hgg pull -u > /dev/null
- $ hgg id
+ $ hg pull -u > /dev/null
+ $ hg id
b74a4149df25 tip Z
- $ hgg bookmarks | grep \* # no active bookmark
+ $ hg bookmarks | grep \* # no active bookmark
[1]
+
+
+test shelving
+ $ cd ../a
+ $ echo anotherfile > anotherfile # this change should not conflict
+ $ hg add anotherfile
+ $ hg commit -m"Change in a"
+ $ cd ../b
+ $ hg up Z | grep Z
+ (activating bookmark Z)
+ $ hg book | grep \* # make sure active bookmark
+ \* Z 10:* (glob)
+ $ echo "test b" >> test
+ $ hg diff --stat
+ test | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ $ hg --config extensions.shelve= shelve
+ shelved as Z
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg pull -u > /dev/null
+ $ hg --trace --config extensions.shelve= unshelve
+ unshelving change 'Z'
+ rebasing shelved changes
+ $ hg diff --stat
+ test | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+
+make the bookmark move by updating it on a, and then pulling with a local change
+# add a commit to a
+ $ cd ../a
+ $ hg up -C X |fgrep "activating bookmark X"
+ (activating bookmark X)
+# go back to b, and check out X
+ $ cd ../b
+ $ hg up -C X |fgrep "activating bookmark X"
+ (activating bookmark X)
+# update and push from a
+ $ make_changes ../a > /dev/null
+ $ echo "more" >> test
+ $ hg pull -u 2>&1 | fgrep -v TESTTMP| fgrep -v "searching for changes" | fgrep -v adding
+ pulling from $TESTTMP/a
+ added 1 changesets with 0 changes to 0 files (+1 heads)
+ updating bookmark X
+ new changesets * (glob)
+ updating to active bookmark X
+ merging test
+ warning: conflicts while merging test! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges
+ $ hg update -C > /dev/null
+ $ rm test.orig
+
+make sure that commits aren't possible if working directory is not pointing to active bookmark
+ $ assert_clean ../a
+ $ assert_clean ../b
+ $ hg --cwd ../a id -i
+ 36a6e592ec06
+ $ hg --cwd ../a book | grep X
+ \* X \d+:36a6e592ec06 (re)
+ $ hg --cwd ../b id -i
+ 36a6e592ec06
+ $ hg --cwd ../b book | grep X
+ \* X \d+:36a6e592ec06 (re)
+ $ make_changes ../a
+ $ hg --cwd ../a book | grep X
+ \* X \d+:f73a71c992b8 (re)
+ $ cd ../b
+ $ hg pull 2>&1 | grep -v add|grep -v pulling|grep -v searching|grep -v changeset
+ updating bookmark X
+ (run 'hg update' to get a working copy)
+ working directory out of sync with active bookmark.
+ Run: hg up X
+ $ hg id -i # we're still on the old commit
+ 36a6e592ec06
+ $ hg book | grep X # while the bookmark moved
+ \* X \d+:f73a71c992b8 (re)
+ $ make_changes
+ abort: can't commit, working directory out of sync with active bookmark.
+ Run: hg up X
+ [255]
+ $ hg up -C -r . > /dev/null # cleanup local changes
+ $ assert_clean
+ $ hg id -i # we're still on the old commit
+ 36a6e592ec06
+ $ hg up X > /dev/null
+ $ hg id -i # now we're on X
+ f73a71c992b8
+ $ hg book | grep X
+ \* X \d+:f73a71c992b8 (re)
+
diff --git a/hgext/bookflow.py b/hgext/bookflow.py
--- a/hgext/bookflow.py
+++ b/hgext/bookflow.py
@@ -22,7 +22,7 @@
extensions
)
-MY_NAME = __name__[len('hgext_'):] if __name__.startswith('hgext_') else __name__
+MY_NAME = 'bookflow'
configtable = {}
configitem = registrar.configitem(configtable)
@@ -36,10 +36,13 @@
def commit_hook(ui, repo, **kwargs):
active = repo._bookmarks.active
- if not active and ui.configbool(MY_NAME, 'require_bookmark', True):
- raise error.Abort(_('Can\'t commit without an active bookmark'))
- elif active in ui.configlist(MY_NAME, 'protect'):
- raise error.Abort(_('Can\'t commit, bookmark {} is protected').format(active))
+ if active:
+ if active in ui.configlist(MY_NAME, 'protect'):
+ raise error.Abort(_('can\'t commit, bookmark {} is protected').format(active))
+ if not cwd_at_bookmark(repo, active):
+ raise error.Abort(_('can\'t commit, working directory out of sync with active bookmark.\nRun: hg up {}').format(active))
+ elif ui.configbool(MY_NAME, 'require_bookmark', True):
+ raise error.Abort(_('can\'t commit without an active bookmark'))
return 0
@@ -51,34 +54,43 @@
# called during update
return False
-
def bookmarks_addbookmarks(orig, repo, tr, names, rev=None, force=False, inactive=False):
if not rev:
marks = repo._bookmarks
for name in names:
if name in marks:
- raise error.Abort("Bookmark {} already exists, to move use the --rev option".format(name))
+ raise error.Abort(_("bookmark {} already exists, to move use the --rev option").format(name))
return orig(repo, tr, names, rev, force, inactive)
-
def commands_commit(orig, ui, repo, *args, **opts):
commit_hook(ui, repo)
return orig(ui, repo, *args, **opts)
+def commands_pull(orig, ui, repo, *args, **opts):
+ rc = orig(ui, repo, *args, **opts)
+ active = repo._bookmarks.active
+ if active and not cwd_at_bookmark(repo, active):
+ ui.warn(_("working directory out of sync with active bookmark.\nRun: hg up {}\n").format(active))
+ return rc
+
+def cwd_at_bookmark(repo, mark):
+ mark_id = repo._bookmarks[mark]
+ cur_id = repo.lookup('.')
+ return cur_id == mark_id
def commands_branch(orig, ui, repo, label=None, **opts):
- if label and not opts.get('clean') and not opts.get('rev'):
- raise error.Abort("Branching should be done using bookmarks:\nhg bookmark " + label)
+ if label and not opts.get(r'clean') and not opts.get(r'rev'):
+ raise error.Abort(_("branching should be done using bookmarks:\nhg bookmark {}").format(label))
return orig(ui, repo, label, **opts)
-
def reposetup(ui, repo):
extensions.wrapfunction(bookmarks, 'update', bookmarks_update)
extensions.wrapfunction(bookmarks, 'addbookmarks', bookmarks_addbookmarks)
- ui.setconfig('hooks', 'pretxncommit.' + MY_NAME, commit_hook, source=MY_NAME)
-
+ # commit hook conflicts with shelving
+ # ui.setconfig('hooks', 'pretxncommit.' + MY_NAME, commit_hook, source=MY_NAME)
def uisetup(ui):
extensions.wrapcommand(commands.table, 'commit', commands_commit)
+ extensions.wrapcommand(commands.table, 'pull', commands_pull)
if not ui.configbool(MY_NAME, 'enable_branches'):
extensions.wrapcommand(commands.table, 'branch', commands_branch)
To: idlsoft, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list