예제 #1
0
파일: svn.py 프로젝트: srwalter/yap
    def cmd_svn(self, subcmd):
	"enable"

	if subcmd not in ["enable"]:
	    raise TypeError

	if "svn" in [x[0] for x in self._list_remotes()]:
	    raise YapError("A remote named 'svn' already exists")


        if not run_command("git config svn-remote.svn.branches"):
            raise YapError("Cannot currently enable in a repository with svn branches")

        url = get_output("git config svn-remote.svn.url")
        if not url:
            raise YapError("Not a git-svn repository?")
        fetch = get_output("git config svn-remote.svn.fetch")
        assert fetch
        lhs, rhs = fetch[0].split(':')


        rev = get_output("git rev-parse %s" % rhs)
        assert rev
        run_safely("git update-ref refs/remotes/svn/trunk %s" % rev[0])

        url = '/'.join((url[0], lhs))
        self._configure_repo(url)
        run_safely("git update-ref -d %s %s" % (rhs, rev[0]))
예제 #2
0
파일: svn.py 프로젝트: srwalter/yap
    def _create_tagged_blob(self):
	keys = dict()
	for i in get_output("git config --list | grep ^svn-remote."):
	    k, v = i.split('=')
	    keys[k] = v
	blob = RepoBlob(keys)
	for b in get_output("git for-each-ref --format='%(refname)' 'refs/remotes/svn'"):
	    b = b.replace('refs/remotes/svn/', '')
	    blob.add_metadata(b)

	fd_w, fd_r = os.popen2("git hash-object -w --stdin")
	pickle.dump(blob, fd_w)
	fd_w.close()
	hash = fd_r.readline().strip()
	run_safely("git tag -f yap-svn %s" % hash)
예제 #3
0
파일: svn.py 프로젝트: srwalter/yap
    def add_metadata(self, branch):
	assert branch not in self.metadata
	gitdir = get_output("git rev-parse --git-dir")
	assert gitdir
	revmap = os.path.join(gitdir[0], "svn", "svn", branch, ".rev_map*")
	revmap = glob.glob(revmap)
	if not revmap:
	    return
	uuid = revmap[0].split('.')[-1]
	if self.uuid is None:
	    self.uuid = uuid
	assert self.uuid == uuid
	rev = get_output("git rev-parse refs/remotes/svn/%s" % branch)
	data = file(revmap[0]).read()
	self.metadata[branch] = rev[0], data
예제 #4
0
파일: tcommit.py 프로젝트: srwalter/yap
    def cmd_switch(self, *args, **flags):
	super(TCommitPlugin, self).cmd_switch(*args, **flags)

        branch = get_output("git symbolic-ref HEAD")
        if branch[0] in self._get_branches():
            self.cmd_uncommit()
            self._remove_branch(branch[0])
예제 #5
0
파일: workdir.py 프로젝트: srwalter/yap
    def _lock_branch(self, branch, locked_by):
        repo = get_output('git rev-parse --git-dir')[0]
        dir = os.path.join(repo, 'yap', 'lock')
        try:
            os.makedirs(dir)
        except OSError:
            pass

        fd, tmplock = tempfile.mkstemp("yap", dir=dir)
	try:
	    os.write(fd, locked_by)
	    os.close(fd)
	    while True:
		lockfile = os.path.join(dir, branch.replace('/', '\/'))
		try:
		    os.link(tmplock, lockfile)
		    break
		except OSError, e:
		    try:
			fd = file(lockfile)
		    except:
			raise e
		    user = fd.readline()
		    # If the workdir has been deleted, break his lock
		    if os.access(user, os.R_OK):
			raise YapError("That branch is being used by an existing workdir")
		    os.unlink(lockfile)
		    continue
	finally:
	    os.unlink(tmplock)
예제 #6
0
파일: tcommit.py 프로젝트: srwalter/yap
    def _get_branches(self):
        repo = get_output("git rev-parse --git-dir")
        state_file = os.path.join(repo[0], 'yap', 'tcommit')

        try:
            b = pickle.load(file(state_file))
        except IOError:
            b = set()
        return b
예제 #7
0
파일: tcommit.py 프로젝트: srwalter/yap
    def _remove_branch(self, branch):
        repo = get_output("git rev-parse --git-dir")
        if not repo:
            return
        state_file = os.path.join(repo[0], 'yap', 'tcommit')

        b = self._get_branches()
        b.remove(branch)
        pickle.dump(b, file(state_file, 'w'))
예제 #8
0
파일: svn.py 프로젝트: srwalter/yap
    def _unlock_svn(self):
	repo = get_output('git rev-parse --git-dir')[0]
	dir = os.path.join(repo, 'yap')
	lockfile = os.path.join(dir, 'svn-lock')

	try:
	    os.unlink(lockfile)
	except OSError:
	    pass
