diff --git a/git-auto-svn b/git-auto-svn
new file mode 100755
index 000000000..b7da01492
--- /dev/null
+++ b/git-auto-svn
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# git_map_branches.py -- a git-command for presenting a graphical view of git
+# branches in the current repo, and their relationships to each other.
+
+. $(type -P python_git_runner.sh)
diff --git a/git_auto_svn.py b/git_auto_svn.py
new file mode 100755
index 000000000..8a35143c5
--- /dev/null
+++ b/git_auto_svn.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Performs all git-svn setup steps necessary for 'git svn dcommit' to work.
+
+Assumes that trunk of the svn remote maps to master of the git remote.
+
+Example:
+git clone https://chromium.googlesource.com/chromium/tools/depot_tools
+cd depot_tools
+git auto-svn
+"""
+
+import argparse
+import os
+import sys
+import urlparse
+
+import subprocess2
+
+from git_common import run as run_git
+from git_common import run_stream as run_git_stream
+from git_common import set_config, root, ROOT
+from git_footers import parse_footers, get_unique, GIT_SVN_ID_PATTERN
+
+
+SVN_EXE = ROOT+'\\svn.bat' if sys.platform.startswith('win') else 'svn'
+
+
+def run_svn(*cmd, **kwargs):
+ """Runs an svn command.
+
+ Returns (stdout, stderr) as a pair of strings.
+
+ Raises subprocess2.CalledProcessError on nonzero return code.
+ """
+ kwargs.setdefault('stdin', subprocess2.PIPE)
+ kwargs.setdefault('stdout', subprocess2.PIPE)
+ kwargs.setdefault('stderr', subprocess2.PIPE)
+
+ cmd = (SVN_EXE,) + cmd
+ proc = subprocess2.Popen(cmd, **kwargs)
+ ret, err = proc.communicate()
+ retcode = proc.wait()
+ if retcode != 0:
+ raise subprocess2.CalledProcessError(retcode, cmd, os.getcwd(), ret, err)
+
+ return ret, err
+
+
+def main(argv):
+ # No command line flags. Just use the parser to prevent people from trying
+ # to pass flags that don't do anything, and to provide 'usage'.
+ parser = argparse.ArgumentParser(
+ description='Automatically set up git-svn for a repo mirrored from svn.')
+ parser.parse_args(argv[1:])
+
+ upstream = root()
+ message = run_git('log', '-1', '--format=%B', upstream)
+ footers = parse_footers(message)
+ git_svn_id = get_unique(footers, 'git-svn-id')
+ match = GIT_SVN_ID_PATTERN.match(git_svn_id)
+ assert match, 'No valid git-svn-id footer found on %s.' % upstream
+ print 'Found git-svn-id footer %s on %s' % (match.group(1), upstream)
+
+ parsed_svn = urlparse.urlparse(match.group(1))
+ path_components = parsed_svn.path.split('/')
+ svn_repo = None
+ svn_path = None
+ for i in xrange(len(path_components)):
+ try:
+ maybe_repo = '%s://%s%s' % (
+ parsed_svn.scheme, parsed_svn.netloc, '/'.join(path_components[:i+1]))
+ print 'Checking ', maybe_repo
+ run_svn('info', maybe_repo)
+ svn_repo = maybe_repo
+ svn_path = '/'.join(path_components[i+1:])
+ break
+ except subprocess2.CalledProcessError:
+ continue
+ assert svn_repo is not None, 'Unable to find svn repo for %s' % match.group(1)
+ print 'Found upstream svn repo %s and path %s' % (svn_repo, svn_path)
+
+ prefix = upstream.rsplit('/')[0]
+ run_git('svn', 'init', '--prefix=%s' % prefix, '-T', svn_path, svn_repo)
+ set_config('svn-remote.svn.fetch',
+ '%s:refs/remotes/%s' % (svn_path, upstream))
+ print 'Configured metadata, running "git svn fetch". This may take some time.'
+ for line in run_git_stream('svn', 'fetch').xreadlines():
+ print line.strip()
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/git_common.py b/git_common.py
index 2e268da0f..99ed53cc4 100644
--- a/git_common.py
+++ b/git_common.py
@@ -319,15 +319,6 @@ def branches(*args):
yield line.split()[-1]
-def run_with_retcode(*cmd, **kwargs):
- """Run a command but only return the status code."""
- try:
- run(*cmd, **kwargs)
- return 0
- except subprocess2.CalledProcessError as cpe:
- return cpe.returncode
-
-
def config(option, default=None):
try:
return run('config', '--get', option) or default
@@ -551,6 +542,15 @@ def run(*cmd, **kwargs):
return run_with_stderr(*cmd, **kwargs)[0]
+def run_with_retcode(*cmd, **kwargs):
+ """Run a command but only return the status code."""
+ try:
+ run(*cmd, **kwargs)
+ return 0
+ except subprocess2.CalledProcessError as cpe:
+ return cpe.returncode
+
+
def run_stream(*cmd, **kwargs):
"""Runs a git command. Returns stdout as a PIPE (file-like object).
@@ -600,6 +600,7 @@ def set_branch_config(branch, option, value, scope='local'):
def set_config(option, value, scope='local'):
run('config', '--' + scope, option, value)
+
def squash_current_branch(header=None, merge_base=None):
header = header or 'git squash commit.'
merge_base = merge_base or get_or_create_merge_base(current_branch())
@@ -723,6 +724,7 @@ def upstream(branch):
except subprocess2.CalledProcessError:
return None
+
def get_git_version():
"""Returns a tuple that contains the numeric components of the current git
version."""
diff --git a/git_footers.py b/git_footers.py
index 6e8136b35..fe72e18a9 100755
--- a/git_footers.py
+++ b/git_footers.py
@@ -11,10 +11,12 @@ from collections import defaultdict
import git_common as git
+
FOOTER_PATTERN = re.compile(r'^\s*([\w-]+): (.*)$')
CHROME_COMMIT_POSITION_PATTERN = re.compile(r'^([\w/-]+)@{#(\d+)}$')
GIT_SVN_ID_PATTERN = re.compile('^([^\s@]+)@(\d+)')
+
def normalize_name(header):
return '-'.join([ word.title() for word in header.strip().split('-') ])
diff --git a/man/html/git-auto-svn.html b/man/html/git-auto-svn.html
new file mode 100644
index 000000000..24445d033
--- /dev/null
+++ b/man/html/git-auto-svn.html
@@ -0,0 +1,837 @@
+
+
+
+
+
+git-auto-svn(1)
+
+
+
+
+
+
+
+
+
DESCRIPTION
+
+
git auto-svn
automatically sets up git-svn metadata and runs git-svn fetch for
+repos that are homed in SVN but mirrored to Git (such as depot_tools itself).
+
It determines the metadata to use by inspecting the git-svn-id
footer of the
+HEAD of the remote upstream ref (by default, origin/master
). git-svn-id
+footers look like this:
+
+
+
git-svn-id: svn://some.host.org/repo/path/to/a/sub/folder@123456 0039d316-1c4b-4281-b951-d872f2087c98
+
+
git auto-svn
extracts the repository url
+(svn://some.host.org/repo/path/to/a/sub/folder) from the git-svn-id
, and
+splits it into the root repository (svn://some.host.org/repo) and the path
+within that repository (/path/to/a/sub/folder).
+
It then sets up the following stanza in .git/config:
+
+
+
[svn-remote "svn"]
+ url = svn://some.host.org/repo
+ fetch = path/to/a/sub/folder:refs/remotes/origin/master
+
+
Finally, it runs git svn fetch
to pull in the data from the svn remote.
+
+
+
+
CONFIGURATION VARIABLES
+
+
+
svn-remote.svn.url
+
This is the url of the root of the remote svn repository.
+
+
+
svn-remote.svn.fetch
+
This looks like a git refspec, but maps a subdirectory of the svn repository
+to a single ref in the git remote.
+
+
+
+
+
EXAMPLE
+
+
+
+
git clone https://chromium.googlesource.com/chromium/tools/depot_tools
+cd depot_tools
+git auto-svn
+
+
This results in the following stanza in depot_tools/.git/config
:
+
+
+
[svn-remote "svn"]
+ url = svn://svn.chromium.org/chrome
+ fetch = trunk/tools/depot_tools:refs/remotes/origin/master
+
+
+
+
+
+
+
Part of the chromium depot_tools(7) suite. These tools are meant to
+assist with the development of chromium and related projects. Download the tools
+from here.
+
+
+
+
+
+
+
diff --git a/man/man1/git-auto-svn.1 b/man/man1/git-auto-svn.1
new file mode 100644
index 000000000..84e238bb4
--- /dev/null
+++ b/man/man1/git-auto-svn.1
@@ -0,0 +1,113 @@
+'\" t
+.\" Title: git-auto-svn
+.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
+.\" Generator: DocBook XSL Stylesheets v1.78.1
+.\" Date: 09/30/2014
+.\" Manual: Chromium depot_tools Manual
+.\" Source: depot_tools 2bbacdc
+.\" Language: English
+.\"
+.TH "GIT\-AUTO\-SVN" "1" "09/30/2014" "depot_tools 2bbacdc" "Chromium depot_tools Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+git-auto-svn \- Automatically set up git\-svn metadata for a repo mirrored from SVN\&.
+.SH "SYNOPSIS"
+.sp
+.nf
+\fIgit auto\-svn\fR
+.fi
+.sp
+.SH "DESCRIPTION"
+.sp
+git auto\-svn automatically sets up git\-svn metadata and runs git\-svn fetch for repos that are homed in SVN but mirrored to Git (such as depot_tools itself)\&.
+.sp
+It determines the metadata to use by inspecting the git\-svn\-id footer of the HEAD of the remote upstream ref (by default, origin/master)\&. git\-svn\-id footers look like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+git\-svn\-id: svn://some\&.host\&.org/repo/path/to/a/sub/folder@123456 0039d316\-1c4b\-4281\-b951\-d872f2087c98
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+git auto\-svn extracts the repository url (svn://some\&.host\&.org/repo/path/to/a/sub/folder) from the git\-svn\-id, and splits it into the root repository (svn://some\&.host\&.org/repo) and the path within that repository (/path/to/a/sub/folder)\&.
+.sp
+It then sets up the following stanza in \&.git/config:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[svn\-remote "svn"]
+ url = svn://some\&.host\&.org/repo
+ fetch = path/to/a/sub/folder:refs/remotes/origin/master
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Finally, it runs git svn fetch to pull in the data from the svn remote\&.
+.SH "CONFIGURATION VARIABLES"
+.SS "svn\-remote\&.svn\&.url"
+.sp
+This is the url of the root of the remote svn repository\&.
+.SS "svn\-remote\&.svn\&.fetch"
+.sp
+This looks like a git refspec, but maps a subdirectory of the svn repository to a single ref in the git remote\&.
+.SH "EXAMPLE"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+git clone https://chromium\&.googlesource\&.com/chromium/tools/depot_tools
+cd depot_tools
+git auto\-svn
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This results in the following stanza in depot_tools/\&.git/config:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[svn\-remote "svn"]
+ url = svn://svn\&.chromium\&.org/chrome
+ fetch = trunk/tools/depot_tools:refs/remotes/origin/master
+.fi
+.if n \{\
+.RE
+.\}
+.SH "CHROMIUM DEPOT_TOOLS"
+.sp
+Part of the chromium \fBdepot_tools\fR(7) suite\&. These tools are meant to assist with the development of chromium and related projects\&. Download the tools from \m[blue]\fBhere\fR\m[]\&\s-2\u[1]\d\s+2\&.
+.SH "NOTES"
+.IP " 1." 4
+here
+.RS 4
+\%https://chromium.googlesource.com/chromium/tools/depot_tools.git
+.RE
diff --git a/man/src/_git-auto-svn_desc.helper.txt b/man/src/_git-auto-svn_desc.helper.txt
new file mode 100644
index 000000000..eabe443d7
--- /dev/null
+++ b/man/src/_git-auto-svn_desc.helper.txt
@@ -0,0 +1 @@
+Automatically set up git-svn metadata for a repo mirrored from SVN.
diff --git a/man/src/git-auto-svn.txt b/man/src/git-auto-svn.txt
new file mode 100644
index 000000000..9aa780d33
--- /dev/null
+++ b/man/src/git-auto-svn.txt
@@ -0,0 +1,69 @@
+git-auto-svn(1)
+===============
+
+NAME
+----
+git-auto-svn -
+include::_git-auto-svn_desc.helper.txt[]
+
+SYNOPSIS
+--------
+[verse]
+'git auto-svn'
+
+DESCRIPTION
+-----------
+
+`git auto-svn` automatically sets up git-svn metadata and runs git-svn fetch for
+repos that are homed in SVN but mirrored to Git (such as depot_tools itself).
+
+It determines the metadata to use by inspecting the `git-svn-id` footer of the
+HEAD of the remote upstream ref (by default, `origin/master`). `git-svn-id`
+footers look like this:
+
+ git-svn-id: svn://some.host.org/repo/path/to/a/sub/folder@123456 0039d316-1c4b-4281-b951-d872f2087c98
+
+`git auto-svn` extracts the repository url
+(svn://some.host.org/repo/path/to/a/sub/folder) from the `git-svn-id`, and
+splits it into the root repository (svn://some.host.org/repo) and the path
+within that repository (/path/to/a/sub/folder).
+
+It then sets up the following stanza in .git/config:
+
+ [svn-remote "svn"]
+ url = svn://some.host.org/repo
+ fetch = path/to/a/sub/folder:refs/remotes/origin/master
+
+Finally, it runs `git svn fetch` to pull in the data from the svn remote.
+
+CONFIGURATION VARIABLES
+-----------------------
+
+svn-remote.svn.url
+~~~~~~~~~~~~~~~~~~
+
+This is the url of the root of the remote svn repository.
+
+svn-remote.svn.fetch
+~~~~~~~~~~~~~~~~~~~~
+
+This looks like a git refspec, but maps a subdirectory of the svn repository
+to a single ref in the git remote.
+
+EXAMPLE
+-------
+
+ git clone https://chromium.googlesource.com/chromium/tools/depot_tools
+ cd depot_tools
+ git auto-svn
+
+This results in the following stanza in `depot_tools/.git/config`:
+
+ [svn-remote "svn"]
+ url = svn://svn.chromium.org/chrome
+ fetch = trunk/tools/depot_tools:refs/remotes/origin/master
+
+
+include::_footer.txt[]
+
+// vim: ft=asciidoc:
diff --git a/man/src/make_docs.sh b/man/src/make_docs.sh
index 73d76e248..d7af87d77 100755
--- a/man/src/make_docs.sh
+++ b/man/src/make_docs.sh
@@ -23,6 +23,7 @@ ensure_in_path() {
}
ensure_in_path xmlto
+ensure_in_path hg
DFLT_CATALOG_PATH="/usr/local/etc/xml/catalog"
if [[ ! $XML_CATALOG_FILES && -f "$DFLT_CATALOG_PATH" ]]