Patchwork D8625: git: add debug logging when there's a mismatch in the cached heads list

login
register
mail settings
Submitter phabricator
Date June 9, 2020, 9:15 p.m.
Message ID <differential-rev-PHID-DREV-6p3pkrqi4vw4r4maseg5-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/46492/
State Superseded
Headers show

Comments

phabricator - June 9, 2020, 9:15 p.m.
durin42 created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  The dag rebuild can be expensive, so let's try and avoid bugs where it
  transparently rebuilds all the time for no reason. This would have
  prevented the issue fixed in D8622 <https://phab.mercurial-scm.org/D8622>.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D8625

AFFECTED FILES
  hgext/git/__init__.py
  hgext/git/gitlog.py
  hgext/git/index.py
  tests/test-git-interop.t

CHANGE DETAILS




To: durin42, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-git-interop.t b/tests/test-git-interop.t
--- a/tests/test-git-interop.t
+++ b/tests/test-git-interop.t
@@ -36,8 +36,12 @@ 
   $ cd ..
 
 Now globally enable extension for the rest of the test:
-  $ echo "[extensions]" >> $HGRCPATH
-  > echo "git=" >> $HGRCPATH
+  $ cat <<EOF >> $HGRCPATH
+  > [extensions]
+  > git=
+  > [git]
+  > log-index-cache-miss = yes
+  > EOF
 
 Make a new repo with git:
   $ mkdir foo
@@ -68,11 +72,14 @@ 
 But if you run hg init --git, it works:
   $ hg init --git
   $ hg id --traceback
+  heads mismatch, rebuilding dagcache
   3d9be8deba43 tip master
   $ hg status
+  heads mismatch, rebuilding dagcache
   ? gamma
 Log works too:
   $ hg log
+  heads mismatch, rebuilding dagcache
   changeset:   1:3d9be8deba43
   bookmark:    master
   tag:         tip
@@ -89,7 +96,8 @@ 
 
 and bookmarks:
   $ hg bookmarks
-   * master                    1:3d9be8deba43
+   * masterheads mismatch, rebuilding dagcache
+                      1:3d9be8deba43
 
 diff even works transparently in both systems:
   $ echo blah >> alpha
@@ -102,6 +110,7 @@ 
    alpha
   +blah
   $ hg diff --git
+  heads mismatch, rebuilding dagcache
   diff --git a/alpha b/alpha
   --- a/alpha
   +++ b/alpha
@@ -112,12 +121,15 @@ 
 Remove a file, it shows as such:
   $ rm alpha
   $ hg status
+  heads mismatch, rebuilding dagcache
   ! alpha
   ? gamma
 
 Revert works:
   $ hg revert alpha --traceback
+  heads mismatch, rebuilding dagcache
   $ hg status
+  heads mismatch, rebuilding dagcache
   ? gamma
   $ git status
   On branch master
@@ -130,6 +142,7 @@ 
 Add shows sanely in both:
   $ hg add gamma
   $ hg status
+  heads mismatch, rebuilding dagcache
   A gamma
   $ hg files
   alpha
@@ -148,7 +161,9 @@ 
 
 forget does what it should as well:
   $ hg forget gamma
+  heads mismatch, rebuilding dagcache
   $ hg status
+  heads mismatch, rebuilding dagcache
   ? gamma
   $ git status
   On branch master
@@ -165,11 +180,15 @@ 
 
   $ echo a >> alpha
   $ hg ci -m 'more alpha' --traceback --date '1583522787 18000'
+  heads mismatch, rebuilding dagcache
   $ echo b >> beta
   $ hg ci -m 'more beta'
+  heads mismatch, rebuilding dagcache
   $ echo a >> alpha
   $ hg ci -m 'even more alpha'
+  heads mismatch, rebuilding dagcache
   $ hg log -G alpha
+  heads mismatch, rebuilding dagcache
   @  changeset:   4:6626247b7dc8
   :  bookmark:    master
   :  tag:         tip
@@ -188,6 +207,7 @@ 
      summary:     Add alpha
   
   $ hg log -G beta
+  heads mismatch, rebuilding dagcache
   o  changeset:   3:d8ee22687733
   :  user:        test <test>
   :  date:        Thu Jan 01 00:00:00 1970 +0000
@@ -200,15 +220,18 @@ 
   
 
   $ hg log -r "children(3d9be8deba43)" -T"{node|short} {children}\n"
+  heads mismatch, rebuilding dagcache
   a1983dd7fb19 3:d8ee22687733
 
 hg annotate
 
   $ hg annotate alpha
+  heads mismatch, rebuilding dagcache
   0: alpha
   2: a
   4: a
   $ hg annotate beta
+  heads mismatch, rebuilding dagcache
   1: beta
   3: b
 
@@ -219,6 +242,7 @@ 
   $ mkdir a
   $ echo "This is file mu." > a/mu
   $ hg ci -A -m 'Introduce file a/mu'
+  heads mismatch, rebuilding dagcache
   adding a/mu
 
 Both hg and git agree a/mu is part of the repo
@@ -238,10 +262,12 @@ 
   On branch master
   nothing to commit, working tree clean
   $ hg status
