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 gitlink:git-svnimport[1], which is 16read-only and geared towards tracking multiple branches. 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; but it cannot (yet) automatically detect new 23branches and tags like git-svnimport does. 24 25git-svn is especially useful when it comes to tracking repositories 26not organized in the way Subversion developers recommend (trunk, 27branches, tags directories). 28 29COMMANDS 30-------- 31-- 32 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. 39 40'fetch':: 41 42Fetch unfetched revisions from the Subversion URL we are 43tracking. refs/remotes/git-svn will be updated to the 44latest revision. 45 46Note: You should never attempt to modify the remotes/git-svn 47branch outside of git-svn. Instead, create a branch from 48remotes/git-svn and work on that branch. Use the 'dcommit' 49command (see below) to write git commits back to 50remotes/git-svn. 51 52'dcommit':: 53 Commit each diff from a specified head directly to the SVN 54 repository, and then rebase or reset (depending on whether or 55 not there is a diff between SVN and head). This will create 56 a revision in SVN for each commit in git. 57 It is recommended that you run git-svn fetch and rebase (not 58 pull or merge) your commits against the latest changes in the 59 SVN repository. 60 An optional command-line argument may be specified as an 61 alternative to HEAD. 62 This is advantageous over 'set-tree' (below) because it produces 63 cleaner, more linear history. 64 65'log':: 66 This should make it easy to look up svn log messages when svn 67 users refer to -r/--revision numbers. 68 69 The following features from `svn log' are supported: 70 71 --revision=<n>[:<n>] - is supported, non-numeric args are not: 72 HEAD, NEXT, BASE, PREV, etc ... 73 -v/--verbose - it's not completely compatible with 74 the --verbose output in svn log, but 75 reasonably close. 76 --limit=<n> - is NOT the same as --max-count, 77 doesn't count merged/excluded commits 78 --incremental - supported 79 80 New features: 81 82 --show-commit - shows the git commit sha1, as well 83 --oneline - our version of --pretty=oneline 84 85 Any other arguments are passed directly to `git log' 86 87'set-tree':: 88 You should consider using 'dcommit' instead of this command. 89 Commit specified commit or tree objects to SVN. This relies on 90 your imported fetch data being up-to-date. This makes 91 absolutely no attempts to do patching when committing to SVN, it 92 simply overwrites files with those specified in the tree or 93 commit. All merging is assumed to have taken place 94 independently of git-svn functions. 95 96'show-ignore':: 97 Recursively finds and lists the svn:ignore property on 98 directories. The output is suitable for appending to 99 the $GIT_DIR/info/exclude file. 100 101'commit-diff':: 102 Commits the diff of two tree-ish arguments from the 103 command-line. This command is intended for interoperability with 104 git-svnimport and does not rely on being inside an git-svn 105 init-ed repository. This command takes three arguments, (a) the 106 original tree to diff against, (b) the new tree result, (c) the 107 URL of the target Subversion repository. The final argument 108 (URL) may be omitted if you are working from a git-svn-aware 109 repository (that has been init-ed with git-svn). 110 The -r<revision> option is required for this. 111 112'graft-branches':: 113 This command attempts to detect merges/branches from already 114 imported history. Techniques used currently include regexes, 115 file copies, and tree-matches). This command generates (or 116 modifies) the $GIT_DIR/info/grafts file. This command is 117 considered experimental, and inherently flawed because 118 merge-tracking in SVN is inherently flawed and inconsistent 119 across different repositories. 120 121'multi-init':: 122 This command supports git-svnimport-like command-line syntax for 123 importing repositories that are laid out as recommended by the 124 SVN folks. This is a bit more tolerant than the git-svnimport 125 command-line syntax and doesn't require the user to figure out 126 where the repository URL ends and where the repository path 127 begins. 128 129-T<trunk_subdir>:: 130--trunk=<trunk_subdir>:: 131-t<tags_subdir>:: 132--tags=<tags_subdir>:: 133-b<branches_subdir>:: 134--branches=<branches_subdir>:: 135 These are the command-line options for multi-init. Each of 136 these flags can point to a relative repository path 137 (--tags=project/tags') or a full url 138 (--tags=https://foo.org/project/tags) 139 140--prefix=<prefix> 141 This allows one to specify a prefix which is prepended to the 142 names of remotes. The prefix does not automatically include a 143 trailing slash, so be sure you include one in the argument if 144 that is what you want. This is useful if you wish to track 145 multiple projects that share a common repository. 146 147'multi-fetch':: 148 This runs fetch on all known SVN branches we're tracking. This 149 will NOT discover new branches (unlike git-svnimport), so 150 multi-init will need to be re-run (it's idempotent). 151 152-- 153 154OPTIONS 155------- 156-- 157 158--shared:: 159--template=<template_directory>:: 160 Only used with the 'init' command. 161 These are passed directly to gitlink:git-init[1]. 162 163-r <ARG>:: 164--revision <ARG>:: 165 166Only used with the 'fetch' command. 167 168Takes any valid -r<argument> svn would accept and passes it 169directly to svn. -r<ARG1>:<ARG2> ranges and "{" DATE "}" syntax 170is also supported. This is passed directly to svn, see svn 171documentation for more details. 172 173This can allow you to make partial mirrors when running fetch. 174 175-:: 176--stdin:: 177 178Only used with the 'set-tree' command. 179 180Read a list of commits from stdin and commit them in reverse 181order. Only the leading sha1 is read from each line, so 182git-rev-list --pretty=oneline output can be used. 183 184--rmdir:: 185 186Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 187 188Remove directories from the SVN tree if there are no files left 189behind. SVN can version empty directories, and they are not 190removed by default if there are no files left in them. git 191cannot version empty directories. Enabling this flag will make 192the commit to SVN act like git. 193 194config key: svn.rmdir 195 196-e:: 197--edit:: 198 199Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 200 201Edit the commit message before committing to SVN. This is off by 202default for objects that are commits, and forced on when committing 203tree objects. 204 205config key: svn.edit 206 207-l<num>:: 208--find-copies-harder:: 209 210Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 211 212They are both passed directly to git-diff-tree see 213gitlink:git-diff-tree[1] for more information. 214 215[verse] 216config key: svn.l 217config key: svn.findcopiesharder 218 219-A<filename>:: 220--authors-file=<filename>:: 221 222Syntax is compatible with the files used by git-svnimport and 223git-cvsimport: 224 225------------------------------------------------------------------------ 226 loginname = Joe User <user@example.com> 227------------------------------------------------------------------------ 228 229If this option is specified and git-svn encounters an SVN 230committer name that does not exist in the authors-file, git-svn 231will abort operation. The user will then have to add the 232appropriate entry. Re-running the previous git-svn command 233after the authors-file is modified should continue operation. 234 235config key: svn.authorsfile 236 237-q:: 238--quiet:: 239 Make git-svn less verbose. 240 241--repack[=<n>]:: 242--repack-flags=<flags> 243 These should help keep disk usage sane for large fetches 244 with many revisions. 245 246 --repack takes an optional argument for the number of revisions 247 to fetch before repacking. This defaults to repacking every 248 1000 commits fetched if no argument is specified. 249 250 --repack-flags are passed directly to gitlink:git-repack[1]. 251 252config key: svn.repack 253config key: svn.repackflags 254 255-m:: 256--merge:: 257-s<strategy>:: 258--strategy=<strategy>:: 259 260These are only used with the 'dcommit' command. 261 262Passed directly to git-rebase when using 'dcommit' if a 263'git-reset' cannot be used (see dcommit). 264 265-n:: 266--dry-run:: 267 268This is only used with the 'dcommit' command. 269 270Print out the series of git arguments that would show 271which diffs would be committed to SVN. 272 273-- 274 275ADVANCED OPTIONS 276---------------- 277-- 278 279-b<refname>:: 280--branch <refname>:: 281Used with 'fetch', 'dcommit' or 'set-tree'. 282 283This can be used to join arbitrary git branches to remotes/git-svn 284on new commits where the tree object is equivalent. 285 286When used with different GIT_SVN_ID values, tags and branches in 287SVN can be tracked this way, as can some merges where the heads 288end up having completely equivalent content. This can even be 289used to track branches across multiple SVN _repositories_. 290 291This option may be specified multiple times, once for each 292branch. 293 294config key: svn.branch 295 296-i<GIT_SVN_ID>:: 297--id <GIT_SVN_ID>:: 298 299This sets GIT_SVN_ID (instead of using the environment). See the 300section on 301'<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>' 302for more information on using GIT_SVN_ID. 303 304-R<remote name>:: 305--svn-remote <remote name>:: 306 Specify the [svn-remote "<remote name>"] section to use, 307 this allows multiple repositories to be tracked. 308 Default: git-svn 309 310--follow-parent:: 311 This is especially helpful when we're tracking a directory 312 that has been moved around within the repository, or if we 313 started tracking a branch and never tracked the trunk it was 314 descended from. This feature is enabled by default, use 315 --no-follow-parent to disable it. 316 317config key: svn.followparent 318 319--no-metadata:: 320 This gets rid of the git-svn-id: lines at the end of every commit. 321 322 If you lose your .git/svn/git-svn/.rev_db file, git-svn will not 323 be able to rebuild it and you won't be able to fetch again, 324 either. This is fine for one-shot imports. 325 326 The 'git-svn log' command will not work on repositories using this, 327 either. 328 329config key: svn.nometadata 330 331-- 332 333Basic Examples 334~~~~~~~~~~~~~~ 335 336Tracking and contributing to a the trunk of a Subversion-managed project: 337 338------------------------------------------------------------------------ 339# Initialize a repo (like git init): 340 git-svn init http://svn.foo.org/project/trunk 341# Fetch remote revisions: 342 git-svn fetch 343# Create your own branch to hack on: 344 git checkout -b my-branch remotes/git-svn 345# Do some work, and then commit your new changes to SVN, as well as 346# automatically updating your working HEAD: 347 git-svn dcommit 348# Something is committed to SVN, rebase the latest into your branch: 349 git-svn fetch && git rebase remotes/git-svn 350# Append svn:ignore settings to the default git exclude file: 351 git-svn show-ignore >> .git/info/exclude 352------------------------------------------------------------------------ 353 354Tracking and contributing to an entire Subversion-managed project 355(complete with a trunk, tags and branches): 356See also: 357'<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>' 358 359------------------------------------------------------------------------ 360# Initialize a repo (like git init): 361 git-svn multi-init http://svn.foo.org/project \ 362 -T trunk -b branches -t tags 363# Fetch remote revisions: 364 git-svn multi-fetch 365# Create your own branch of trunk to hack on: 366 git checkout -b my-trunk remotes/trunk 367# Do some work, and then commit your new changes to SVN, as well as 368# automatically updating your working HEAD: 369 git-svn dcommit -i trunk 370# Something has been committed to trunk, rebase the latest into your branch: 371 git-svn multi-fetch && git rebase remotes/trunk 372# Append svn:ignore settings of trunk to the default git exclude file: 373 git-svn show-ignore -i trunk >> .git/info/exclude 374# Check for new branches and tags (no arguments are needed): 375 git-svn multi-init 376------------------------------------------------------------------------ 377 378REBASE VS. PULL/MERGE 379--------------------- 380 381Originally, git-svn recommended that the remotes/git-svn branch be 382pulled or merged from. This is because the author favored 383'git-svn set-tree B' to commit a single head rather than the 384'git-svn set-tree A..B' notation to commit multiple commits. 385 386If you use 'git-svn set-tree A..B' to commit several diffs and you do 387not have the latest remotes/git-svn merged into my-branch, you should 388use 'git rebase' to update your work branch instead of 'git pull' or 389'git merge'. 'pull/merge' can cause non-linear history to be flattened 390when committing into SVN, which can lead to merge commits reversing 391previous commits in SVN. 392 393DESIGN PHILOSOPHY 394----------------- 395Merge tracking in Subversion is lacking and doing branched development 396with Subversion is cumbersome as a result. git-svn does not do 397automated merge/branch tracking by default and leaves it entirely up to 398the user on the git side. 399 400[[tracking-multiple-repos]] 401TRACKING MULTIPLE REPOSITORIES OR BRANCHES 402------------------------------------------ 403Because git-svn does not care about relationships between different 404branches or directories in a Subversion repository, git-svn has a simple 405hack to allow it to track an arbitrary number of related _or_ unrelated 406SVN repositories via one git repository. Simply use the --id/-i flag or 407set the GIT_SVN_ID environment variable to a name other other than 408"git-svn" (the default) and git-svn will ignore the contents of the 409$GIT_DIR/svn/git-svn directory and instead do all of its work in 410$GIT_DIR/svn/$GIT_SVN_ID for that invocation. The interface branch will 411be remotes/$GIT_SVN_ID, instead of remotes/git-svn. Any 412remotes/$GIT_SVN_ID branch should never be modified by the user outside 413of git-svn commands. 414 415If you're tracking a directory that has moved, or otherwise been 416branched or tagged off of another directory in the repository and you 417care about the full history of the project, then you can use 418the --follow-parent option. 419 420------------------------------------------------ 421 git-svn fetch --follow-parent 422------------------------------------------------ 423 424BUGS 425---- 426 427We ignore all SVN properties except svn:executable. Too difficult to 428map them since we rely heavily on git write-tree being _exactly_ the 429same on both the SVN and git working trees and I prefer not to clutter 430working trees with metadata files. 431 432Renamed and copied directories are not detected by git and hence not 433tracked when committing to SVN. I do not plan on adding support for 434this as it's quite difficult and time-consuming to get working for all 435the possible corner cases (git doesn't do it, either). Renamed and 436copied files are fully supported if they're similar enough for git to 437detect them. 438 439SEE ALSO 440-------- 441gitlink:git-rebase[1] 442 443Author 444------ 445Written by Eric Wong <normalperson@yhbt.net>. 446 447Documentation 448------------- 449Written by Eric Wong <normalperson@yhbt.net>.