예제 #9
0
파일: workdir.py 프로젝트: srwalter/yap
    def cmd_workdir(self, branch, workdir=None):
        "<branch> [workdir]"

        self._check_git()

        branches = get_output("git for-each-ref --format='%(refname)' 'refs/heads'")
        if 'refs/heads/%s' % branch not in branches:
            raise YapError("Not a branch: %s" % branch)

        current = get_output("git symbolic-ref HEAD")[0]
	repodir = self._get_repodir()
	repo = os.path.join(repodir, '.git')
        if workdir is None:
            repoparent, reponame = os.path.split(repodir)
            workdir = os.path.join(repoparent, "%s-%s" % (reponame, branch))

        # Make sure the current branch is locked
        try:
            self._lock_branch(current.replace('refs/heads/', ''), repodir)
        except:
            pass

        self._lock_branch(branch, workdir)
	# If we fail after this point, unlock the branch
	try:
	    try:
		os.mkdir(workdir)
	    except OSError, e:
		raise YapError("Can't create new workdir: %s (%s)" % (workdir, e))

	    os.chdir(workdir)
	    os.mkdir(".git")
	    os.chdir(".git")

	    for x in ["config", "refs", "logs/refs", "objects", "info",
		      "hooks", "packed-refs", "remotes", "yap", "svn"]:
		if os.path.dirname(x):
		    os.makedirs(os.path.dirname(x))
		os.symlink(os.path.join(repo, x), x)

	    run_safely("cp %s HEAD" % os.path.join(repo, 'HEAD'))
	    os.chdir("..")
	    run_safely("git symbolic-ref HEAD refs/heads/%s" % branch)
	    self.cmd_revert(**{'-a': 1})
예제 #10
0
파일: svn.py 프로젝트: srwalter/yap
    def _resolve_svn_rev(self, revnum):
	rev = None
	gitdir = get_output("git rev-parse --git-dir")
	assert gitdir

	# Work with whateven svn remote is configured
	remotes = get_output("git config --get-regexp 'svn-remote.*.fetch'")
	assert remotes

	revmaps = []
	for remote in remotes:
	    remote = remote.split(' ')
	    remote = remote[1].split(':')
            refspec = remote[1]
	    remote = remote[1].split('/')
	    remote = remote[2]
	    path = os.path.join(gitdir[0], "svn", remote,
		    "*", ".rev_map*")
	    revmaps += glob.glob(path)

	    path = os.path.join(gitdir[0], "svn", refspec, ".rev_map*")
	    revmaps += glob.glob(path)

	for f in revmaps:
	    rm = SVNRevMap(f)
	    idx = bisect.bisect_left(rm, revnum)
	    if idx >= len(rm) or rm[idx] != revnum:
		continue

	    revnum, rev = rm.get_record(idx)
	    if rev == "0" * 40:
		continue
	    break

	if not rev:
	    rev = get_output("git svn find-rev r%d 2>/dev/null" % revnum)
	if not rev:
	    rev = None
	return rev
예제 #11
0
파일: workdir.py 프로젝트: srwalter/yap
    def _unlock_branch(self, branch):
        repo = get_output('git rev-parse --git-dir')[0]
        dir = os.path.join(repo, 'yap', 'lock')
        try:
            os.makedirs(dir)
        except OSError:
            pass

        lockfile = os.path.join(dir, branch.replace('/', '\/'))

        try:
            os.unlink(lockfile)
        except OSError:
            pass
예제 #12
0
파일: tcommit.py 프로젝트: srwalter/yap
    def cmd_commit(self, *args, **flags):
        if '-t' in flags:
	    override = True
	    args = []
	    flags = {'-a': 1, '-m': 'yap wip'}
	else:
	    override = False

	super(TCommitPlugin, self).cmd_commit(*args, **flags)

	if override is True:
            branch = get_output("git symbolic-ref HEAD")
            if branch:
                self._add_branch(branch[0])
예제 #13
0
파일: svn.py 프로젝트: srwalter/yap
    def _lock_svn(self):
	repo = get_output('git rev-parse --git-dir')[0]
	dir = os.path.join(repo, 'yap')
	fd, tmplock = tempfile.mkstemp("yap", dir=dir)
	try:
	    os.close(fd)

	    lockfile = os.path.join(dir, 'svn-lock')
	    try:
		os.link(tmplock, lockfile)
	    except OSError:
		raise YapError("A subversion operation is already in progress")
	finally:
	    os.unlink(tmplock)
