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