branching: merge stable into default
authorRaphaël Gomès <rgomes@octobus.net>
Wed, 12 Jun 2024 11:29:11 +0200
changeset 51642 69c5f8d6c710
parent 51632 9c668377aa9f (current diff)
parent 51641 a898c24a4cd0 (diff)
child 51644 f28c52a9f7b4
branching: merge stable into default
mercurial/changelog.py
mercurial/exchange.py
mercurial/localrepo.py
--- a/.hgsigs	Wed Sep 06 18:23:32 2023 +0200
+++ b/.hgsigs	Wed Jun 12 11:29:11 2024 +0200
@@ -261,3 +261,4 @@
 2e6fde2ed01e63f0de6a5966994fbb60b1f87057 0 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
+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
--- a/.hgtags	Wed Sep 06 18:23:32 2023 +0200
+++ b/.hgtags	Wed Jun 12 11:29:11 2024 +0200
@@ -277,3 +277,4 @@
 2e6fde2ed01e63f0de6a5966994fbb60b1f87057 6.7.1
 803e61387e86f103483120df35619bdb175e3482 6.7.2
 028dc3f92dbd0f93bb78f9848c94ba5eecd72e71 6.7.3
+a1a011d4b148955975cb40d619d285fdd4ee8713 6.7.4
--- a/mercurial/changelog.py	Wed Sep 06 18:23:32 2023 +0200
+++ b/mercurial/changelog.py	Wed Jun 12 11:29:11 2024 +0200
@@ -360,8 +360,10 @@
             if new_index is not None:
                 self._indexfile = new_index
                 tr.registertmp(new_index)
-        tr.addpending(b'cl-%i' % id(self), self._writepending)
-        tr.addfinalize(b'cl-%i' % id(self), self._finalize)
+        # use "000" as prefix to make sure we run before the spliting of legacy
+        # inline changelog..
+        tr.addpending(b'000-cl-%i' % id(self), self._writepending)
+        tr.addfinalize(b'000-cl-%i' % id(self), self._finalize)
 
     def _finalize(self, tr):
         """finalize index updates"""
--- a/mercurial/exchange.py	Wed Sep 06 18:23:32 2023 +0200
+++ b/mercurial/exchange.py	Wed Jun 12 11:29:11 2024 +0200
@@ -490,42 +490,46 @@
     # get lock as we might write phase data
     wlock = lock = None
     try:
