vcssync: helper function to ensure a Git commit present locally (
bug 1357597); r?glob
It allows us to perform a fetch without using remotes. This isn't a
common practice in Git land and the syntax for `git fetch` is a bit
wonky. So it is best to abstract it away.
Plus, we can avoid network I/O if the given commit is present
locally.
MozReview-Commit-ID: 6pn2b5Iao9i
--- a/vcssync/mozvcssync/gitutil.py
+++ b/vcssync/mozvcssync/gitutil.py
@@ -63,16 +63,41 @@ def setup_local_clone(path, url, git=Non
if not os.path.exists(path):
if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path))
logger.info('cloning %s to %s' % (url, path))
git.cmd('clone', url, path)
+def ensure_revision_present(repo, revision, fetch_url, fetch_ref, local_ref):
+ """Ensure a Git revision is present in a repo.
+
+ Given a ``dulwich.repo.Repo`` and a ``revision``, ensure that revision is
+ present in the local repo.
+
+ If it is, this operation no-ops.
+
+ If the revision isn't present or isn't defined, ``fetch_ref`` will be
+ fetched from ``fetch_url`` and stored in ``local_ref``. After the fetch,
+ we verify that the requested revision is present locally (if defined).
+ """
+ if revision and revision in repo:
+ return
+
+ logger.warn('fetching %s from %s' % (fetch_ref, fetch_url))
+ subprocess.check_call(
+ [b'git', b'fetch', b'--no-tags', fetch_url,
+ b'+refs/heads/%s:%s' % (fetch_ref, local_ref)],
+ cwd=repo.path)
+
+ if revision and revision not in repo:
+ raise Exception('revision %s not found after fetch' % revision)
+
+
def update_git_refs(repo, reason, *actions):
"""Update Git refs via reflog writes.
Accepts a ``dulwich.repo.Repo``, a bytes ``reason`` describing why this
was done, and 1 or more tuples describing the update to perform. Tuples
have the form:
('update', ref, new_id, old_id)