예제 #14
0
파일: tcommit.py 프로젝트: srwalter/yap
    def _add_branch(self, branch):
        repo = get_output("git rev-parse --git-dir")
        if not repo:
            return
        dir = os.path.join(repo[0], 'yap')
	try:
	    os.mkdir(dir)
	except OSError:
	    pass
        state_file = os.path.join(dir, 'tcommit')

        b = self._get_branches()
        b.add(branch)
        pickle.dump(b, file(state_file, 'w'))
예제 #15
0
파일: svn.py 프로젝트: srwalter/yap
    def _filter_log(self, commit):
        commit = super(SvnPlugin, self)._filter_log(commit)

        new = []
        for line in commit:
            if line.strip().startswith("git-svn-id:"):
                while not new[-1].strip():
                    new = new[:-1]

                urlrev = line.strip().split(' ')[1]
                url, rev = urlrev.split('@')
		m = re.search("commit ([0-9a-f]+)", commit[0])
		if m is None:
		    continue
		hash = m.group(1)
		if self._svn_next_rev != hash:
		    h2 = self._resolve_svn_rev(int(rev))
		    if h2 != hash:
			continue

		next_hash = get_output("git rev-parse --verify %s^ 2>/dev/null" % hash)
		if next_hash:
		    self._svn_next_rev = next_hash[0]
		else:
		    self._svn_next_rev = None
                root = get_output("git config svn-remote.svn.url")
                assert root
                url = url.replace(root[0], '')

		if stdout_is_tty():
		    new.insert(1, "\033[32mSubversion: r%s %s\033[0m\n" % (rev, url))
		else:
		    new.insert(1, "Subversion: r%s %s\n" % (rev, url))

                continue
            new.append(line)
        return new
예제 #16
0
파일: workdir.py 프로젝트: srwalter/yap
    def cmd_switch(self, branch, *args, **flags):
        self._check_git()

        current = get_output("git symbolic-ref HEAD")[0]

	repodir = self._get_repodir()
        self._lock_branch(branch, repodir)

        try:
            super(WorkdirPlugin, self).cmd_switch(branch, *args, **flags)
        except:
            self._unlock_branch(branch)
            raise

        self._unlock_branch(current.replace('refs/heads/', ''))
예제 #17
0
파일: svn.py 프로젝트: srwalter/yap
    def _cleanup_branches(self):
	for b in get_output("git for-each-ref --format='%(refname)' 'refs/remotes/svn/*@*'"):
	    head = b.replace('refs/remotes/svn/', '')
	    path = os.path.join(".git", "svn", "svn", head)
            try:
                files = os.listdir(path)
                for f in files:
                    os.unlink(os.path.join(path, f))
                os.rmdir(path)
            except OSError:
                pass

	    path = os.path.join(".git", "svn", "refs", "remotes", "svn", head)
            try:
                files = os.listdir(path)
                for f in files:
                    os.unlink(os.path.join(path, f))
                os.rmdir(path)
            except OSError:
                pass

	    ref = get_output("git rev-parse %s" % b)
	    if ref:
		run_safely("git update-ref -d %s %s" % (b, ref[0]))
예제 #18
0
파일: svn.py 프로젝트: srwalter/yap
    def cmd_clone(self, *args, **flags):
	handled = True
	if not args:
	    handled = False
	if (handled and not args[0].startswith("http")
	 	    and not args[0].startswith("svn")
                    and not args[0].startswith("file://")):
	    handled = False
	if handled and run_command("svn info %s" % args[0]):
	    handled = False

	if handled:
            self._clone_svn(*args, **flags)
	else:
            super(SvnPlugin, self).cmd_clone(*args, **flags)

	if self._enabled():
	    # nothing to do
	    return

	run_safely("git fetch origin --tags")
	hash = get_output("git rev-parse --verify refs/tags/yap-svn 2>/dev/null")
	if not hash:
	    return

	fd = os.popen("git cat-file blob %s" % hash[0])
	blob = pickle.load(fd)
	for k, v in blob.keys.items():
	    run_safely("git config %s %s" % (k, v))

        self.cmd_repo("svn", blob.keys['svn-remote.svn.url'])
        os.system("git config yap.svn.enabled 1")
	run_safely("git fetch origin 'refs/remotes/svn/*:refs/remotes/svn/*'")

	for b in blob.metadata.keys():
	    branch = os.path.join(".git", "svn", "svn", b)
	    os.makedirs(branch)
	    fd = file(os.path.join(branch, ".rev_map.%s" % blob.uuid), "w")
	    rev, metadata = blob.metadata[b]
	    fd.write(metadata)

	    branch = os.path.join(".git", "svn", "refs", "remotes", "svn", b)
	    os.makedirs(branch)
	    fd = file(os.path.join(branch, ".rev_map.%s" % blob.uuid), "w")
	    rev, metadata = blob.metadata[b]
	    fd.write(metadata)

	    run_command("git update-ref refs/remotes/svn/%s %s" % (b, rev))
