subrepo: lazier git push logic
Avoids calls to git push when the revision is already known to be
in the remote repository. Now, when using a read-only git subrepo,
git will never need to talk to its upstream repository.
--- a/mercurial/subrepo.py Mon Nov 22 17:39:46 2010 +0100
+++ b/mercurial/subrepo.py Sun Nov 21 22:00:51 2010 -0500
@@ -665,6 +665,10 @@
out, code = self._gitdir(['cat-file', '-e', revision])
return code == 0
+ def _gitisancestor(self, r1, r2):
+ base = self._gitcommand(['merge-base', r1, r2]).strip()
+ return base == r1
+
def _gitbranchmap(self):
'returns the current branch and a map from git revision to branch[es]'
bm = {}
@@ -767,17 +771,31 @@
self._gitcommand(['merge', '--no-commit', revision])
def push(self, force):
+ # if a branch in origin contains the revision, nothing to do
+ current, bm = self._gitbranchmap()
+ for revision, branches in bm.iteritems():
+ for b in branches:
+ if b.startswith('remotes/origin'):
+ if self._gitisancestor(self._state[1], revision):
+ return True
+ # otherwise, try to push the currently checked out branch
cmd = ['push']
if force:
cmd.append('--force')
- # push the currently checked out branch
- current, bm = self._gitbranchmap()
if current:
+ # determine if the current branch is even useful
+ if not self._gitisancestor(self._state[1], current):
+ self._ui.warn(_('unrelated git branch checked out '
+ 'in subrepo %s\n') % self._relpath)
+ return False
+ self._ui.status(_('pushing branch %s of subrepo %s\n') %
+ (current, self._relpath))
self._gitcommand(cmd + ['origin', current, '-q'])
return True
else:
self._ui.warn(_('no branch checked out in subrepo %s\n'
- 'nothing to push') % self._relpath)
+ 'cannot push revision %s') %
+ (self._relpath, self._state[1]))
return False
def remove(self):
--- a/tests/test-subrepo-git.t Mon Nov 22 17:39:46 2010 +0100
+++ b/tests/test-subrepo-git.t Sun Nov 21 22:00:51 2010 -0500
@@ -134,6 +134,7 @@
$ hg push
pushing to $TESTTMP/t
+ pushing branch testing of subrepo s
searching for changes
adding changesets
adding manifests
@@ -170,12 +171,44 @@
revision f47b465e1bce645dbf37232a00574aa1546ca8d3
$ hg push
pushing to $TESTTMP/t
+ pushing branch testing of subrepo s
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
+make upstream git changes
+
+ $ cd ..
+ $ git clone -q gitroot gitclone
+ $ cd gitclone
+ $ echo ff >> f
+ $ git commit -q -a -m ff
+ $ echo fff >> f
+ $ git commit -q -a -m fff
+ $ git push -q origin testing
+
+make and push changes to hg without updating the subrepo
+
+ $ cd ../t
+ $ hg clone . ../td
+ updating to branch default
+ cloning subrepo s
+ checking out detached HEAD in subrepo s
+ check out a git branch if you intend to make changes
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cd ../td
+ $ echo aa >> a
+ $ hg commit -m aa
+ $ hg push
+ pushing to $TESTTMP/t
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files
+
update to a revision without the subrepo, keeping the local git repository
$ cd ../t