-        # bundle2 push may receive a reply bundle touching bookmarks
-        # requiring the wlock. Take it now to ensure proper ordering.
-        maypushback = pushop.ui.configbool(b'experimental', b'bundle2.pushback')
-        if (
-            (not _forcebundle1(pushop))
-            and maypushback
-            and not bookmod.bookmarksinstore(repo)
-        ):
-            wlock = pushop.repo.wlock()
-        lock = pushop.repo.lock()
-        pushop.trmanager = transactionmanager(
-            pushop.repo, b'push-response', pushop.remote.url()
-        )
-    except error.LockUnavailable as err:
-        # source repo cannot be locked.
-        # We do not abort the push, but just disable the local phase
-        # synchronisation.
-        msg = b'cannot lock source repository: %s\n' % stringutil.forcebytestr(
-            err
-        )
-        pushop.ui.debug(msg)
-
-    with wlock or util.nullcontextmanager():
-        with lock or util.nullcontextmanager():
-            with pushop.trmanager or util.nullcontextmanager():
-                pushop.repo.checkpush(pushop)
-                _checkpublish(pushop)
-                _pushdiscovery(pushop)
-                if not pushop.force:
-                    _checksubrepostate(pushop)
-                if not _forcebundle1(pushop):
-                    _pushbundle2(pushop)
-                _pushchangeset(pushop)
-                _pushsyncphase(pushop)
-                _pushobsolete(pushop)
-                _pushbookmark(pushop)
+        try:
+            # bundle2 push may receive a reply bundle touching bookmarks
+            # requiring the wlock. Take it now to ensure proper ordering.
+            maypushback = pushop.ui.configbool(
+                b'experimental',
+                b'bundle2.pushback',
+            )
+            if (
+                (not _forcebundle1(pushop))
+                and maypushback
+                and not bookmod.bookmarksinstore(repo)
+            ):
+                wlock = pushop.repo.wlock()
+            lock = pushop.repo.lock()
+            pushop.trmanager = transactionmanager(
+                pushop.repo, b'push-response', pushop.remote.url()
+            )
+        except error.LockUnavailable as err:
+            # source repo cannot be locked.
+            # We do not abort the push, but just disable the local phase
+            # synchronisation.
+            msg = b'cannot lock source repository: %s\n'
+            msg %= stringutil.forcebytestr(err)
+            pushop.ui.debug(msg)
+
+        pushop.repo.checkpush(pushop)
+        _checkpublish(pushop)
+        _pushdiscovery(pushop)
+        if not pushop.force:
+            _checksubrepostate(pushop)
+        if not _forcebundle1(pushop):
+            _pushbundle2(pushop)
+        _pushchangeset(pushop)
+        _pushsyncphase(pushop)
+        _pushobsolete(pushop)
+        _pushbookmark(pushop)
+        if pushop.trmanager is not None:
+            pushop.trmanager.close()
+    finally:
+        lockmod.release(pushop.trmanager, lock, wlock)
 
     if repo.ui.configbool(b'experimental', b'remotenames'):
         logexchange.pullremotenames(repo, remote)
@@ -745,13 +749,19 @@
             if bookmod.isdivergent(b):
                 pushop.ui.warn(_(b'cannot push divergent bookmark %s!\n') % b)
                 pushop.bkresult = 2
+            elif pushed and repo[scid].rev() not in pushed:
+                # in case of race or secret
+                msg = _(b'cannot push bookmark X without its revision: %s!\n')
+                pushop.ui.warn(msg % b)
+                pushop.bkresult = 2
             else:
                 pushop.outbookmarks.append((b, b'', scid))
     # search for overwritten bookmark
     for b, scid, dcid in list(advdst) + list(diverge) + list(differ):
         if b in explicit:
             explicit.remove(b)
-            pushop.outbookmarks.append((b, dcid, scid))
+            if not pushed or repo[scid].rev() in pushed:
+                pushop.outbookmarks.append((b, dcid, scid))
     # search for bookmark to delete
     for b, scid, dcid in adddst:
         if b in explicit:
@@ -1739,10 +1749,10 @@
             )
 
     pullop.trmanager = transactionmanager(repo, b'pull', remote.url())
-    wlock = util.nullcontextmanager()
+    wlock = util.nullcontextmanager
     if not bookmod.bookmarksinstore(repo):
-        wlock = repo.wlock()
-    with wlock, repo.lock(), pullop.trmanager:
+        wlock = repo.wlock
+    with wlock(), repo.lock(), pullop.trmanager:
         if confirm or (
             repo.ui.configbool(b"pull", b"confirm") and not repo.ui.plain()
         ):
--- a/mercurial/helptext/config.txt	Wed Sep 06 18:23:32 2023 +0200
+++ b/mercurial/helptext/config.txt	Wed Jun 12 11:29:11 2024 +0200
@@ -1438,6 +1438,12 @@
   parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
   update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
 
+``prelock``
+  run before the store lock is taken, mostly used for test and debug.
+
+``prewlock``
+  run before the working copy lock is taken, mostly used for test and debug.
+
 .. note::
 
    It is generally better to use standard hooks rather than the
--- a/mercurial/localrepo.py	Wed Sep 06 18:23:32 2023 +0200
+++ b/mercurial/localrepo.py	Wed Jun 12 11:29:11 2024 +0200
@@ -3122,6 +3122,7 @@
             l.lock()
             return l
 
