1git-svn(1) 2========== 3 4NAME 5---- 6git-svn - Bidirectional operation between a single Subversion branch and git 7 8SYNOPSIS 9-------- 10'git svn' <command> [options] [arguments] 11 12DESCRIPTION 13----------- 14'git-svn' is a simple conduit for changesets between Subversion and git. 15It provides a bidirectional flow of changes between a Subversion and a git 16repository. 17 18'git-svn' can track a single Subversion branch simply by using a 19URL to the branch, follow branches laid out in the Subversion recommended 20method (trunk, branches, tags directories) with the --stdlayout option, or 21follow branches in any layout with the -T/-t/-b options (see options to 22'init' below, and also the 'clone' command). 23 24Once tracking a Subversion branch (with any of the above methods), the git 25repository can be updated from Subversion by the 'fetch' command and 26Subversion updated from git by the 'dcommit' command. 27 28COMMANDS 29-------- 30-- 31 32'init':: 33 Initializes an empty git repository with additional 34 metadata directories for 'git-svn'. The Subversion URL 35 may be specified as a command-line argument, or as full 36 URL arguments to -T/-t/-b. Optionally, the target 37 directory to operate on can be specified as a second 38 argument. Normally this command initializes the current 39 directory. 40 41-T<trunk_subdir>;; 42--trunk=<trunk_subdir>;; 43-t<tags_subdir>;; 44--tags=<tags_subdir>;; 45-b<branches_subdir>;; 46--branches=<branches_subdir>;; 47-s;; 48--stdlayout;; 49 These are optional command-line options for init. Each of 50 these flags can point to a relative repository path 51 (--tags=project/tags') or a full url 52 (--tags=https://foo.org/project/tags). The option --stdlayout is 53 a shorthand way of setting trunk,tags,branches as the relative paths, 54 which is the Subversion default. If any of the other options are given 55 as well, they take precedence. 56--no-metadata;; 57 Set the 'noMetadata' option in the [svn-remote] config. 58--use-svm-props;; 59 Set the 'useSvmProps' option in the [svn-remote] config. 60--use-svnsync-props;; 61 Set the 'useSvnsyncProps' option in the [svn-remote] config. 62--rewrite-root=<URL>;; 63 Set the 'rewriteRoot' option in the [svn-remote] config. 64--use-log-author;; 65 When retrieving svn commits into git (as part of fetch, rebase, or 66 dcommit operations), look for the first From: or Signed-off-by: line 67 in the log message and use that as the author string. 68--add-author-from;; 69 When committing to svn from git (as part of commit or dcommit 70 operations), if the existing log message doesn't already have a 71 From: or Signed-off-by: line, append a From: line based on the 72 git commit's author string. If you use this, then --use-log-author 73 will retrieve a valid author string for all commits. 74--username=<USER>;; 75 For transports that SVN handles authentication for (http, 76 https, and plain svn), specify the username. For other 77 transports (eg svn+ssh://), you must include the username in 78 the URL, eg svn+ssh://foo@svn.bar.com/project 79--prefix=<prefix>;; 80 This allows one to specify a prefix which is prepended 81 to the names of remotes if trunk/branches/tags are 82 specified. The prefix does not automatically include a 83 trailing slash, so be sure you include one in the 84 argument if that is what you want. If --branches/-b is 85 specified, the prefix must include a trailing slash. 86 Setting a prefix is useful if you wish to track multiple 87 projects that share a common repository. 88 89'fetch':: 90 Fetch unfetched revisions from the Subversion remote we are 91 tracking. The name of the [svn-remote "..."] section in the 92 .git/config file may be specified as an optional command-line 93 argument. 94 95--localtime;; 96 Store Git commit times in the local timezone instead of UTC. This 97 makes 'git-log' (even without --date=local) show the same times 98 that `svn log` would in the local timezone. 99 100--parent;; 101 Fetch only from the SVN parent of the current HEAD. 102 103This doesn't interfere with interoperating with the Subversion 104repository you cloned from, but if you wish for your local Git 105repository to be able to interoperate with someone else's local Git 106repository, either don't use this option or you should both use it in 107the same local timezone. 108 109--ignore-paths=<regex>;; 110 This allows one to specify Perl regular expression that will 111 cause skipping of all matching paths from checkout from SVN. 112 Examples: 113 114 --ignore-paths="^doc" - skip "doc*" directory for every fetch. 115 116 --ignore-paths="^[^/]+/(?:branches|tags)" - skip "branches" 117 and "tags" of first level directories. 118 119 Regular expression is not persistent, you should specify 120 it every time when fetching. 121 122'clone':: 123 Runs 'init' and 'fetch'. It will automatically create a 124 directory based on the basename of the URL passed to it; 125 or if a second argument is passed; it will create a directory 126 and work within that. It accepts all arguments that the 127 'init' and 'fetch' commands accept; with the exception of 128 '--fetch-all'. After a repository is cloned, the 'fetch' 129 command will be able to update revisions without affecting 130 the working tree; and the 'rebase' command will be able 131 to update the working tree with the latest changes. 132 133'rebase':: 134 This fetches revisions from the SVN parent of the current HEAD 135 and rebases the current (uncommitted to SVN) work against it. 136 137This works similarly to `svn update` or 'git-pull' except that 138it preserves linear history with 'git-rebase' instead of 139'git-merge' for ease of dcommitting with 'git-svn'. 140 141This accepts all options that 'git-svn fetch' and 'git-rebase' 142accept. However, '--fetch-all' only fetches from the current 143[svn-remote], and not all [svn-remote] definitions. 144 145Like 'git-rebase'; this requires that the working tree be clean 146and have no uncommitted changes. 147 148-l;; 149--local;; 150 Do not fetch remotely; only run 'git-rebase' against the 151 last fetched commit from the upstream SVN. 152 153'dcommit':: 154 Commit each diff from a specified head directly to the SVN 155 repository, and then rebase or reset (depending on whether or 156 not there is a diff between SVN and head). This will create 157 a revision in SVN for each commit in git. 158 It is recommended that you run 'git-svn' fetch and rebase (not 159 pull or merge) your commits against the latest changes in the 160 SVN repository. 161 An optional command-line argument may be specified as an 162 alternative to HEAD. 163 This is advantageous over 'set-tree' (below) because it produces 164 cleaner, more linear history. 165+ 166--no-rebase;; 167 After committing, do not rebase or reset. 168--commit-url <URL>;; 169 Commit to this SVN URL (the full path). This is intended to 170 allow existing git-svn repositories created with one transport 171 method (e.g. `svn://` or `http://` for anonymous read) to be 172 reused if a user is later given access to an alternate transport 173 method (e.g. `svn+ssh://` or `https://`) for commit. 174 175config key: svn-remote.<name>.commiturl 176 177config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options) 178 179 Using this option for any other purpose (don't ask) 180 is very strongly discouraged. 181-- 182 183'branch':: 184 Create a branch in the SVN repository. 185 186-m;; 187--message;; 188 Allows to specify the commit message. 189 190-t;; 191--tag;; 192 Create a tag by using the tags_subdir instead of the branches_subdir 193 specified during git svn init. 194 195'tag':: 196 Create a tag in the SVN repository. This is a shorthand for 197 'branch -t'. 198 199'log':: 200 This should make it easy to look up svn log messages when svn 201 users refer to -r/--revision numbers. 202+ 203The following features from `svn log' are supported: 204+ 205-- 206--revision=<n>[:<n>];; 207 is supported, non-numeric args are not: 208 HEAD, NEXT, BASE, PREV, etc ... 209-v/--verbose;; 210 it's not completely compatible with the --verbose 211 output in svn log, but reasonably close. 212--limit=<n>;; 213 is NOT the same as --max-count, doesn't count 214 merged/excluded commits 215--incremental;; 216 supported 217-- 218+ 219New features: 220+ 221-- 222--show-commit;; 223 shows the git commit sha1, as well 224--oneline;; 225 our version of --pretty=oneline 226-- 227+ 228NOTE: SVN itself only stores times in UTC and nothing else. The regular svn 229client converts the UTC time to the local time (or based on the TZ= 230environment). This command has the same behaviour. 231+ 232Any other arguments are passed directly to 'git-log' 233 234'blame':: 235 Show what revision and author last modified each line of a file. The 236 output of this mode is format-compatible with the output of 237 `svn blame' by default. Like the SVN blame command, 238 local uncommitted changes in the working copy are ignored; 239 the version of the file in the HEAD revision is annotated. Unknown 240 arguments are passed directly to 'git-blame'. 241+ 242--git-format;; 243 Produce output in the same format as 'git-blame', but with 244 SVN revision numbers instead of git commit hashes. In this mode, 245 changes that haven't been committed to SVN (including local 246 working-copy edits) are shown as revision 0. 247 248-- 249'find-rev':: 250 When given an SVN revision number of the form 'rN', returns the 251 corresponding git commit hash (this can optionally be followed by a 252 tree-ish to specify which branch should be searched). When given a 253 tree-ish, returns the corresponding SVN revision number. 254 255'set-tree':: 256 You should consider using 'dcommit' instead of this command. 257 Commit specified commit or tree objects to SVN. This relies on 258 your imported fetch data being up-to-date. This makes 259 absolutely no attempts to do patching when committing to SVN, it 260 simply overwrites files with those specified in the tree or 261 commit. All merging is assumed to have taken place 262 independently of 'git-svn' functions. 263 264'create-ignore':: 265 Recursively finds the svn:ignore property on directories and 266 creates matching .gitignore files. The resulting files are staged to 267 be committed, but are not committed. Use -r/--revision to refer to a 268 specific revision. 269 270'show-ignore':: 271 Recursively finds and lists the svn:ignore property on 272 directories. The output is suitable for appending to 273 the $GIT_DIR/info/exclude file. 274 275'commit-diff':: 276 Commits the diff of two tree-ish arguments from the 277 command-line. This command does not rely on being inside an `git-svn 278 init`-ed repository. This command takes three arguments, (a) the 279 original tree to diff against, (b) the new tree result, (c) the 280 URL of the target Subversion repository. The final argument 281 (URL) may be omitted if you are working from a 'git-svn'-aware 282 repository (that has been `init`-ed with 'git-svn'). 283 The -r<revision> option is required for this. 284 285'info':: 286 Shows information about a file or directory similar to what 287 `svn info' provides. Does not currently support a -r/--revision 288 argument. Use the --url option to output only the value of the 289 'URL:' field. 290 291'proplist':: 292 Lists the properties stored in the Subversion repository about a 293 given file or directory. Use -r/--revision to refer to a specific 294 Subversion revision. 295 296'propget':: 297 Gets the Subversion property given as the first argument, for a 298 file. A specific revision can be specified with -r/--revision. 299 300'show-externals':: 301 Shows the Subversion externals. Use -r/--revision to specify a 302 specific revision. 303 304-- 305 306OPTIONS 307------- 308-- 309 310--shared[={false|true|umask|group|all|world|everybody}]:: 311--template=<template_directory>:: 312 Only used with the 'init' command. 313 These are passed directly to 'git-init'. 314 315-r <ARG>:: 316--revision <ARG>:: 317 318Used with the 'fetch' command. 319 320This allows revision ranges for partial/cauterized history 321to be supported. $NUMBER, $NUMBER1:$NUMBER2 (numeric ranges), 322$NUMBER:HEAD, and BASE:$NUMBER are all supported. 323 324This can allow you to make partial mirrors when running fetch; 325but is generally not recommended because history will be skipped 326and lost. 327 328-:: 329--stdin:: 330 331Only used with the 'set-tree' command. 332 333Read a list of commits from stdin and commit them in reverse 334order. Only the leading sha1 is read from each line, so 335'git-rev-list --pretty=oneline' output can be used. 336 337--rmdir:: 338 339Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 340 341Remove directories from the SVN tree if there are no files left 342behind. SVN can version empty directories, and they are not 343removed by default if there are no files left in them. git 344cannot version empty directories. Enabling this flag will make 345the commit to SVN act like git. 346 347config key: svn.rmdir 348 349-e:: 350--edit:: 351 352Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 353 354Edit the commit message before committing to SVN. This is off by 355default for objects that are commits, and forced on when committing 356tree objects. 357 358config key: svn.edit 359 360-l<num>:: 361--find-copies-harder:: 362 363Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 364 365They are both passed directly to 'git-diff-tree'; see 366linkgit:git-diff-tree[1] for more information. 367 368[verse] 369config key: svn.l 370config key: svn.findcopiesharder 371 372-A<filename>:: 373--authors-file=<filename>:: 374 375Syntax is compatible with the file used by 'git-cvsimport': 376 377------------------------------------------------------------------------ 378 loginname = Joe User <user@example.com> 379------------------------------------------------------------------------ 380 381If this option is specified and 'git-svn' encounters an SVN 382committer name that does not exist in the authors-file, 'git-svn' 383will abort operation. The user will then have to add the 384appropriate entry. Re-running the previous 'git-svn' command 385after the authors-file is modified should continue operation. 386 387config key: svn.authorsfile 388 389-q:: 390--quiet:: 391 Make 'git-svn' less verbose. Specify a second time to make it 392 even less verbose. 393 394--repack[=<n>]:: 395--repack-flags=<flags>:: 396 397These should help keep disk usage sane for large fetches 398with many revisions. 399 400--repack takes an optional argument for the number of revisions 401to fetch before repacking. This defaults to repacking every 4021000 commits fetched if no argument is specified. 403 404--repack-flags are passed directly to 'git-repack'. 405 406[verse] 407config key: svn.repack 408config key: svn.repackflags 409 410-m:: 411--merge:: 412-s<strategy>:: 413--strategy=<strategy>:: 414 415These are only used with the 'dcommit' and 'rebase' commands. 416 417Passed directly to 'git-rebase' when using 'dcommit' if a 418'git-reset' cannot be used (see 'dcommit'). 419 420-n:: 421--dry-run:: 422 423This can be used with the 'dcommit', 'rebase', 'branch' and 'tag' 424commands. 425 426For 'dcommit', print out the series of git arguments that would show 427which diffs would be committed to SVN. 428 429For 'rebase', display the local branch associated with the upstream svn 430repository associated with the current branch and the URL of svn 431repository that will be fetched from. 432 433For 'branch' and 'tag', display the urls that will be used for copying when 434creating the branch or tag. 435 436-- 437 438ADVANCED OPTIONS 439---------------- 440-- 441 442-i<GIT_SVN_ID>:: 443--id <GIT_SVN_ID>:: 444 445This sets GIT_SVN_ID (instead of using the environment). This 446allows the user to override the default refname to fetch from 447when tracking a single URL. The 'log' and 'dcommit' commands 448no longer require this switch as an argument. 449 450-R<remote name>:: 451--svn-remote <remote name>:: 452 Specify the [svn-remote "<remote name>"] section to use, 453 this allows SVN multiple repositories to be tracked. 454 Default: "svn" 455 456--follow-parent:: 457 This is especially helpful when we're tracking a directory 458 that has been moved around within the repository, or if we 459 started tracking a branch and never tracked the trunk it was 460 descended from. This feature is enabled by default, use 461 --no-follow-parent to disable it. 462 463config key: svn.followparent 464 465-- 466CONFIG FILE-ONLY OPTIONS 467------------------------ 468-- 469 470svn.noMetadata:: 471svn-remote.<name>.noMetadata:: 472 473This gets rid of the 'git-svn-id:' lines at the end of every commit. 474 475If you lose your .git/svn/git-svn/.rev_db file, 'git-svn' will not 476be able to rebuild it and you won't be able to fetch again, 477either. This is fine for one-shot imports. 478 479The 'git-svn log' command will not work on repositories using 480this, either. Using this conflicts with the 'useSvmProps' 481option for (hopefully) obvious reasons. 482 483svn.useSvmProps:: 484svn-remote.<name>.useSvmProps:: 485 486This allows 'git-svn' to re-map repository URLs and UUIDs from 487mirrors created using SVN::Mirror (or svk) for metadata. 488 489If an SVN revision has a property, "svm:headrev", it is likely 490that the revision was created by SVN::Mirror (also used by SVK). 491The property contains a repository UUID and a revision. We want 492to make it look like we are mirroring the original URL, so 493introduce a helper function that returns the original identity 494URL and UUID, and use it when generating metadata in commit 495messages. 496 497svn.useSvnsyncProps:: 498svn-remote.<name>.useSvnsyncprops:: 499 Similar to the useSvmProps option; this is for users 500 of the svnsync(1) command distributed with SVN 1.4.x and 501 later. 502 503svn-remote.<name>.rewriteRoot:: 504 This allows users to create repositories from alternate 505 URLs. For example, an administrator could run 'git-svn' on the 506 server locally (accessing via file://) but wish to distribute 507 the repository with a public http:// or svn:// URL in the 508 metadata so users of it will see the public URL. 509 510svn.brokenSymlinkWorkaround:: 511This disables potentially expensive checks to workaround broken symlinks 512checked into SVN by broken clients. Set this option to "false" if you 513track a SVN repository with many empty blobs that are not symlinks. 514This option may be changed while "git-svn" is running and take effect on 515the next revision fetched. If unset, git-svn assumes this option to be 516"true". 517 518-- 519 520Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps 521options all affect the metadata generated and used by 'git-svn'; they 522*must* be set in the configuration file before any history is imported 523and these settings should never be changed once they are set. 524 525Additionally, only one of these four options can be used per-svn-remote 526section because they affect the 'git-svn-id:' metadata line. 527 528 529BASIC EXAMPLES 530-------------- 531 532Tracking and contributing to the trunk of a Subversion-managed project: 533 534------------------------------------------------------------------------ 535# Clone a repo (like git clone): 536 git svn clone http://svn.example.com/project/trunk 537# Enter the newly cloned directory: 538 cd trunk 539# You should be on master branch, double-check with git-branch 540 git branch 541# Do some work and commit locally to git: 542 git commit ... 543# Something is committed to SVN, rebase your local changes against the 544# latest changes in SVN: 545 git svn rebase 546# Now commit your changes (that were committed previously using git) to SVN, 547# as well as automatically updating your working HEAD: 548 git svn dcommit 549# Append svn:ignore settings to the default git exclude file: 550 git svn show-ignore >> .git/info/exclude 551------------------------------------------------------------------------ 552 553Tracking and contributing to an entire Subversion-managed project 554(complete with a trunk, tags and branches): 555 556------------------------------------------------------------------------ 557# Clone a repo (like git clone): 558 git svn clone http://svn.example.com/project -T trunk -b branches -t tags 559# View all branches and tags you have cloned: 560 git branch -r 561# Create a new branch in SVN 562 git svn branch waldo 563# Reset your master to trunk (or any other branch, replacing 'trunk' 564# with the appropriate name): 565 git reset --hard remotes/trunk 566# You may only dcommit to one branch/tag/trunk at a time. The usage 567# of dcommit/rebase/show-ignore should be the same as above. 568------------------------------------------------------------------------ 569 570The initial 'git-svn clone' can be quite time-consuming 571(especially for large Subversion repositories). If multiple 572people (or one person with multiple machines) want to use 573'git-svn' to interact with the same Subversion repository, you can 574do the initial 'git-svn clone' to a repository on a server and 575have each person clone that repository with 'git-clone': 576 577------------------------------------------------------------------------ 578# Do the initial import on a server 579 ssh server "cd /pub && git svn clone http://svn.example.com/project 580# Clone locally - make sure the refs/remotes/ space matches the server 581 mkdir project 582 cd project 583 git init 584 git remote add origin server:/pub/project 585 git config --add remote.origin.fetch '+refs/remotes/*:refs/remotes/*' 586 git fetch 587# Create a local branch from one of the branches just fetched 588 git checkout -b master FETCH_HEAD 589# Initialize git-svn locally (be sure to use the same URL and -T/-b/-t options as were used on server) 590 git svn init http://svn.example.com/project 591# Pull the latest changes from Subversion 592 git svn rebase 593------------------------------------------------------------------------ 594 595REBASE VS. PULL/MERGE 596--------------------- 597 598Originally, 'git-svn' recommended that the 'remotes/git-svn' branch be 599pulled or merged from. This is because the author favored 600`git svn set-tree B` to commit a single head rather than the 601`git svn set-tree A..B` notation to commit multiple commits. 602 603If you use `git svn set-tree A..B` to commit several diffs and you do 604not have the latest remotes/git-svn merged into my-branch, you should 605use `git svn rebase` to update your work branch instead of `git pull` or 606`git merge`. `pull`/`merge' can cause non-linear history to be flattened 607when committing into SVN, which can lead to merge commits reversing 608previous commits in SVN. 609 610DESIGN PHILOSOPHY 611----------------- 612Merge tracking in Subversion is lacking and doing branched development 613with Subversion can be cumbersome as a result. While 'git-svn' can track 614copy history (including branches and tags) for repositories adopting a 615standard layout, it cannot yet represent merge history that happened 616inside git back upstream to SVN users. Therefore it is advised that 617users keep history as linear as possible inside git to ease 618compatibility with SVN (see the CAVEATS section below). 619 620CAVEATS 621------- 622 623For the sake of simplicity and interoperating with a less-capable system 624(SVN), it is recommended that all 'git-svn' users clone, fetch and dcommit 625directly from the SVN server, and avoid all 'git-clone'/'pull'/'merge'/'push' 626operations between git repositories and branches. The recommended 627method of exchanging code between git branches and users is 628'git-format-patch' and 'git-am', or just 'dcommit'ing to the SVN repository. 629 630Running 'git-merge' or 'git-pull' is NOT recommended on a branch you 631plan to 'dcommit' from. Subversion does not represent merges in any 632reasonable or useful fashion; so users using Subversion cannot see any 633merges you've made. Furthermore, if you merge or pull from a git branch 634that is a mirror of an SVN branch, 'dcommit' may commit to the wrong 635branch. 636 637'git-clone' does not clone branches under the refs/remotes/ hierarchy or 638any 'git-svn' metadata, or config. So repositories created and managed with 639using 'git-svn' should use 'rsync' for cloning, if cloning is to be done 640at all. 641 642Since 'dcommit' uses rebase internally, any git branches you 'git-push' to 643before 'dcommit' on will require forcing an overwrite of the existing ref 644on the remote repository. This is generally considered bad practice, 645see the linkgit:git-push[1] documentation for details. 646 647Do not use the --amend option of linkgit:git-commit[1] on a change you've 648already dcommitted. It is considered bad practice to --amend commits 649you've already pushed to a remote repository for other users, and 650dcommit with SVN is analogous to that. 651 652BUGS 653---- 654 655We ignore all SVN properties except svn:executable. Any unhandled 656properties are logged to $GIT_DIR/svn/<refname>/unhandled.log 657 658Renamed and copied directories are not detected by git and hence not 659tracked when committing to SVN. I do not plan on adding support for 660this as it's quite difficult and time-consuming to get working for all 661the possible corner cases (git doesn't do it, either). Committing 662renamed and copied files are fully supported if they're similar enough 663for git to detect them. 664 665CONFIGURATION 666------------- 667 668'git-svn' stores [svn-remote] configuration information in the 669repository .git/config file. It is similar the core git 670[remote] sections except 'fetch' keys do not accept glob 671arguments; but they are instead handled by the 'branches' 672and 'tags' keys. Since some SVN repositories are oddly 673configured with multiple projects glob expansions such those 674listed below are allowed: 675 676------------------------------------------------------------------------ 677[svn-remote "project-a"] 678 url = http://server.org/svn 679 fetch = trunk/project-a:refs/remotes/project-a/trunk 680 branches = branches/*/project-a:refs/remotes/project-a/branches/* 681 tags = tags/*/project-a:refs/remotes/project-a/tags/* 682------------------------------------------------------------------------ 683 684Keep in mind that the '*' (asterisk) wildcard of the local ref 685(right of the ':') *must* be the farthest right path component; 686however the remote wildcard may be anywhere as long as it's own 687independent path component (surrounded by '/' or EOL). This 688type of configuration is not automatically created by 'init' and 689should be manually entered with a text-editor or using 'git-config'. 690 691SEE ALSO 692-------- 693linkgit:git-rebase[1] 694 695Author 696------ 697Written by Eric Wong <normalperson@yhbt.net>. 698 699Documentation 700------------- 701Written by Eric Wong <normalperson@yhbt.net>.