+  heads mismatch, rebuilding dagcache
 
 
 node|shortest works correctly
   $ hg log -T '{node}\n' | sort
+  heads mismatch, rebuilding dagcache
   3d9be8deba43482be2c81a4cb4be1f10d85fa8bc
   6626247b7dc8f231b183b8a4761c89139baca2ad
   a1983dd7fb19cbd83ad5a1c2fc8bf3d775dea12f
@@ -249,13 +275,16 @@ 
   c5864c9d16fb3431fe2c175ff84dc6accdbb2c18
   d8ee22687733a1991813560b15128cd9734f4b48
   $ hg log -r ae1ab744f95bfd5b07cf573baef98a778058537b --template "{shortest(node,1)}\n"
+  heads mismatch, rebuilding dagcache
   ae
 
 This coveres changelog.findmissing()
   $ hg merge --preview 3d9be8deba43
+  heads mismatch, rebuilding dagcache
 
 This covers manifest.diff()
   $ hg diff -c 3d9be8deba43
+  heads mismatch, rebuilding dagcache
   diff -r c5864c9d16fb -r 3d9be8deba43 beta
   --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   +++ b/beta	Mon Jan 01 00:00:11 2007 +0000
diff --git a/hgext/git/index.py b/hgext/git/index.py
--- a/hgext/git/index.py
+++ b/hgext/git/index.py
@@ -216,7 +216,12 @@ 
     db.commit()
 
 
-def _index_repo(gitrepo, db, progress_factory=lambda *args, **kwargs: None):
+def _index_repo(
+    gitrepo,
+    db,
+    logfn=lambda x: None,
+    progress_factory=lambda *args, **kwargs: None,
+):
     # Identify all references so we can tell the walker to visit all of them.
     all_refs = gitrepo.listall_references()
     possible_heads = set()
@@ -253,6 +258,7 @@ 
     cur_cache_heads = {h.hex for h in possible_heads}
     if cur_cache_heads == cache_heads:
         return
+    logfn(b'heads mismatch, rebuilding dagcache\n')
     for start in possible_heads:
         if walker is None:
             walker = gitrepo.walk(start, _OUR_ORDER)
@@ -339,7 +345,9 @@ 
         prog.complete()
 
 
-def get_index(gitrepo, progress_factory=lambda *args, **kwargs: None):
+def get_index(
+    gitrepo, logfn=lambda x: None, progress_factory=lambda *args, **kwargs: None
+):
     cachepath = os.path.join(
         pycompat.fsencode(gitrepo.path), b'..', b'.hg', b'cache'
     )
@@ -349,5 +357,5 @@ 
     db = _createdb(dbpath)
     # TODO check against gitrepo heads before doing a full index
     # TODO thread a ui.progress call into this layer
-    _index_repo(gitrepo, db, progress_factory)
+    _index_repo(gitrepo, db, logfn, progress_factory)
     return db
diff --git a/hgext/git/gitlog.py b/hgext/git/gitlog.py
--- a/hgext/git/gitlog.py
+++ b/hgext/git/gitlog.py
@@ -399,7 +399,7 @@ 
             'refs/hg/internal/latest-commit', oid, force=True
         )
         # Reindex now to pick up changes. We omit the progress
-        # callback because this will be very quick.
+        # and log callbacks because this will be very quick.
         index._index_repo(self.gitrepo, self._db)
         return oid.raw
 
diff --git a/hgext/git/__init__.py b/hgext/git/__init__.py
--- a/hgext/git/__init__.py
+++ b/hgext/git/__init__.py
@@ -16,6 +16,7 @@ 
     extensions,
     localrepo,
     pycompat,
+    registrar,
     scmutil,
     store,
     util,
@@ -28,6 +29,13 @@ 
     index,
 )
 
+configtable = {}
+configitem = registrar.configitem(configtable)
+# git.log-index-cache-miss: internal knob for testing
+configitem(
+    b"git", b"log-index-cache-miss", default=False,
+)
+
 # TODO: extract an interface for this in core
 class gitstore(object):  # store.basicstore):
     def __init__(self, path, vfstype):
@@ -41,13 +49,14 @@ 
             os.path.normpath(os.path.join(path, b'..', b'.git'))
         )
         self._progress_factory = lambda *args, **kwargs: None
+        self._logfn = lambda x: None
 
     @util.propertycache
     def _db(self):
         # We lazy-create the database because we want to thread a
         # progress callback down to the indexing process if it's
         # required, and we don't have a ui handle in makestore().
-        return index.get_index(self.git, self._progress_factory)
+        return index.get_index(self.git, self._logfn, self._progress_factory)
 
     def join(self, f):
         """Fake store.join method for git repositories.
@@ -276,6 +285,8 @@ 
     if repo.local() and isinstance(repo.store, gitstore):
         orig = repo.__class__
         repo.store._progress_factory = repo.ui.makeprogress
+        if ui.configbool(b'git', b'log-index-cache-miss'):
+            repo.store._logfn = repo.ui.warn
 
         class gitlocalrepo(orig):
             def _makedirstate(self):