+        self.hook(b'prelock', throw=True)
         l = self._lock(
             vfs=self.svfs,
             lockname=b"lock",
@@ -3146,6 +3147,7 @@
             l.lock()
             return l
 
+        self.hook(b'prewlock', throw=True)
         # We do not need to check for non-waiting lock acquisition.  Such
         # acquisition would not cause dead-lock as they would just fail.
         if wait and (
--- a/mercurial/revlog.py	Wed Sep 06 18:23:32 2023 +0200
+++ b/mercurial/revlog.py	Wed Jun 12 11:29:11 2024 +0200
@@ -1148,7 +1148,14 @@
         )
 
     def _divert_index(self):
-        return self.index_file + b'.a'
+        index_file = self.index_file
+        # when we encounter a legacy inline-changelog, split it. However it is
+        # important to use the expected filename for pending content
+        # (<radix>.a) otherwise hooks won't be seeing the content of the
+        # pending transaction.
+        if index_file.endswith(b'.s'):
+            index_file = self.index_file[:-2]
+        return index_file + b'.a'
 
     def delay(self):
         assert not self.is_open
@@ -2895,10 +2902,13 @@
                 maybe_self._inner.index_file = old_index_file_path
 
         tr.registertmp(new_index_file_path)
+        # we use 001 here to make this this happens after the finalisation of
+        # pending changelog write (using 000). Otherwise the two finalizer
+        # would step over each other and delete the changelog.i file.
         if self.target[1] is not None:
-            callback_id = b'000-revlog-split-%d-%s' % self.target
+            callback_id = b'001-revlog-split-%d-%s' % self.target
         else:
-            callback_id = b'000-revlog-split-%d' % self.target[0]
+            callback_id = b'001-revlog-split-%d' % self.target[0]
         tr.addfinalize(callback_id, finalize_callback)
         tr.addabort(callback_id, abort_callback)
 
--- a/relnotes/6.7	Wed Sep 06 18:23:32 2023 +0200
+++ b/relnotes/6.7	Wed Jun 12 11:29:11 2024 +0200
@@ -1,5 +1,23 @@
+= Mercurial 6.7.4 =
+
+Exceptional release following a critical regression causing possible data loss
+in certain conditions:
+
+ * inline-changelog: fix a critical bug in write_pending that delete data (3cf9e52f5e27)
+ * inline-changelog: fix pending transaction visibility when splitting (1721d983dd6d)
+
+Other changes in this release:
+
+ * exchange: fix locking to actually be scoped
+ * chistedit: change action for the correct item
+ * rust-status: sort the failed matches when printing them
+ * hooks: add a prewlock and a prelock hooks
+ * bookmark: fix remote bookmark deletion when the push is raced
+
 = Mercurial 6.7.3 =
 
+/!\ This release contains a bug causing possible data loss, use 6.7.4 instead.
+
  * setup: display return code information about failed `hg` call
  * bundle-spec: properly identify changegroup-less bundle
  * bundle-spec: properly parse boolean configuration as boolean
@@ -17,6 +35,8 @@
 
 = Mercurial 6.7.2 =
 
+/!\ This release contains a bug causing possible data loss, use 6.7.4 instead.
+
 Exceptional release following a large performance regression when cloning.
 
 We are setting up automated benchmarks to reduce the likelihood of regressions
@@ -28,6 +48,8 @@
 
 = Mercurial 6.7.1 =
 
+/!\ This release contains a bug causing possible data loss, use 6.7.4 instead.
+
 Exceptional release following a crash found in delta code that can be triggered
 with complex repository shapes.
 
@@ -37,6 +59,8 @@
 
 = Mercurial 6.7 =
 
+/!\ This release contains a bug causing possible data loss, use 6.7.4 instead.
+
 As usual, a *lot* of patches don't make it to this list.
 
 == New Features ==
Binary file tests/bundles/inlined-changelog.tar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-bookmarks-push-race.t	Wed Jun 12 11:29:11 2024 +0200
@@ -0,0 +1,153 @@
+============================================
+Testing various race condition while pushing
+============================================
+
+  $ cat << EOF >> $HGRCPATH
+  > [command-templates]
+  > log={rev}:{node|short} {desc|firstline} {bookmarks}
+  > [ui]
+  > timeout = 20
+  > [phases]
+  > publish=False
+  > EOF
+
+Initial Setup
+=============
+
+  $ hg init dst
+  $ echo a > dst/a-file
+  $ hg --cwd dst add a-file
+  $ hg --cwd dst commit -m root
+  $ hg --cwd dst bookmark my-book
+  $ hg --cwd dst bookmarks
+   * my-book                   0:a64e49638499
+  $ hg --cwd dst log -G
+  @  0:a64e49638499 root my-book
+  
+
+  $ hg clone ssh://user@dummy/dst src
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets a64e49638499 (1 drafts)
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg --cwd src update my-book
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (activating bookmark my-book)
+  $ hg --cwd src log -G
+  @  0:a64e49638499 root my-book
+  
+
+  $ echo b > src/a-file
+  $ hg --cwd src commit -m cA0_
+  $ hg --cwd src log -G
+  @  1:e89d3a6ed79b cA0_ my-book
+  |
+  o  0:a64e49638499 root
+  
+
+Race condition while pushing a forward moving bookmarks
+=======================================================
+
+This is currently slightly broken as we eventually don't push the bookmark.
+However at least we do not delete the remote one.
+
+  $ echo c > src/a-file
+  $ hg --cwd src push -B my-book --config hooks.prelock="hg commit -m cA1_"
+  pushing to ssh://user@dummy/dst
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  $ hg --cwd src log -G
+  @  2:08d837bbfe8d cA1_ my-book
+  |
+  o  1:e89d3a6ed79b cA0_
+  |
+  o  0:a64e49638499 root
+  
+  $ hg --cwd dst log -G
+  o  1:e89d3a6ed79b cA0_
+  |
+  @  0:a64e49638499 root my-book
+  
+
+create a side-moving bookmark
+Race condition while pushing a side moving bookmarks
+=======================================================
+
+resynchronize the repo and setup test
+-------------------------------------
+
+  $ hg --cwd src push -B my-book
+  pushing to ssh://user@dummy/dst
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  updating bookmark my-book
+  $ hg --cwd dst log -G
+  o  2:08d837bbfe8d cA1_ my-book
+  |
+  o  1:e89d3a6ed79b cA0_
+  |
+  @  0:a64e49638499 root
+  
+
+  $ hg --cwd src up 'desc("root")'
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (leaving bookmark my-book)
+  $ echo d > src/a-file
+  $ hg --cwd src commit -m cB0_
+  created new head
+  $ hg --cwd src bookmark --force my-book
+  $ echo e > src/a-file
+  $ hg --cwd src log -G
+  @  3:726401661fe5 cB0_ my-book
+  |
+  | o  2:08d837bbfe8d cA1_
+  | |
+  | o  1:e89d3a6ed79b cA0_
+  |/
+  o  0:a64e49638499 root
+  
+
+Push the bookmark while a commit is being made
+----------------------------------------------
+
+This is currently slightly broken as we eventually don't push the bookmark.
+However at least we do not delete the remote one.
+
+  $ hg --cwd src push -f -r 'desc("cB0_")' -B my-book --config hooks.prelock="hg commit -m cB1_"
+  pushing to ssh://user@dummy/dst
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files (+1 heads)
+  $ hg --cwd src log -G
+  @  4:a7f9cbf631a0 cB1_ my-book
+  |
+  o  3:726401661fe5 cB0_
+  |
+  | o  2:08d837bbfe8d cA1_
+  | |
+  | o  1:e89d3a6ed79b cA0_
+  |/
+  o  0:a64e49638499 root
+  
+
+  $ hg --cwd dst log -G
+  o  3:726401661fe5 cB0_
+  |
+  | o  2:08d837bbfe8d cA1_ my-book
+  | |
+  | o  1:e89d3a6ed79b cA0_
+  |/
+  @  0:a64e49638499 root
+  
--- a/tests/test-bookmarks.t	Wed Sep 06 18:23:32 2023 +0200
+++ b/tests/test-bookmarks.t	Wed Jun 12 11:29:11 2024 +0200
@@ -1082,9 +1082,9 @@
   >            time.sleep(0.5)
   >        if os.path.exists(b"$TESTTMP/unpause"):
   >            os.remove(b"$TESTTMP/unpause")
-  >    # It is important that this finalizer start with 'a', so it runs before
-  >    # the changelog finalizer appends to the changelog.
-  >    tr.addfinalize(b'a-sleep', sleep)
+  >    # It is important that this finalizer start with '000-a', so it runs
+  >    # before the changelog finalizer appends to the changelog.
+  >    tr.addfinalize(b'000-a-sleep', sleep)
   >    return tr
   > 
   > def extsetup(ui):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-split-legacy-inline-changelog.t	Wed Jun 12 11:29:11 2024 +0200
@@ -0,0 +1,303 @@
+======================================================
+Test operation on repository with an inlined changelog
+======================================================
+
+Inlined revlog has been a bag of complexity for a long time and the combination
+with special transaction logic on the changelog was a long source of bugs
+poorly covered by the test suites.
+
+We stopped doing any usage of inlined-revlog for changelog in a93e52f0b6ff,
+upgrading legacy inlined version as soon as possible when we see them. However
+this Mercurial does not produce such inlined-changelog that case is very poorly
+covered in the test suites. This test file aims at covering these cases.
+
+Double checking test data
+=========================
+
+We should have a repository around
+
+  $ mkdir sanity-check
+  $ cd sanity-check
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ cd inlined-changelog
+  $ hg root
+  $TESTTMP/sanity-check/inlined-changelog
+
+The repository should not be corrupted initially
+
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 1 changesets with 1 changes to 1 files
+
+The changelog of that repository MUST be inlined
+
+  $ hg debugrevlog -c | grep -E '^flags\b'
+  flags  : inline
+
+Touching that repository MUST split that inlined changelog
+
+  $ hg branch foo --quiet
+  $ hg commit -m foo --quiet
+  $ hg debugrevlog -c | grep -E '^flags\b'
+  flags  : (none)
+
+  $ cd ../..
+
+Test doing a simple commit
+==========================
+
+Simple commit
+-------------
+
+  $ mkdir simple-commit
+  $ cd simple-commit
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ cd inlined-changelog
+  $ hg up --quiet
+  $ hg log -GT '[{rev}] {desc}\n'
+  @  [0] first commit
+  
+  $ echo b > b
+  $ hg add b
+  $ hg commit -m "second changeset"
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 2 changesets with 2 changes to 2 files
+  $ hg log -GT '[{rev}] {desc}\n'
+  @  [1] second changeset
+  |
+  o  [0] first commit
+  
+  $ cd ../..
+
+Simple commit with a pretxn hook configured
+-------------------------------------------
+
+Before 6.7.3 this used to delete the changelog index
+
+  $ mkdir pretxnclose-commit
+  $ cd pretxnclose-commit
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ cat >> inlined-changelog/.hg/hgrc <<EOF
+  > [hooks]
+  > pretxnclose=hg log -r tip -T "pre-txn tip rev: {rev}\n"
+  > EOF
+  $ cd inlined-changelog
+  $ hg up --quiet
+  $ hg log -GT '[{rev}] {desc}\n'
+  @  [0] first commit
+  
+  $ echo b > b
+  $ hg add b
+  $ hg commit -m "second changeset"
+  pre-txn tip rev: 1
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 2 changesets with 2 changes to 2 files
+  $ hg log -GT '[{rev}] {desc}\n'
+  @  [1] second changeset
+  |
+  o  [0] first commit
+  
+  $ cd ../..
+
+Test pushing to a repository with a repository revlog
+=====================================================
+
+Simple local push
+-----------------
+
+  $ mkdir simple-local-push
+  $ cd simple-local-push
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [0] first commit
+
+  $ hg clone --pull inlined-changelog client
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets 827f11bfd362
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd client
+  $ echo b > b
+  $ hg add b
+  $ hg commit -m "second changeset"
+  $ hg push
+  pushing to $TESTTMP/*/inlined-changelog (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  $ cd ..
+
+  $ hg verify -R inlined-changelog
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 2 changesets with 2 changes to 2 files
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [1] second changeset
+  [0] first commit
+  $ cd ..
+
+Simple local push with a pretxnchangegroup hook
+-----------------------------------------------
+
+Before 6.7.3 this used to delete the server changelog
+
+  $ mkdir pretxnchangegroup-local-push
+  $ cd pretxnchangegroup-local-push
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ cat >> inlined-changelog/.hg/hgrc <<EOF
+  > [hooks]
+  > pretxnchangegroup=hg log -r tip -T "pre-txn tip rev: {rev}\n"
+  > EOF
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [0] first commit
+
+  $ hg clone --pull inlined-changelog client
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets 827f11bfd362
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd client
+  $ echo b > b
+  $ hg add b
+  $ hg commit -m "second changeset"
+  $ hg push
+  pushing to $TESTTMP/*/inlined-changelog (glob)
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  pre-txn tip rev: 1
+  added 1 changesets with 1 changes to 1 files
+  $ cd ..
+
+  $ hg verify -R inlined-changelog
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 2 changesets with 2 changes to 2 files
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [1] second changeset
+  [0] first commit
+  $ cd ..
+
+Simple ssh push
+-----------------
+
+  $ mkdir simple-ssh-push
+  $ cd simple-ssh-push
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [0] first commit
+
+  $ hg clone ssh://user@dummy/"`pwd`"/inlined-changelog client
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets 827f11bfd362
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd client
+  $ echo b > b
+  $ hg add b
+  $ hg commit -m "second changeset"
+  $ hg push
+  pushing to ssh://user@dummy/$TESTTMP/simple-ssh-push/inlined-changelog
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+  $ cd ..
+
+  $ hg verify -R inlined-changelog
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 2 changesets with 2 changes to 2 files
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [1] second changeset
+  [0] first commit
+  $ cd ..
+
+Simple ssh push with a pretxnchangegroup hook
+-----------------------------------------------
+
+Before 6.7.3 this used to delete the server changelog
+
+  $ mkdir pretxnchangegroup-ssh-push
+  $ cd pretxnchangegroup-ssh-push
+  $ tar xf $TESTDIR/bundles/inlined-changelog.tar
+  $ cat >> inlined-changelog/.hg/hgrc <<EOF
+  > [hooks]
+  > pretxnchangegroup=hg log -r tip -T "pre-txn tip rev: {rev}\n"
+  > EOF
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [0] first commit
+
+  $ hg clone ssh://user@dummy/"`pwd`"/inlined-changelog client
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets 827f11bfd362
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ cd client
+  $ echo b > b
+  $ hg add b
+  $ hg commit -m "second changeset"
+  $ hg push
+  pushing to ssh://user@dummy/$TESTTMP/pretxnchangegroup-ssh-push/inlined-changelog
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: pre-txn tip rev: 1
+  remote: added 1 changesets with 1 changes to 1 files
+  $ cd ..
+
+  $ hg verify -R inlined-changelog
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checking dirstate
+  checked 2 changesets with 2 changes to 2 files
+  $ hg log -R inlined-changelog -T '[{rev}] {desc}\n'
+  [1] second changeset
+  [0] first commit
+  $ cd ..