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. 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 These are optional command-line options for init. Each of 48 these flags can point to a relative repository path 49 (--tags=project/tags') or a full url 50 (--tags=https://foo.org/project/tags) 51 52--prefix=<prefix> 53 This allows one to specify a prefix which is prepended 54 to the names of remotes if trunk/branches/tags are 55 specified. The prefix does not automatically include a 56 trailing slash, so be sure you include one in the 57 argument if that is what you want. This is useful if 58 you wish to track multiple projects that share a common 59 repository. 60 61'fetch':: 62 63 Fetch unfetched revisions from the Subversion remote we are 64 tracking. The name of the [svn-remote "..."] section in the 65 .git/config file may be specified as an optional command-line 66 argument. 67 68'dcommit':: 69 Commit each diff from a specified head directly to the SVN 70 repository, and then rebase or reset (depending on whether or 71 not there is a diff between SVN and head). This will create 72 a revision in SVN for each commit in git. 73 It is recommended that you run git-svn fetch and rebase (not 74 pull or merge) your commits against the latest changes in the 75 SVN repository. 76 An optional command-line argument may be specified as an 77 alternative to HEAD. 78 This is advantageous over 'set-tree' (below) because it produces 79 cleaner, more linear history. 80 81'log':: 82 This should make it easy to look up svn log messages when svn 83 users refer to -r/--revision numbers. 84 85 The following features from `svn log' are supported: 86 87 --revision=<n>[:<n>] - is supported, non-numeric args are not: 88 HEAD, NEXT, BASE, PREV, etc ... 89 -v/--verbose - it's not completely compatible with 90 the --verbose output in svn log, but 91 reasonably close. 92 --limit=<n> - is NOT the same as --max-count, 93 doesn't count merged/excluded commits 94 --incremental - supported 95 96 New features: 97 98 --show-commit - shows the git commit sha1, as well 99 --oneline - our version of --pretty=oneline 100 101 Any other arguments are passed directly to `git log' 102 103'set-tree':: 104 You should consider using 'dcommit' instead of this command. 105 Commit specified commit or tree objects to SVN. This relies on 106 your imported fetch data being up-to-date. This makes 107 absolutely no attempts to do patching when committing to SVN, it 108 simply overwrites files with those specified in the tree or 109 commit. All merging is assumed to have taken place 110 independently of git-svn functions. 111 112'show-ignore':: 113 Recursively finds and lists the svn:ignore property on 114 directories. The output is suitable for appending to 115 the $GIT_DIR/info/exclude file. 116 117'commit-diff':: 118 Commits the diff of two tree-ish arguments from the 119 command-line. This command is intended for interoperability with 120 git-svnimport and does not rely on being inside an git-svn 121 init-ed repository. This command takes three arguments, (a) the 122 original tree to diff against, (b) the new tree result, (c) the 123 URL of the target Subversion repository. The final argument 124 (URL) may be omitted if you are working from a git-svn-aware 125 repository (that has been init-ed with git-svn). 126 The -r<revision> option is required for this. 127 128-- 129 130OPTIONS 131------- 132-- 133 134--shared[={false|true|umask|group|all|world|everybody}]:: 135--template=<template_directory>:: 136 Only used with the 'init' command. 137 These are passed directly to gitlink:git-init[1]. 138 139-r <ARG>:: 140--revision <ARG>:: 141 142Used with the 'fetch' command. 143 144This allows revision ranges for partial/cauterized history 145to be supported. $NUMBER, $NUMBER1:$NUMBER2 (numeric ranges), 146$NUMBER:HEAD, and BASE:$NUMBER are all supported. 147 148This can allow you to make partial mirrors when running fetch; 149but is generally not recommended because history will be skipped 150and lost. 151 152-:: 153--stdin:: 154 155Only used with the 'set-tree' command. 156 157Read a list of commits from stdin and commit them in reverse 158order. Only the leading sha1 is read from each line, so 159git-rev-list --pretty=oneline output can be used. 160 161--rmdir:: 162 163Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 164 165Remove directories from the SVN tree if there are no files left 166behind. SVN can version empty directories, and they are not 167removed by default if there are no files left in them. git 168cannot version empty directories. Enabling this flag will make 169the commit to SVN act like git. 170 171config key: svn.rmdir 172 173-e:: 174--edit:: 175 176Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 177 178Edit the commit message before committing to SVN. This is off by 179default for objects that are commits, and forced on when committing 180tree objects. 181 182config key: svn.edit 183 184-l<num>:: 185--find-copies-harder:: 186 187Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. 188 189They are both passed directly to git-diff-tree see 190gitlink:git-diff-tree[1] for more information. 191 192[verse] 193config key: svn.l 194config key: svn.findcopiesharder 195 196-A<filename>:: 197--authors-file=<filename>:: 198 199Syntax is compatible with the files used by git-svnimport and 200git-cvsimport: 201 202------------------------------------------------------------------------ 203 loginname = Joe User <user@example.com> 204------------------------------------------------------------------------ 205 206If this option is specified and git-svn encounters an SVN 207committer name that does not exist in the authors-file, git-svn 208will abort operation. The user will then have to add the 209appropriate entry. Re-running the previous git-svn command 210after the authors-file is modified should continue operation. 211 212config key: svn.authorsfile 213 214-q:: 215--quiet:: 216 Make git-svn less verbose. 217 218--repack[=<n>]:: 219--repack-flags=<flags> 220 These should help keep disk usage sane for large fetches 221 with many revisions. 222 223 --repack takes an optional argument for the number of revisions 224 to fetch before repacking. This defaults to repacking every 225 1000 commits fetched if no argument is specified. 226 227 --repack-flags are passed directly to gitlink:git-repack[1]. 228 229config key: svn.repack 230config key: svn.repackflags 231 232-m:: 233--merge:: 234-s<strategy>:: 235--strategy=<strategy>:: 236 237These are only used with the 'dcommit' command. 238 239Passed directly to git-rebase when using 'dcommit' if a 240'git-reset' cannot be used (see dcommit). 241 242-n:: 243--dry-run:: 244 245This is only used with the 'dcommit' command. 246 247Print out the series of git arguments that would show 248which diffs would be committed to SVN. 249 250-- 251 252ADVANCED OPTIONS 253---------------- 254-- 255 256-i<GIT_SVN_ID>:: 257--id <GIT_SVN_ID>:: 258 259This sets GIT_SVN_ID (instead of using the environment). This 260allows the user to override the default refname to fetch from 261when tracking a single URL. The 'log' and 'dcommit' commands 262no longer require this switch as an argument. 263 264-R<remote name>:: 265--svn-remote <remote name>:: 266 Specify the [svn-remote "<remote name>"] section to use, 267 this allows SVN multiple repositories to be tracked. 268 Default: "svn" 269 270--follow-parent:: 271 This is especially helpful when we're tracking a directory 272 that has been moved around within the repository, or if we 273 started tracking a branch and never tracked the trunk it was 274 descended from. This feature is enabled by default, use 275 --no-follow-parent to disable it. 276 277config key: svn.followparent 278 279svn.noMetadata: 280svn-remote.<name>.noMetadata: 281 This gets rid of the git-svn-id: lines at the end of every commit. 282 283 If you lose your .git/svn/git-svn/.rev_db file, git-svn will not 284 be able to rebuild it and you won't be able to fetch again, 285 either. This is fine for one-shot imports. 286 287 The 'git-svn log' command will not work on repositories using 288 this, either. Using this conflicts with the 'useSvmProps' 289 option for (hopefully) obvious reasons. 290 291svn.useSvmProps: 292svn-remote.<name>.useSvmProps: 293 This allows git-svn to re-map repository URLs and UUIDs from 294 mirrors created using SVN::Mirror (or svk) for metadata. 295 296 If an SVN revision has a property, "svm:headrev", it is likely 297 that the revision was created by SVN::Mirror (also used by SVK). 298 The property contains a repository UUID and a revision. We want 299 to make it look like we are mirroring the original URL, so 300 introduce a helper function that returns the original identity 301 URL and UUID, and use it when generating metadata in commit 302 messages. 303 304 Using this conflicts with the 'noMetadata' option for 305 (hopefully) obvious reasons. 306 307-- 308 309Basic Examples 310~~~~~~~~~~~~~~ 311 312Tracking and contributing to a the trunk of a Subversion-managed project: 313 314------------------------------------------------------------------------ 315# Initialize a repo (like git init): 316 git-svn init http://svn.foo.org/project/trunk 317# Fetch remote revisions: 318 git-svn fetch 319# Create your own branch to hack on: 320 git checkout -b my-branch remotes/git-svn 321# Do some work, and then commit your new changes to SVN, as well as 322# automatically updating your working HEAD: 323 git-svn dcommit 324# Something is committed to SVN, rebase the latest into your branch: 325 git-svn fetch && git rebase remotes/git-svn 326# Append svn:ignore settings to the default git exclude file: 327 git-svn show-ignore >> .git/info/exclude 328------------------------------------------------------------------------ 329 330Tracking and contributing to an entire Subversion-managed project 331(complete with a trunk, tags and branches): 332 333------------------------------------------------------------------------ 334# Initialize a repo (like git init): 335 git-svn init http://svn.foo.org/project -T trunk -b branches -t tags 336# Fetch remote revisions: 337 git-svn fetch 338# Create your own branch of trunk to hack on: 339 git checkout -b my-trunk remotes/trunk 340# Do some work, and then commit your new changes to SVN, as well as 341# automatically updating your working HEAD: 342 git-svn dcommit 343# Something has been committed to trunk, rebase the latest into your branch: 344 git-svn fetch && git rebase remotes/trunk 345# Append svn:ignore settings of trunk to the default git exclude file: 346 git-svn show-ignore -i trunk >> .git/info/exclude 347------------------------------------------------------------------------ 348 349REBASE VS. PULL/MERGE 350--------------------- 351 352Originally, git-svn recommended that the remotes/git-svn branch be 353pulled or merged from. This is because the author favored 354'git-svn set-tree B' to commit a single head rather than the 355'git-svn set-tree A..B' notation to commit multiple commits. 356 357If you use 'git-svn set-tree A..B' to commit several diffs and you do 358not have the latest remotes/git-svn merged into my-branch, you should 359use 'git rebase' to update your work branch instead of 'git pull' or 360'git merge'. 'pull/merge' can cause non-linear history to be flattened 361when committing into SVN, which can lead to merge commits reversing 362previous commits in SVN. 363 364DESIGN PHILOSOPHY 365----------------- 366Merge tracking in Subversion is lacking and doing branched development 367with Subversion is cumbersome as a result. git-svn does not do 368automated merge/branch tracking by default and leaves it entirely up to 369the user on the git side. git-svn does however follow copy 370history of the directory that it is tracking, however (much like 371how 'svn log' works). 372 373BUGS 374---- 375 376We ignore all SVN properties except svn:executable. Too difficult to 377map them since we rely heavily on git write-tree being _exactly_ the 378same on both the SVN and git working trees and I prefer not to clutter 379working trees with metadata files. 380 381Renamed and copied directories are not detected by git and hence not 382tracked when committing to SVN. I do not plan on adding support for 383this as it's quite difficult and time-consuming to get working for all 384the possible corner cases (git doesn't do it, either). Renamed and 385copied files are fully supported if they're similar enough for git to 386detect them. 387 388CONFIGURATION 389------------- 390 391git-svn stores [svn-remote] configuration information in the 392repository .git/config file. It is similar the core git 393[remote] sections except 'fetch' keys do not accept glob 394arguments; but they are instead handled by the 'branches' 395and 'tags' keys. Since some SVN repositories are oddly 396configured with multiple projects glob expansions such those 397listed below are allowed: 398 399------------------------------------------------------------------------ 400[svn-remote "project-a"] 401 url = http://server.org/svn 402 branches = branches/*/project-a:refs/remotes/project-a/branches/* 403 tags = tags/*/project-a:refs/remotes/project-a/tags/* 404 trunk = trunk/project-a:refs/remotes/project-a/trunk 405------------------------------------------------------------------------ 406 407Keep in mind that the '*' (asterisk) wildcard of the local ref 408(left of the ':') *must* be the farthest right path component; 409however the remote wildcard may be anywhere as long as it's own 410independent path componet (surrounded by '/' or EOL). This 411type of configuration is not automatically created by 'init' and 412should be manually entered with a text-editor or using 413gitlink:git-config[1] 414 415SEE ALSO 416-------- 417gitlink:git-rebase[1] 418 419Author 420------ 421Written by Eric Wong <normalperson@yhbt.net>. 422 423Documentation 424------------- 425Written by Eric Wong <normalperson@yhbt.net>.