git-svnimport: support for incremental import
[git/repo.git] / Documentation / git-svn.txt
blobf754d2f679b0f77c85767de8b45f089d441e4c4d
1 git-svn(1)
2 ==========
4 NAME
5 ----
6 git-svn - bidirectional operation between Subversion and git
8 SYNOPSIS
9 --------
10 'git-svn' <command> [options] [arguments]
12 DESCRIPTION
13 -----------
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).
29 COMMANDS
30 --------
33 'init'::
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.
40 'fetch'::
42 Fetch unfetched revisions from the Subversion URL we are
43 tracking.  refs/remotes/git-svn will be updated to the
44 latest revision.
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
50 remotes/git-svn.
52 See '<<fetch-args,Additional Fetch Arguments>>' if you are interested in
53 manually joining branches on commit.
55 'dcommit'::
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
62         alternative to HEAD.
63         This is advantageous over 'set-tree' (below) because it produces
64         cleaner, more linear history.
66 'log'::
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
76                                reasonably close.
77         --limit=<n>          - is NOT the same as --max-count,
78                                doesn't count merged/excluded commits
79         --incremental        - supported
81         New features:
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'
88 'set-tree'::
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.
97 'rebuild'::
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.
107 'show-ignore'::
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.
112 'commit-diff'::
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.
123 'graft-branches'::
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.
132 'multi-init'::
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
138         begins.
140 'multi-fetch'::
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).
147 OPTIONS
148 -------
151 --shared::
152 --template=<template_directory>::
153         Only used with the 'init' command.
154         These are passed directly to gitlink:git-init-db[1].
156 -r <ARG>::
157 --revision <ARG>::
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.
169 --stdin::
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.
177 --rmdir::
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
189 -e::
190 --edit::
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
196 tree objects.
198 repo-config key: svn.edit
200 -l<num>::
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.
208 [verse]
209 repo-config key: svn.l
210 repo-config key: svn.findcopiesharder
212 -A<filename>::
213 --authors-file=<filename>::
215 Syntax is compatible with the files used by git-svnimport and
216 git-cvsimport:
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
230 -q::
231 --quiet::
232         Make git-svn less verbose.  This only affects git-svn if you
233         have the SVN::* libraries installed and are using them.
235 --repack[=<n>]::
236 --repack-flags=<flags>
237         These should help keep disk usage sane for large fetches
238         with many revisions.
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
249 -m::
250 --merge::
251 -s<strategy>::
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).
259 -n::
260 --dry-run::
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.
269 ADVANCED OPTIONS
270 ----------------
273 -b<refname>::
274 --branch <refname>::
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
286 branch.
288 repo-config key: svn.branch
290 -i<GIT_SVN_ID>::
291 --id <GIT_SVN_ID>::
293 This sets GIT_SVN_ID (instead of using the environment).  See the
294 section on
295 '<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
296 for more information on using GIT_SVN_ID.
298 --follow-parent::
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
302         descended from.
304         This relies on the SVN::* libraries to work.
306 repo-config key: svn.followparent
308 --no-metadata::
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,
316         either.
318 repo-config key: svn.nometadata
322 COMPATIBILITY OPTIONS
323 ---------------------
326 --upgrade::
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
345 enabled for them.
347 Otherwise, do not enable this flag unless you know what you're
348 doing.
350 repo-config key: svn.noignoreexternals
352 --ignore-nodate::
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.
362 SVN was very wrong.
366 Basic Examples
367 ~~~~~~~~~~~~~~
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:
375         git-svn fetch
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:
380         git-svn dcommit
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):
389 See also:
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:
397         git-svn multi-fetch
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):
408         git-svn multi-init
409 ------------------------------------------------------------------------
411 REBASE VS. PULL
412 ---------------
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.
425 DESIGN PHILOSOPHY
426 -----------------
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
445 of git-svn commands.
447 [[fetch-args]]
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
476 section.
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
485         Changed paths:
486            D /trunk
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 ------------------------------------------------------------------------
501 BUGS
502 ----
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
521 detect them.
523 SEE ALSO
524 --------
525 gitlink:git-rebase[1]
527 Author
528 ------
529 Written by Eric Wong <normalperson@yhbt.net>.
531 Documentation
532 -------------
533 Written by Eric Wong <normalperson@yhbt.net>.