# HG changeset patch # User Pierre-Yves David # Date 1677087729 -3600 # Node ID 596a6b9b0570a86702aa2ac446ff980d9e97708e # Parent bf27727e6c7805bd2b4d83147ce38552c02c6f63# Parent ee63c87a0cac92520c04ac922e6a7d001c16960e branching: merge stable into default This show that the recent changes on default fixed the issue with transaction overwriting content in `test-transaction-wc-rollback-race.t` diff -r ee63c87a0cac -r 596a6b9b0570 rust/Cargo.lock --- a/rust/Cargo.lock Fri Feb 17 16:48:11 2023 +0000 +++ b/rust/Cargo.lock Wed Feb 22 18:42:09 2023 +0100 @@ -1023,21 +1023,19 @@ [[package]] name = "rayon" -version = "1.5.3" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", diff -r ee63c87a0cac -r 596a6b9b0570 rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml Fri Feb 17 16:48:11 2023 +0000 +++ b/rust/hg-core/Cargo.toml Wed Feb 22 18:42:09 2023 +0100 @@ -24,7 +24,7 @@ rand = "0.8.5" rand_pcg = "0.3.1" rand_distr = "0.4.3" -rayon = "1.5.3" +rayon = "1.6.1" regex = "1.7.0" sha-1 = "0.10.0" twox-hash = "1.6.3" diff -r ee63c87a0cac -r 596a6b9b0570 rust/rhg/Cargo.toml --- a/rust/rhg/Cargo.toml Fri Feb 17 16:48:11 2023 +0000 +++ b/rust/rhg/Cargo.toml Wed Feb 22 18:42:09 2023 +0100 @@ -22,4 +22,4 @@ format-bytes = "0.3.0" users = "0.11.0" which = "4.3.0" -rayon = "1.5.3" +rayon = "1.6.1" diff -r ee63c87a0cac -r 596a6b9b0570 setup.py --- a/setup.py Fri Feb 17 16:48:11 2023 +0000 +++ b/setup.py Wed Feb 22 18:42:09 2023 +0100 @@ -333,6 +333,8 @@ pieces = sysstr(hg.run(cmd)).split() numerictags = [t for t in pieces if t[0:1].isdigit()] hgid = sysstr(hg.run(['id', '-i'])).strip() + if hgid.count('+') == 2: + hgid = hgid.replace("+", ".", 1) if not hgid: eprint("/!\\") eprint(r"/!\ Unable to determine hg version from local repository") @@ -343,7 +345,7 @@ if hgid.endswith('+'): # propagate the dirty status to the tag version += '+' else: # no tag found on the checked out revision - ltagcmd = ['parents', '--template', '{latesttag}'] + ltagcmd = ['log', '--rev', 'wdir()', '--template', '{latesttag}'] ltag = sysstr(hg.run(ltagcmd)) if not ltag: eprint("/!\\") @@ -352,7 +354,13 @@ r"/!\ Failed to retrieve current revision distance to lated tag" ) return '' - changessincecmd = ['log', '-T', 'x\n', '-r', "only(.,'%s')" % ltag] + changessincecmd = [ + 'log', + '-T', + 'x\n', + '-r', + "only(parents(),'%s')" % ltag, + ] changessince = len(hg.run(changessincecmd).splitlines()) version = '%s+hg%s.%s' % (ltag, changessince, hgid) if version.endswith('+'): diff -r ee63c87a0cac -r 596a6b9b0570 tests/test-transaction-wc-rollback-race.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-transaction-wc-rollback-race.t Wed Feb 22 18:42:09 2023 +0100 @@ -0,0 +1,263 @@ +======================================================================= +Check potential race condition around transaction and working copy data +======================================================================= + +#testcases bookmarks-in-store bookmarks-wc-level + +The transaction is garanteed to run with the lock, but may runs without the +wlock. So if the transaction backup/restore some content related to the +working-copy and protected by the wlock, we might run into trouble if another +process grab the wlock and modify them. + +This test file is testing various cases where such parallel changes happens to +validate the transaction behavior. + +Other is used to get a simple pull source. As pull is a simple way to create +transaction without the wlock. + +Setup +===== + +Avoid long deadlock + + $ cat << EOF >> $HGRCPATH + > [ui] + > timeout=10 + > EOF + +#if bookmarks-in-store + $ cat << EOF >> $HGRCPATH + > [format] + > bookmarks-in-store = yes + > EOF +#endif + + + $ hg init repo + $ cd repo + $ for filename in a b c d e f g h i j k l m; do + > echo $filename > default_$filename + > hg add default_$filename + > hg commit --quiet --message default_$filename + > done + $ hg bookmark --rev . foo + $ hg branch babar + marked working directory as branch babar + (branches are permanent and global, did you want a bookmark?) + $ for filename in a b c d e f g h i j k l m; do + > echo $filename > babar_$filename + > hg add babar_$filename + > hg commit --quiet --message babar_$filename + > done + $ hg bookmark --rev . bar + $ hg up 'desc("default_m")' + 0 files updated, 0 files merged, 13 files removed, 0 files unresolved + $ hg log -G -T '[{branch}] ({bookmarks}) {desc}\n' + o [babar] (bar) babar_m + | + o [babar] () babar_l + | + o [babar] () babar_k + | + o [babar] () babar_j + | + o [babar] () babar_i + | + o [babar] () babar_h + | + o [babar] () babar_g + | + o [babar] () babar_f + | + o [babar] () babar_e + | + o [babar] () babar_d + | + o [babar] () babar_c + | + o [babar] () babar_b + | + o [babar] () babar_a + | + @ [default] (foo) default_m + | + o [default] () default_l + | + o [default] () default_k + | + o [default] () default_j + | + o [default] () default_i + | + o [default] () default_h + | + o [default] () default_g + | + o [default] () default_f + | + o [default] () default_e + | + o [default] () default_d + | + o [default] () default_c + | + o [default] () default_b + | + o [default] () default_a + + + $ cat << EOF >> ../txn-close.sh + > rm -f $TESTTMP/transaction-continue + > $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-continue $TESTTMP/transaction-waiting + > rm -f $TESTTMP/transaction-waiting + > exit 1 + > EOF + $ cat << EOF >> .hg/hgrc + > [hooks] + > pretxnclose.test = sh $TESTTMP/txn-close.sh + > EOF + +Check the overall logic is working, the transaction is holding the `lock` , but +not the `wlock`, then get aborted on a signal-file. + + $ hg phase --rev 0 + 0: draft + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ echo y | hg --config ui.interactive=yes debuglock --set-wlock + ready to release the lock (y)? y + $ echo y | hg --config ui.interactive=yes debuglock --set-lock + abort: lock is already held + [255] + $ touch $TESTTMP/transaction-continue + $ wait + $ hg phase --rev 0 + 0: draft + $ cat ../log.err + abort: pretxnclose.test hook exited with status 1 + +Actual testing +============== + +Changing tracked file +--------------------- + + $ hg status + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ hg forget default_a + $ hg status + R default_a + $ touch $TESTTMP/transaction-continue + $ wait + $ hg status + R default_a + $ hg revert --all --quiet + +Changing branch from default +---------------------------- + + $ hg branch + default + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ hg branch celeste + marked working directory as branch celeste + $ hg branch + celeste + $ touch $TESTTMP/transaction-continue + $ wait + $ hg branch + celeste + +Changing branch from another one +-------------------------------- + + $ hg up babar --quiet + $ hg branch + babar + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ hg branch celeste + marked working directory as branch celeste + $ hg branch + celeste + $ touch $TESTTMP/transaction-continue + $ wait + $ hg branch + celeste + +updating working copy +--------------------- + + $ hg st + $ hg log --rev . -T '{desc}\n' + babar_m + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ hg update "parents(.)" --quiet + $ hg log --rev . -T '{desc}\n' + babar_l + $ hg st + $ touch $TESTTMP/transaction-continue + $ wait + $ hg log --rev . -T '{desc}\n' + babar_l + $ hg st + + $ hg purge --no-confirm + $ hg up --quiet babar + +Activating a bookmark +--------------------- +(without going through the bookmark command) + +Show the activation/desactivation pattern that exist without taking the store +lock. + + $ hg log -r . -T '= {activebookmark} =\n' + = = + $ hg up bar + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark bar) + $ hg log -r . -T '= {activebookmark} =\n' + = bar = + $ hg up . + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + (leaving bookmark bar) + $ hg log -r . -T '= {activebookmark} =\n' + = = + +Activating the bookmark during a transaction + + $ hg up . --quiet + $ hg log -r . -T '= {activebookmark} =\n' + = = + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ hg up bar + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + (activating bookmark bar) + $ hg log -r . -T '= {activebookmark} =\n' + = bar = + $ touch $TESTTMP/transaction-continue + $ wait + $ hg log -r . -T '= {activebookmark} =\n' + = bar = + +Deactivating the bookmark + + $ hg up bar --quiet + $ hg log -r . -T '= {activebookmark} =\n' + = bar = + $ hg phase --public --rev 0 2> ../log.err & + $ $RUNTESTDIR/testlib/wait-on-file 5 $TESTTMP/transaction-waiting + $ hg up . + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + (leaving bookmark bar) + $ hg log -r . -T '= {activebookmark} =\n' + = = + $ touch $TESTTMP/transaction-continue + $ wait + $ hg log -r . -T '= {activebookmark} =\n' + = =