Merge branch 'sr/remote-helper-export'
* sr/remote-helper-export: t5800: testgit helper requires Python support Makefile: Simplify handling of python scripts remote-helpers: add tests for testgit helper remote-helpers: add testgit helper remote-helpers: add support for an export command remote-helpers: allow requesing the path to the .git directory fast-import: always create marks_file directories clone: also configure url for bare clones clone: pass the remote name to remote_get Conflicts: Makefile
This commit is contained in:
51
git_remote_helpers/git/exporter.py
Normal file
51
git_remote_helpers/git/exporter.py
Normal file
@ -0,0 +1,51 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
class GitExporter(object):
|
||||
"""An exporter for testgit repositories.
|
||||
|
||||
The exporter simply delegates to git fast-export.
|
||||
"""
|
||||
|
||||
def __init__(self, repo):
|
||||
"""Creates a new exporter for the specified repo.
|
||||
"""
|
||||
|
||||
self.repo = repo
|
||||
|
||||
def export_repo(self, base):
|
||||
"""Exports a fast-export stream for the given directory.
|
||||
|
||||
Simply delegates to git fast-epxort and pipes it through sed
|
||||
to make the refs show up under the prefix rather than the
|
||||
default refs/heads. This is to demonstrate how the export
|
||||
data can be stored under it's own ref (using the refspec
|
||||
capability).
|
||||
"""
|
||||
|
||||
dirname = self.repo.get_base_path(base)
|
||||
path = os.path.abspath(os.path.join(dirname, 'testgit.marks'))
|
||||
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
|
||||
print "feature relative-marks"
|
||||
if os.path.exists(os.path.join(dirname, 'git.marks')):
|
||||
print "feature import-marks=%s/git.marks" % self.repo.hash
|
||||
print "feature export-marks=%s/git.marks" % self.repo.hash
|
||||
sys.stdout.flush()
|
||||
|
||||
args = ["git", "--git-dir=" + self.repo.gitpath, "fast-export", "--export-marks=" + path]
|
||||
|
||||
if os.path.exists(path):
|
||||
args.append("--import-marks=" + path)
|
||||
|
||||
args.append("HEAD")
|
||||
|
||||
p1 = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
|
||||
args = ["sed", "s_refs/heads/_" + self.repo.prefix + "_g"]
|
||||
|
||||
subprocess.check_call(args, stdin=p1.stdout)
|
38
git_remote_helpers/git/importer.py
Normal file
38
git_remote_helpers/git/importer.py
Normal file
@ -0,0 +1,38 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
class GitImporter(object):
|
||||
"""An importer for testgit repositories.
|
||||
|
||||
This importer simply delegates to git fast-import.
|
||||
"""
|
||||
|
||||
def __init__(self, repo):
|
||||
"""Creates a new importer for the specified repo.
|
||||
"""
|
||||
|
||||
self.repo = repo
|
||||
|
||||
def do_import(self, base):
|
||||
"""Imports a fast-import stream to the given directory.
|
||||
|
||||
Simply delegates to git fast-import.
|
||||
"""
|
||||
|
||||
dirname = self.repo.get_base_path(base)
|
||||
if self.repo.local:
|
||||
gitdir = self.repo.gitpath
|
||||
else:
|
||||
gitdir = os.path.abspath(os.path.join(dirname, '.git'))
|
||||
path = os.path.abspath(os.path.join(dirname, 'git.marks'))
|
||||
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
|
||||
args = ["git", "--git-dir=" + gitdir, "fast-import", "--quiet", "--export-marks=" + path]
|
||||
|
||||
if os.path.exists(path):
|
||||
args.append("--import-marks=" + path)
|
||||
|
||||
subprocess.check_call(args)
|
61
git_remote_helpers/git/non_local.py
Normal file
61
git_remote_helpers/git/non_local.py
Normal file
@ -0,0 +1,61 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from git_remote_helpers.util import die, warn
|
||||
|
||||
|
||||
class NonLocalGit(object):
|
||||
"""Handler to interact with non-local repos.
|
||||
"""
|
||||
|
||||
def __init__(self, repo):
|
||||
"""Creates a new non-local handler for the specified repo.
|
||||
"""
|
||||
|
||||
self.repo = repo
|
||||
|
||||
def clone(self, base):
|
||||
"""Clones the non-local repo to base.
|
||||
|
||||
Does nothing if a clone already exists.
|
||||
"""
|
||||
|
||||
path = os.path.join(self.repo.get_base_path(base), '.git')
|
||||
|
||||
# already cloned
|
||||
if os.path.exists(path):
|
||||
return path
|
||||
|
||||
os.makedirs(path)
|
||||
args = ["git", "clone", "--bare", "--quiet", self.repo.gitpath, path]
|
||||
|
||||
subprocess.check_call(args)
|
||||
|
||||
return path
|
||||
|
||||
def update(self, base):
|
||||
"""Updates checkout of the non-local repo in base.
|
||||
"""
|
||||
|
||||
path = os.path.join(self.repo.get_base_path(base), '.git')
|
||||
|
||||
if not os.path.exists(path):
|
||||
die("could not find repo at %s", path)
|
||||
|
||||
args = ["git", "--git-dir=" + path, "fetch", "--quiet", self.repo.gitpath]
|
||||
subprocess.check_call(args)
|
||||
|
||||
args = ["git", "--git-dir=" + path, "update-ref", "refs/heads/master", "FETCH_HEAD"]
|
||||
subprocess.check_call(args)
|
||||
|
||||
def push(self, base):
|
||||
"""Pushes from the non-local repo to base.
|
||||
"""
|
||||
|
||||
path = os.path.join(self.repo.get_base_path(base), '.git')
|
||||
|
||||
if not os.path.exists(path):
|
||||
die("could not find repo at %s", path)
|
||||
|
||||
args = ["git", "--git-dir=" + path, "push", "--quiet", self.repo.gitpath]
|
||||
subprocess.check_call(args)
|
70
git_remote_helpers/git/repo.py
Normal file
70
git_remote_helpers/git/repo.py
Normal file
@ -0,0 +1,70 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def sanitize(rev, sep='\t'):
|
||||
"""Converts a for-each-ref line to a name/value pair.
|
||||
"""
|
||||
|
||||
splitrev = rev.split(sep)
|
||||
branchval = splitrev[0]
|
||||
branchname = splitrev[1].strip()
|
||||
if branchname.startswith("refs/heads/"):
|
||||
branchname = branchname[11:]
|
||||
|
||||
return branchname, branchval
|
||||
|
||||
def is_remote(url):
|
||||
"""Checks whether the specified value is a remote url.
|
||||
"""
|
||||
|
||||
prefixes = ["http", "file", "git"]
|
||||
|
||||
return any(url.startswith(i) for i in prefixes)
|
||||
|
||||
class GitRepo(object):
|
||||
"""Repo object representing a repo.
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
"""Initializes a new repo at the given path.
|
||||
"""
|
||||
|
||||
self.path = path
|
||||
self.head = None
|
||||
self.revmap = {}
|
||||
self.local = not is_remote(self.path)
|
||||
|
||||
if(self.path.endswith('.git')):
|
||||
self.gitpath = self.path
|
||||
else:
|
||||
self.gitpath = os.path.join(self.path, '.git')
|
||||
|
||||
if self.local and not os.path.exists(self.gitpath):
|
||||
os.makedirs(self.gitpath)
|
||||
|
||||
def get_revs(self):
|
||||
"""Fetches all revs from the remote.
|
||||
"""
|
||||
|
||||
args = ["git", "ls-remote", self.gitpath]
|
||||
path = ".cached_revs"
|
||||
ofile = open(path, "w")
|
||||
|
||||
subprocess.check_call(args, stdout=ofile)
|
||||
output = open(path).readlines()
|
||||
self.revmap = dict(sanitize(i) for i in output)
|
||||
if "HEAD" in self.revmap:
|
||||
del self.revmap["HEAD"]
|
||||
self.revs = self.revmap.keys()
|
||||
ofile.close()
|
||||
|
||||
def get_head(self):
|
||||
"""Determines the head of a local repo.
|
||||
"""
|
||||
|
||||
if not self.local:
|
||||
return
|
||||
|
||||
path = os.path.join(self.gitpath, "HEAD")
|
||||
head = open(path).readline()
|
||||
self.head, _ = sanitize(head, ' ')
|
Reference in New Issue
Block a user