6 git-svn - bidirectional operation between Subversion and git
10 'git-svn' <command> [options] [arguments]
14 git-svn is a simple conduit for changesets between Subversion and git.
15 It is not to be confused with gitlink:git-svnimport[1], which is
16 read-only and geared towards tracking multiple branches.
18 git-svn was originally designed for an individual developer who wants a
19 bidirectional flow of changesets between a single branch in Subversion
20 and an arbitrary number of branches in git. Since its inception,
21 git-svn has gained the ability to track multiple branches in a manner
22 similar to git-svnimport; but it cannot (yet) automatically detect new
23 branches and tags like git-svnimport does.
25 git-svn is especially useful when it comes to tracking repositories
26 not organized in the way Subversion developers recommend (trunk,
27 branches, tags directories).
34 Creates an empty git repository with additional metadata
35 directories for git-svn. The Subversion URL must be specified
36 as a command-line argument. Optionally, the target directory
37 to operate on can be specified as a second argument. Normally
38 this command initializes the current directory.
42 Fetch unfetched revisions from the Subversion URL we are
43 tracking. refs/remotes/git-svn will be updated to the
46 Note: You should never attempt to modify the remotes/git-svn
47 branch outside of git-svn. Instead, create a branch from
48 remotes/git-svn and work on that branch. Use the 'dcommit'
49 command (see below) to write git commits back to
52 See '<<fetch-args,Additional Fetch Arguments>>' if you are interested in
53 manually joining branches on commit.
56 Commit all diffs from a specified head directly to the SVN
57 repository, and then rebase or reset (depending on whether or
58 not there is a diff between SVN and head). It is recommended
59 that you run git-svn fetch and rebase (not pull) your commits
60 against the latest changes in the SVN repository.
61 An optional command-line argument may be specified as an
63 This is advantageous over 'set-tree' (below) because it produces
64 cleaner, more linear history.
67 This should make it easy to look up svn log messages when svn
68 users refer to -r/--revision numbers.
70 The following features from `svn log' are supported:
72 --revision=<n>[:<n>] - is supported, non-numeric args are not:
73 HEAD, NEXT, BASE, PREV, etc ...
74 -v/--verbose - it's not completely compatible with
75 the --verbose output in svn log, but
77 --limit=<n> - is NOT the same as --max-count,
78 doesn't count merged/excluded commits
79 --incremental - supported
83 --show-commit - shows the git commit sha1, as well
84 --oneline - our version of --pretty=oneline
86 Any other arguments are passed directly to `git log'
89 You should consider using 'dcommit' instead of this command.
90 Commit specified commit or tree objects to SVN. This relies on
91 your imported fetch data being up-to-date. This makes
92 absolutely no attempts to do patching when committing to SVN, it
93 simply overwrites files with those specified in the tree or
94 commit. All merging is assumed to have taken place
95 independently of git-svn functions.
98 Not a part of daily usage, but this is a useful command if
99 you've just cloned a repository (using gitlink:git-clone[1]) that was
100 tracked with git-svn. Unfortunately, git-clone does not clone
101 git-svn metadata and the svn working tree that git-svn uses for
102 its operations. This rebuilds the metadata so git-svn can
103 resume fetch operations. A Subversion URL may be optionally
104 specified at the command-line if the directory/repository you're
105 tracking has moved or changed protocols.
108 Recursively finds and lists the svn:ignore property on
109 directories. The output is suitable for appending to
110 the $GIT_DIR/info/exclude file.
113 Commits the diff of two tree-ish arguments from the
114 command-line. This command is intended for interopability with
115 git-svnimport and does not rely on being inside an git-svn
116 init-ed repository. This command takes three arguments, (a) the
117 original tree to diff against, (b) the new tree result, (c) the
118 URL of the target Subversion repository. The final argument
119 (URL) may be omitted if you are working from a git-svn-aware
120 repository (that has been init-ed with git-svn).
121 The -r<revision> option is required for this.
124 This command attempts to detect merges/branches from already
125 imported history. Techniques used currently include regexes,
126 file copies, and tree-matches). This command generates (or
127 modifies) the $GIT_DIR/info/grafts file. This command is
128 considered experimental, and inherently flawed because
129 merge-tracking in SVN is inherently flawed and inconsistent
130 across different repositories.
133 This command supports git-svnimport-like command-line syntax for
134 importing repositories that are layed out as recommended by the
135 SVN folks. This is a bit more tolerant than the git-svnimport
136 command-line syntax and doesn't require the user to figure out
137 where the repository URL ends and where the repository path
141 This runs fetch on all known SVN branches we're tracking. This
142 will NOT discover new branches (unlike git-svnimport), so
143 multi-init will need to be re-run (it's idempotent).
152 --template=<template_directory>::
153 Only used with the 'init' command.
154 These are passed directly to gitlink:git-init-db[1].
159 Only used with the 'fetch' command.
161 Takes any valid -r<argument> svn would accept and passes it
162 directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax
163 is also supported. This is passed directly to svn, see svn
164 documentation for more details.
166 This can allow you to make partial mirrors when running fetch.
171 Only used with the 'set-tree' command.
173 Read a list of commits from stdin and commit them in reverse
174 order. Only the leading sha1 is read from each line, so
175 git-rev-list --pretty=oneline output can be used.
179 Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
181 Remove directories from the SVN tree if there are no files left
182 behind. SVN can version empty directories, and they are not
183 removed by default if there are no files left in them. git
184 cannot version empty directories. Enabling this flag will make
185 the commit to SVN act like git.
187 repo-config key: svn.rmdir
192 Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
194 Edit the commit message before committing to SVN. This is off by
195 default for objects that are commits, and forced on when committing
198 repo-config key: svn.edit
201 --find-copies-harder::
203 Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands.
205 They are both passed directly to git-diff-tree see
206 gitlink:git-diff-tree[1] for more information.
209 repo-config key: svn.l
210 repo-config key: svn.findcopiesharder
213 --authors-file=<filename>::
215 Syntax is compatible with the files used by git-svnimport and
218 ------------------------------------------------------------------------
219 loginname = Joe User <user@example.com>
220 ------------------------------------------------------------------------
222 If this option is specified and git-svn encounters an SVN
223 committer name that does not exist in the authors-file, git-svn
224 will abort operation. The user will then have to add the
225 appropriate entry. Re-running the previous git-svn command
226 after the authors-file is modified should continue operation.
228 repo-config key: svn.authorsfile
232 Make git-svn less verbose. This only affects git-svn if you
233 have the SVN::* libraries installed and are using them.
236 --repack-flags=<flags>
237 These should help keep disk usage sane for large fetches
240 --repack takes an optional argument for the number of revisions
241 to fetch before repacking. This defaults to repacking every
242 1000 commits fetched if no argument is specified.
244 --repack-flags are passed directly to gitlink:git-repack[1].
246 repo-config key: svn.repack
247 repo-config key: svn.repackflags
252 --strategy=<strategy>::
254 These are only used with the 'dcommit' command.
256 Passed directly to git-rebase when using 'dcommit' if a
257 'git-reset' cannot be used (see dcommit).
262 This is only used with the 'dcommit' command.
264 Print out the series of git arguments that would show
265 which diffs would be committed to SVN.
275 Used with 'fetch', 'dcommit' or 'set-tree'.
277 This can be used to join arbitrary git branches to remotes/git-svn
278 on new commits where the tree object is equivalent.
280 When used with different GIT_SVN_ID values, tags and branches in
281 SVN can be tracked this way, as can some merges where the heads
282 end up having completely equivalent content. This can even be
283 used to track branches across multiple SVN _repositories_.
285 This option may be specified multiple times, once for each
288 repo-config key: svn.branch
293 This sets GIT_SVN_ID (instead of using the environment). See the
295 '<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
296 for more information on using GIT_SVN_ID.
299 This is especially helpful when we're tracking a directory
300 that has been moved around within the repository, or if we
301 started tracking a branch and never tracked the trunk it was
304 This relies on the SVN::* libraries to work.
306 repo-config key: svn.followparent
309 This gets rid of the git-svn-id: lines at the end of every commit.
311 With this, you lose the ability to use the rebuild command. If
312 you ever lose your .git/svn/git-svn/.rev_db file, you won't be
313 able to fetch again, either. This is fine for one-shot imports.
315 The 'git-svn log' command will not work on repositories using this,
318 repo-config key: svn.nometadata
322 COMPATIBILITY OPTIONS
323 ---------------------
327 Only used with the 'rebuild' command.
329 Run this if you used an old version of git-svn that used
330 "git-svn-HEAD" instead of "remotes/git-svn" as the branch
331 for tracking the remote.
333 --no-ignore-externals::
334 Only used with the 'fetch' and 'rebuild' command.
336 This command has no effect when you are using the SVN::*
337 libraries with git, svn:externals are always avoided.
339 By default, git-svn passes --ignore-externals to svn to avoid
340 fetching svn:external trees into git. Pass this flag to enable
341 externals tracking directly via git.
343 Versions of svn that do not support --ignore-externals are
344 automatically detected and this flag will be automatically
347 Otherwise, do not enable this flag unless you know what you're
350 repo-config key: svn.noignoreexternals
353 Only used with the 'fetch' command.
355 By default git-svn will crash if it tries to import a revision
356 from SVN which has '(no date)' listed as the date of the revision.
357 This is repository corruption on SVN's part, plain and simple.
358 But sometimes you really need those revisions anyway.
360 If supplied git-svn will convert '(no date)' entries to the UNIX
361 epoch (midnight on Jan. 1, 1970). Yes, that's probably very wrong.
369 Tracking and contributing to a the trunk of a Subversion-managed project:
371 ------------------------------------------------------------------------
372 # Initialize a repo (like git init-db):
373 git-svn init http://svn.foo.org/project/trunk
374 # Fetch remote revisions:
376 # Create your own branch to hack on:
377 git checkout -b my-branch remotes/git-svn
378 # Do some work, and then commit your new changes to SVN, as well as
379 # automatically updating your working HEAD:
381 # Something is committed to SVN, rebase the latest into your branch:
382 git-svn fetch && git rebase remotes/git-svn
383 # Append svn:ignore settings to the default git exclude file:
384 git-svn show-ignore >> .git/info/exclude
385 ------------------------------------------------------------------------
387 Tracking and contributing to an entire Subversion-managed project
388 (complete with a trunk, tags and branches):
390 '<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
392 ------------------------------------------------------------------------
393 # Initialize a repo (like git init-db):
394 git-svn multi-init http://svn.foo.org/project \
395 -T trunk -b branches -t tags
396 # Fetch remote revisions:
398 # Create your own branch of trunk to hack on:
399 git checkout -b my-trunk remotes/trunk
400 # Do some work, and then commit your new changes to SVN, as well as
401 # automatically updating your working HEAD:
402 git-svn dcommit -i trunk
403 # Something has been committed to trunk, rebase the latest into your branch:
404 git-svn multi-fetch && git rebase remotes/trunk
405 # Append svn:ignore settings of trunk to the default git exclude file:
406 git-svn show-ignore -i trunk >> .git/info/exclude
407 # Check for new branches and tags (no arguments are needed):
409 ------------------------------------------------------------------------
414 Originally, git-svn recommended that the remotes/git-svn branch be
415 pulled from. This is because the author favored 'git-svn set-tree B'
416 to commit a single head rather than the 'git-svn set-tree A..B' notation
417 to commit multiple commits.
419 If you use 'git-svn set-tree A..B' to commit several diffs and you do not
420 have the latest remotes/git-svn merged into my-branch, you should use
421 'git rebase' to update your work branch instead of 'git pull'. 'pull'
422 can cause non-linear history to be flattened when committing into SVN,
423 which can lead to merge commits reversing previous commits in SVN.
427 Merge tracking in Subversion is lacking and doing branched development
428 with Subversion is cumbersome as a result. git-svn does not do
429 automated merge/branch tracking by default and leaves it entirely up to
430 the user on the git side.
432 [[tracking-multiple-repos]]
433 TRACKING MULTIPLE REPOSITORIES OR BRANCHES
434 ------------------------------------------
435 Because git-svn does not care about relationships between different
436 branches or directories in a Subversion repository, git-svn has a simple
437 hack to allow it to track an arbitrary number of related _or_ unrelated
438 SVN repositories via one git repository. Simply use the --id/-i flag or
439 set the GIT_SVN_ID environment variable to a name other other than
440 "git-svn" (the default) and git-svn will ignore the contents of the
441 $GIT_DIR/svn/git-svn directory and instead do all of its work in
442 $GIT_DIR/svn/$GIT_SVN_ID for that invocation. The interface branch will
443 be remotes/$GIT_SVN_ID, instead of remotes/git-svn. Any
444 remotes/$GIT_SVN_ID branch should never be modified by the user outside
448 ADDITIONAL FETCH ARGUMENTS
449 --------------------------
450 This is for advanced users, most users should ignore this section.
452 Unfetched SVN revisions may be imported as children of existing commits
453 by specifying additional arguments to 'fetch'. Additional parents may
454 optionally be specified in the form of sha1 hex sums at the
455 command-line. Unfetched SVN revisions may also be tied to particular
456 git commits with the following syntax:
458 ------------------------------------------------
459 svn_revision_number=git_commit_sha1
460 ------------------------------------------------
462 This allows you to tie unfetched SVN revision 375 to your current HEAD:
464 ------------------------------------------------
465 git-svn fetch 375=$(git-rev-parse HEAD)
466 ------------------------------------------------
468 Advanced Example: Tracking a Reorganized Repository
469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
470 Note: this example is now obsolete if you have SVN::* libraries
471 installed. Simply use --follow-parent when fetching.
473 If you're tracking a directory that has moved, or otherwise been
474 branched or tagged off of another directory in the repository and you
475 care about the full history of the project, then you can read this
478 This is how Yann Dirson tracked the trunk of the ufoai directory when
479 the /trunk directory of his repository was moved to /ufoai/trunk and
480 he needed to continue tracking /ufoai/trunk where /trunk left off.
482 ------------------------------------------------------------------------
483 # This log message shows when the repository was reorganized:
484 r166 | ydirson | 2006-03-02 01:36:55 +0100 (Thu, 02 Mar 2006) | 1 line
487 A /ufoai/trunk (from /trunk:165)
489 # First we start tracking the old revisions:
490 GIT_SVN_ID=git-oldsvn git-svn init \
491 https://svn.sourceforge.net/svnroot/ufoai/trunk
492 GIT_SVN_ID=git-oldsvn git-svn fetch -r1:165
494 # And now, we continue tracking the new revisions:
495 GIT_SVN_ID=git-newsvn git-svn init \
496 https://svn.sourceforge.net/svnroot/ufoai/ufoai/trunk
497 GIT_SVN_ID=git-newsvn git-svn fetch \
498 166=`git-rev-parse refs/remotes/git-oldsvn`
499 ------------------------------------------------------------------------
504 If you are not using the SVN::* Perl libraries and somebody commits a
505 conflicting changeset to SVN at a bad moment (right before you commit)
506 causing a conflict and your commit to fail, your svn working tree
507 ($GIT_DIR/git-svn/tree) may be dirtied. The easiest thing to do is
508 probably just to rm -rf $GIT_DIR/git-svn/tree and run 'rebuild'. You
509 can avoid this problem entirely by using 'dcommit'.
511 We ignore all SVN properties except svn:executable. Too difficult to
512 map them since we rely heavily on git write-tree being _exactly_ the
513 same on both the SVN and git working trees and I prefer not to clutter
514 working trees with metadata files.
516 Renamed and copied directories are not detected by git and hence not
517 tracked when committing to SVN. I do not plan on adding support for
518 this as it's quite difficult and time-consuming to get working for all
519 the possible corner cases (git doesn't do it, either). Renamed and
520 copied files are fully supported if they're similar enough for git to
525 gitlink:git-rebase[1]
529 Written by Eric Wong <normalperson@yhbt.net>.
533 Written by Eric Wong <normalperson@yhbt.net>.