예제 #19
0
파일: svn.py 프로젝트: srwalter/yap
    def cmd_push(self, *args, **flags):
	if self._applicable(args):
	    if len (args) >= 2:
		merge = args[1]
	    else:
                current = get_output("git symbolic-ref HEAD")
                if not current:
                    raise YapError("Not on a branch!")

                current = current[0].replace('refs/heads/', '')
                remote, merge = self._get_tracking(current)
		if remote != "svn":
		    raise YapError("Need a branch name")
	    self._push_svn(merge, **flags)
	    return
	super(SvnPlugin, self).cmd_push(*args, **flags)
예제 #20
0
파일: svn.py 프로젝트: srwalter/yap
    def _applicable(self, args):
	if not self._enabled():
	    return False

	if args and args[0] == 'svn':
	    return True

	if not args:
	    current = get_output("git symbolic-ref HEAD")
	    if not current:
		raise YapError("Not on a branch!")

	    current = current[0].replace('refs/heads/', '')
	    remote, merge = self._get_tracking(current)
	    if remote == "svn":
		return True
	
	return False
예제 #21
0
파일: svn.py 프로젝트: srwalter/yap
 def _get_root(self, url):
     root = get_output("svn info %s 2>/dev/null | gawk '/Repository Root:/{print $3}'" % url)
     if not root:
         raise YapError("Not an SVN repo: %s" % url)
     return root[0]
예제 #22
0
파일: svn.py 프로젝트: srwalter/yap
    def _enabled(self):
	enabled = get_output("git config yap.svn.enabled")
	return bool(enabled)
예제 #23
0
파일: svn.py 프로젝트: srwalter/yap
    def _push_svn(self, branch, **flags):
        if '-d' in flags:
            raise YapError("Deleting svn branches not supported")
	print "Verifying branch is up-to-date"
        run_safely("git svn fetch svn")

        branch = branch.replace('refs/heads/', '')
	rev = get_output("git rev-parse --verify refs/remotes/svn/%s" % branch)

        # Create the branch if requested
        if not rev:
            if '-c' not in flags:
                raise YapError("No matching branch on the repo.  Use -c to create a new branch there.")
            src  = get_output("git svn info | gawk '/URL:/{print $2}'")[0]
            brev = get_output("git svn info | gawk '/Revision:/{print $2}'")[0]
            root = get_output("git config svn-remote.svn.url")[0]
            branch_path = get_output("git config svn-remote.svn.branches")[0].split(':')[0]
            branch_path = branch_path.rstrip('/*')
            dst = '/'.join((root, branch_path, branch))

            # Create the branch in svn
            run_safely("svn cp -r%s %s %s -m 'create branch %s'"
                    % (brev, src, dst, branch))
            run_safely("git svn fetch svn")
            rev = get_output("git rev-parse refs/remotes/svn/%s 2>/dev/null" % branch)
            base = get_output("git svn find-rev r%s" % brev)

            # Apply our commits to the new branch
            try:
                fd, tmpfile = tempfile.mkstemp("yap")
                os.close(fd)
                os.system("git format-patch -k --stdout '%s' > %s"
                        % (base[0], tmpfile))
                start = get_output("git rev-parse HEAD")
                self.cmd_point("refs/remotes/svn/%s"
                        % branch, **{'-f': True})

                stat = os.stat(tmpfile)
                size = stat[6]
                if size > 0:
                    rc = run_command("git am -3 %s" % tmpfile)
                    if (rc):
                        self.cmd_point(start[0], **{'-f': True})
                        raise YapError("Failed to port changes to new svn branch")
            finally:
                os.unlink(tmpfile)

	base = get_output("git merge-base HEAD %s" % rev[0])
	if base[0] != rev[0]:
	    raise YapError("Branch not up-to-date.  Update first.")
	current = get_output("git symbolic-ref HEAD")
	if not current:
	    raise YapError("Not on a branch!")
	current = current[0].replace('refs/heads/', '')
	self._confirm_push(current, branch, "svn")
	if run_command("git update-index --refresh"):
	    raise YapError("Can't push with uncommitted changes")

	master = get_output("git rev-parse --verify refs/heads/master 2>/dev/null")
	os.system("git svn dcommit")
	run_safely("git svn rebase")
	if not master:
	    master = get_output("git rev-parse --verify refs/heads/master 2>/dev/null")
	    if master:
		run_safely("git update-ref -d refs/heads/master %s" % master[0])
예제 #24
0
파일: workdir.py 프로젝트: srwalter/yap
    def _get_repodir(self):
        repo = get_output('git rev-parse --git-dir')[0]
	if not repo.startswith('/'):
	    repo = os.path.join(os.getcwd(), repo)
        repodir = os.path.dirname(repo)
	return repodir