summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2014-08-30 21:22:48 (GMT)
committerRichard Maw <richard.maw@codethink.co.uk>2014-09-02 16:31:17 (GMT)
commit66ec3928392d09cba6037fc6c665cb1aa02e86e1 (patch)
tree11ad39373466065a3058fab42372381e517e11ec
parentf96452965e8065466bdd7188e66dded581bdc1a7 (diff)
downloadmorph-66ec3928392d09cba6037fc6c665cb1aa02e86e1.tar.gz
Use git's remotes to determine unpushed branchesbaserock/richardmaw/less-ls-remote
Rather than using `git ls-remote` every time to see if there are changes at the remote end, use a local cache. Git already solves this problem with its refs/remotes/$foo branch namespace, so we can just use that instead. In addition, the detection of which upstream branch to use has been improved; it now uses git's notion of which the upstream branch of your current branch is, which saves effort in the implementation, and allows the name of the local branch to differ from that of the remote branch. This now won't notice if the branch you currently have checked out had commits pushed from another source, but for some use-cases this is preferable, as the result equivalent to if you had built before the other push. It may make sense to further extend this logic to check that the local branch is not ahead of the remote branch, instead of requiring them to be equal.
-rw-r--r--morphlib/buildbranch.py17
-rw-r--r--morphlib/gitdir.py16
2 files changed, 23 insertions, 10 deletions
diff --git a/morphlib/buildbranch.py b/morphlib/buildbranch.py
index 885f5cf..638350e 100644
--- a/morphlib/buildbranch.py
+++ b/morphlib/buildbranch.py
@@ -222,17 +222,14 @@ class BuildBranch(object):
'''
for gd, (build_ref, index) in self._to_push.iteritems():
- remote = gd.get_remote('origin')
- head_ref = gd.disambiguate_ref(gd.HEAD)
+ head_ref = gd.HEAD
+ upstream_ref = gd.get_upstream_of_branch(head_ref)
+ if upstream_ref is None:
+ yield gd
+ continue
head_sha1 = gd.resolve_ref_to_commit(head_ref)
- pushed_refs = sorted(
- (remote_ref
- for remote_sha1, remote_ref in remote.ls()
- # substring match of refs, since ref may be a tag,
- # in which case it would end with ^{}
- if remote_sha1 == head_sha1 and head_ref in remote_ref),
- key=len)
- if not pushed_refs:
+ upstream_sha1 = gd.resolve_ref_to_commit(upstream_ref)
+ if head_sha1 != upstream_sha1:
yield gd
def push_build_branches(self, push_cb=lambda **kwargs: None):
diff --git a/morphlib/gitdir.py b/morphlib/gitdir.py
index 40ac643..9fef4f1 100644
--- a/morphlib/gitdir.py
+++ b/morphlib/gitdir.py
@@ -515,6 +515,22 @@ class GitDirectory(object):
else:
return 'refs/heads/' + ref
+ def get_upstream_of_branch(self, branch): # pragma: no cover
+ try:
+ out = morphlib.git.gitcmd(
+ self._runcmd, 'rev-parse', '--abbrev-ref',
+ '%s@{upstream}' % branch).strip()
+ return out
+ except cliapp.AppException as e:
+ emsg = str(e)
+ if 'does not point to a branch' in emsg:
+ # ref wasn't a branch, can't have upstream
+ # treat it the same as no upstream for convenience
+ return None
+ elif 'No upstream configured for branch' in emsg:
+ return None
+ raise
+
def resolve_ref_to_commit(self, ref):
return self._rev_parse('%s^{commit}' % ref)