| git-svn(1) |
| ========== |
| |
| NAME |
| ---- |
| git-svn - Bidirectional operation between a single Subversion branch and git |
| |
| SYNOPSIS |
| -------- |
| 'git-svn' <command> [options] [arguments] |
| |
| DESCRIPTION |
| ----------- |
| git-svn is a simple conduit for changesets between Subversion and git. |
| It is not to be confused with gitlink:git-svnimport[1], which is |
| read-only. |
| |
| git-svn was originally designed for an individual developer who wants a |
| bidirectional flow of changesets between a single branch in Subversion |
| and an arbitrary number of branches in git. Since its inception, |
| git-svn has gained the ability to track multiple branches in a manner |
| similar to git-svnimport. |
| |
| git-svn is especially useful when it comes to tracking repositories |
| not organized in the way Subversion developers recommend (trunk, |
| branches, tags directories). |
| |
| COMMANDS |
| -------- |
| -- |
| |
| 'init':: |
| Initializes an empty git repository with additional |
| metadata directories for git-svn. The Subversion URL |
| may be specified as a command-line argument, or as full |
| URL arguments to -T/-t/-b. Optionally, the target |
| directory to operate on can be specified as a second |
| argument. Normally this command initializes the current |
| directory. |
| |
| -T<trunk_subdir>:: |
| --trunk=<trunk_subdir>:: |
| -t<tags_subdir>:: |
| --tags=<tags_subdir>:: |
| -b<branches_subdir>:: |
| --branches=<branches_subdir>:: |
| These are optional command-line options for init. Each of |
| these flags can point to a relative repository path |
| (--tags=project/tags') or a full url |
| (--tags=https://foo.org/project/tags) |
| |
| --prefix=<prefix> |
| This allows one to specify a prefix which is prepended |
| to the names of remotes if trunk/branches/tags are |
| specified. The prefix does not automatically include a |
| trailing slash, so be sure you include one in the |
| argument if that is what you want. This is useful if |
| you wish to track multiple projects that share a common |
| repository. |
| |
| 'fetch':: |
| |
| Fetch unfetched revisions from the Subversion remote we are |
| tracking. The name of the [svn-remote "..."] section in the |
| .git/config file may be specified as an optional command-line |
| argument. |
| |
| 'dcommit':: |
| Commit each diff from a specified head directly to the SVN |
| repository, and then rebase or reset (depending on whether or |
| not there is a diff between SVN and head). This will create |
| a revision in SVN for each commit in git. |
| It is recommended that you run git-svn fetch and rebase (not |
| pull or merge) your commits against the latest changes in the |
| SVN repository. |
| An optional command-line argument may be specified as an |
| alternative to HEAD. |
| This is advantageous over 'set-tree' (below) because it produces |
| cleaner, more linear history. |
| |
| 'log':: |
| This should make it easy to look up svn log messages when svn |
| users refer to -r/--revision numbers. |
| |
| The following features from `svn log' are supported: |
| |
| --revision=<n>[:<n>] - is supported, non-numeric args are not: |
| HEAD, NEXT, BASE, PREV, etc ... |
| -v/--verbose - it's not completely compatible with |
| the --verbose output in svn log, but |
| reasonably close. |
| --limit=<n> - is NOT the same as --max-count, |
| doesn't count merged/excluded commits |
| --incremental - supported |
| |
| New features: |
| |
| --show-commit - shows the git commit sha1, as well |
| --oneline - our version of --pretty=oneline |
| |
| Any other arguments are passed directly to `git log' |
| |
| 'set-tree':: |
| You should consider using 'dcommit' instead of this command. |
| Commit specified commit or tree objects to SVN. This relies on |
| your imported fetch data being up-to-date. This makes |
| absolutely no attempts to do patching when committing to SVN, it |
| simply overwrites files with those specified in the tree or |
| commit. All merging is assumed to have taken place |
| independently of git-svn functions. |
| |
| 'show-ignore':: |
| Recursively finds and lists the svn:ignore property on |
| directories. The output is suitable for appending to |
| the $GIT_DIR/info/exclude file. |
| |
| 'commit-diff':: |
| Commits the diff of two tree-ish arguments from the |
| command-line. This command is intended for interoperability with |
| git-svnimport and does not rely on being inside an git-svn |
| init-ed repository. This command takes three arguments, (a) the |
| original tree to diff against, (b) the new tree result, (c) the |
| URL of the target Subversion repository. The final argument |
| (URL) may be omitted if you are working from a git-svn-aware |
| repository (that has been init-ed with git-svn). |
| The -r<revision> option is required for this. |
| |
| -- |
| |
| OPTIONS |
| ------- |
| -- |
| |
| --shared[={false|true|umask|group|all|world|everybody}]:: |
| --template=<template_directory>:: |
| Only used with the 'init' command. |
| These are passed directly to gitlink:git-init[1]. |
| |
| -r <ARG>:: |
| --revision <ARG>:: |
| |
| Used with the 'fetch' command. |
| |
| This allows revision ranges for partial/cauterized history |
| to be supported. $NUMBER, $NUMBER1:$NUMBER2 (numeric ranges), |
| $NUMBER:HEAD, and BASE:$NUMBER are all supported. |
| |
| This can allow you to make partial mirrors when running fetch; |
| but is generally not recommended because history will be skipped |
| and lost. |
| |
| -:: |
| --stdin:: |
| |
| Only used with the 'set-tree' command. |
| |
| Read a list of commits from stdin and commit them in reverse |
| order. Only the leading sha1 is read from each line, so |
| git-rev-list --pretty=oneline output can be used. |
| |
| --rmdir:: |
| |
| Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. |
| |
| Remove directories from the SVN tree if there are no files left |
| behind. SVN can version empty directories, and they are not |
| removed by default if there are no files left in them. git |
| cannot version empty directories. Enabling this flag will make |
| the commit to SVN act like git. |
| |
| config key: svn.rmdir |
| |
| -e:: |
| --edit:: |
| |
| Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. |
| |
| Edit the commit message before committing to SVN. This is off by |
| default for objects that are commits, and forced on when committing |
| tree objects. |
| |
| config key: svn.edit |
| |
| -l<num>:: |
| --find-copies-harder:: |
| |
| Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. |
| |
| They are both passed directly to git-diff-tree see |
| gitlink:git-diff-tree[1] for more information. |
| |
| [verse] |
| config key: svn.l |
| config key: svn.findcopiesharder |
| |
| -A<filename>:: |
| --authors-file=<filename>:: |
| |
| Syntax is compatible with the files used by git-svnimport and |
| git-cvsimport: |
| |
| ------------------------------------------------------------------------ |
| loginname = Joe User <user@example.com> |
| ------------------------------------------------------------------------ |
| |
| If this option is specified and git-svn encounters an SVN |
| committer name that does not exist in the authors-file, git-svn |
| will abort operation. The user will then have to add the |
| appropriate entry. Re-running the previous git-svn command |
| after the authors-file is modified should continue operation. |
| |
| config key: svn.authorsfile |
| |
| -q:: |
| --quiet:: |
| Make git-svn less verbose. |
| |
| --repack[=<n>]:: |
| --repack-flags=<flags> |
| These should help keep disk usage sane for large fetches |
| with many revisions. |
| |
| --repack takes an optional argument for the number of revisions |
| to fetch before repacking. This defaults to repacking every |
| 1000 commits fetched if no argument is specified. |
| |
| --repack-flags are passed directly to gitlink:git-repack[1]. |
| |
| config key: svn.repack |
| config key: svn.repackflags |
| |
| -m:: |
| --merge:: |
| -s<strategy>:: |
| --strategy=<strategy>:: |
| |
| These are only used with the 'dcommit' command. |
| |
| Passed directly to git-rebase when using 'dcommit' if a |
| 'git-reset' cannot be used (see dcommit). |
| |
| -n:: |
| --dry-run:: |
| |
| This is only used with the 'dcommit' command. |
| |
| Print out the series of git arguments that would show |
| which diffs would be committed to SVN. |
| |
| -- |
| |
| ADVANCED OPTIONS |
| ---------------- |
| -- |
| |
| -i<GIT_SVN_ID>:: |
| --id <GIT_SVN_ID>:: |
| |
| This sets GIT_SVN_ID (instead of using the environment). This |
| allows the user to override the default refname to fetch from |
| when tracking a single URL. The 'log' and 'dcommit' commands |
| no longer require this switch as an argument. |
| |
| -R<remote name>:: |
| --svn-remote <remote name>:: |
| Specify the [svn-remote "<remote name>"] section to use, |
| this allows SVN multiple repositories to be tracked. |
| Default: "svn" |
| |
| --follow-parent:: |
| This is especially helpful when we're tracking a directory |
| that has been moved around within the repository, or if we |
| started tracking a branch and never tracked the trunk it was |
| descended from. This feature is enabled by default, use |
| --no-follow-parent to disable it. |
| |
| config key: svn.followparent |
| |
| svn.noMetadata: |
| svn-remote.<name>.noMetadata: |
| This gets rid of the git-svn-id: lines at the end of every commit. |
| |
| If you lose your .git/svn/git-svn/.rev_db file, git-svn will not |
| be able to rebuild it and you won't be able to fetch again, |
| either. This is fine for one-shot imports. |
| |
| The 'git-svn log' command will not work on repositories using |
| this, either. Using this conflicts with the 'useSvmProps' |
| option for (hopefully) obvious reasons. |
| |
| svn.useSvmProps: |
| svn-remote.<name>.useSvmProps: |
| This allows git-svn to re-map repository URLs and UUIDs from |
| mirrors created using SVN::Mirror (or svk) for metadata. |
| |
| If an SVN revision has a property, "svm:headrev", it is likely |
| that the revision was created by SVN::Mirror (also used by SVK). |
| The property contains a repository UUID and a revision. We want |
| to make it look like we are mirroring the original URL, so |
| introduce a helper function that returns the original identity |
| URL and UUID, and use it when generating metadata in commit |
| messages. |
| |
| Using this conflicts with the 'noMetadata' option for |
| (hopefully) obvious reasons. |
| |
| -- |
| |
| Basic Examples |
| ~~~~~~~~~~~~~~ |
| |
| Tracking and contributing to a the trunk of a Subversion-managed project: |
| |
| ------------------------------------------------------------------------ |
| # Initialize a repo (like git init): |
| git-svn init http://svn.foo.org/project/trunk |
| # Fetch remote revisions: |
| git-svn fetch |
| # Create your own branch to hack on: |
| git checkout -b my-branch remotes/git-svn |
| # Do some work, and then commit your new changes to SVN, as well as |
| # automatically updating your working HEAD: |
| git-svn dcommit |
| # Something is committed to SVN, rebase the latest into your branch: |
| git-svn fetch && git rebase remotes/git-svn |
| # Append svn:ignore settings to the default git exclude file: |
| git-svn show-ignore >> .git/info/exclude |
| ------------------------------------------------------------------------ |
| |
| Tracking and contributing to an entire Subversion-managed project |
| (complete with a trunk, tags and branches): |
| |
| ------------------------------------------------------------------------ |
| # Initialize a repo (like git init): |
| git-svn init http://svn.foo.org/project -T trunk -b branches -t tags |
| # Fetch remote revisions: |
| git-svn fetch |
| # Create your own branch of trunk to hack on: |
| git checkout -b my-trunk remotes/trunk |
| # Do some work, and then commit your new changes to SVN, as well as |
| # automatically updating your working HEAD: |
| git-svn dcommit |
| # Something has been committed to trunk, rebase the latest into your branch: |
| git-svn fetch && git rebase remotes/trunk |
| # Append svn:ignore settings of trunk to the default git exclude file: |
| git-svn show-ignore -i trunk >> .git/info/exclude |
| ------------------------------------------------------------------------ |
| |
| REBASE VS. PULL/MERGE |
| --------------------- |
| |
| Originally, git-svn recommended that the remotes/git-svn branch be |
| pulled or merged from. This is because the author favored |
| 'git-svn set-tree B' to commit a single head rather than the |
| 'git-svn set-tree A..B' notation to commit multiple commits. |
| |
| If you use 'git-svn set-tree A..B' to commit several diffs and you do |
| not have the latest remotes/git-svn merged into my-branch, you should |
| use 'git rebase' to update your work branch instead of 'git pull' or |
| 'git merge'. 'pull/merge' can cause non-linear history to be flattened |
| when committing into SVN, which can lead to merge commits reversing |
| previous commits in SVN. |
| |
| DESIGN PHILOSOPHY |
| ----------------- |
| Merge tracking in Subversion is lacking and doing branched development |
| with Subversion is cumbersome as a result. git-svn does not do |
| automated merge/branch tracking by default and leaves it entirely up to |
| the user on the git side. git-svn does however follow copy |
| history of the directory that it is tracking, however (much like |
| how 'svn log' works). |
| |
| BUGS |
| ---- |
| |
| We ignore all SVN properties except svn:executable. Too difficult to |
| map them since we rely heavily on git write-tree being _exactly_ the |
| same on both the SVN and git working trees and I prefer not to clutter |
| working trees with metadata files. |
| |
| Renamed and copied directories are not detected by git and hence not |
| tracked when committing to SVN. I do not plan on adding support for |
| this as it's quite difficult and time-consuming to get working for all |
| the possible corner cases (git doesn't do it, either). Renamed and |
| copied files are fully supported if they're similar enough for git to |
| detect them. |
| |
| CONFIGURATION |
| ------------- |
| |
| git-svn stores [svn-remote] configuration information in the |
| repository .git/config file. It is similar the core git |
| [remote] sections except 'fetch' keys do not accept glob |
| arguments; but they are instead handled by the 'branches' |
| and 'tags' keys. Since some SVN repositories are oddly |
| configured with multiple projects glob expansions such those |
| listed below are allowed: |
| |
| ------------------------------------------------------------------------ |
| [svn-remote "project-a"] |
| url = http://server.org/svn |
| branches = branches/*/project-a:refs/remotes/project-a/branches/* |
| tags = tags/*/project-a:refs/remotes/project-a/tags/* |
| trunk = trunk/project-a:refs/remotes/project-a/trunk |
| ------------------------------------------------------------------------ |
| |
| Keep in mind that the '*' (asterisk) wildcard of the local ref |
| (left of the ':') *must* be the farthest right path component; |
| however the remote wildcard may be anywhere as long as it's own |
| independent path componet (surrounded by '/' or EOL). This |
| type of configuration is not automatically created by 'init' and |
| should be manually entered with a text-editor or using |
| gitlink:git-config[1] |
| |
| SEE ALSO |
| -------- |
| gitlink:git-rebase[1] |
| |
| Author |
| ------ |
| Written by Eric Wong <normalperson@yhbt.net>. |
| |
| Documentation |
| ------------- |
| Written by Eric Wong <normalperson@yhbt.net>. |