Documentation / git-svn.txton commit git-svn: extra safety for noMetadata and useSvmProps users (97ae091)
   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
 319svn.noMetadata:
 320svn-remote.<name>.noMetadata:
 321        This gets rid of the git-svn-id: lines at the end of every commit.
 322
 323        If you lose your .git/svn/git-svn/.rev_db file, git-svn will not
 324        be able to rebuild it and you won't be able to fetch again,
 325        either.  This is fine for one-shot imports.
 326
 327        The 'git-svn log' command will not work on repositories using
 328        this, either.  Using this conflicts with the 'useSvmProps'
 329        option for (hopefully) obvious reasons.
 330
 331svn.useSvmProps:
 332svn-remote.<name>.useSvmProps:
 333        This allows git-svn to re-map repository URLs and UUIDs from
 334        mirrors created using SVN::Mirror (or svk) for metadata.
 335
 336        If an SVN revision has a property, "svm:headrev", it is likely
 337        that the revision was created by SVN::Mirror (also used by SVK).
 338        The property contains a repository UUID and a revision.  We want
 339        to make it look like we are mirroring the original URL, so
 340        introduce a helper function that returns the original identity
 341        URL and UUID, and use it when generating metadata in commit
 342        messages.
 343
 344        Using this conflicts with the 'noMetadata' option for
 345        (hopefully) obvious reasons.
 346
 347--
 348
 349Basic Examples
 350~~~~~~~~~~~~~~
 351
 352Tracking and contributing to a the trunk of a Subversion-managed project:
 353
 354------------------------------------------------------------------------
 355# Initialize a repo (like git init):
 356        git-svn init http://svn.foo.org/project/trunk
 357# Fetch remote revisions:
 358        git-svn fetch
 359# Create your own branch to hack on:
 360        git checkout -b my-branch remotes/git-svn
 361# Do some work, and then commit your new changes to SVN, as well as
 362# automatically updating your working HEAD:
 363        git-svn dcommit
 364# Something is committed to SVN, rebase the latest into your branch:
 365        git-svn fetch && git rebase remotes/git-svn
 366# Append svn:ignore settings to the default git exclude file:
 367        git-svn show-ignore >> .git/info/exclude
 368------------------------------------------------------------------------
 369
 370Tracking and contributing to an entire Subversion-managed project
 371(complete with a trunk, tags and branches):
 372See also:
 373'<<tracking-multiple-repos,Tracking Multiple Repositories or Branches>>'
 374
 375------------------------------------------------------------------------
 376# Initialize a repo (like git init):
 377        git-svn multi-init http://svn.foo.org/project \
 378                -T trunk -b branches -t tags
 379# Fetch remote revisions:
 380        git-svn multi-fetch
 381# Create your own branch of trunk to hack on:
 382        git checkout -b my-trunk remotes/trunk
 383# Do some work, and then commit your new changes to SVN, as well as
 384# automatically updating your working HEAD:
 385        git-svn dcommit -i trunk
 386# Something has been committed to trunk, rebase the latest into your branch:
 387        git-svn multi-fetch && git rebase remotes/trunk
 388# Append svn:ignore settings of trunk to the default git exclude file:
 389        git-svn show-ignore -i trunk >> .git/info/exclude
 390# Check for new branches and tags (no arguments are needed):
 391        git-svn multi-init
 392------------------------------------------------------------------------
 393
 394REBASE VS. PULL/MERGE
 395---------------------
 396
 397Originally, git-svn recommended that the remotes/git-svn branch be
 398pulled or merged from.  This is because the author favored
 399'git-svn set-tree B' to commit a single head rather than the
 400'git-svn set-tree A..B' notation to commit multiple commits.
 401
 402If you use 'git-svn set-tree A..B' to commit several diffs and you do
 403not have the latest remotes/git-svn merged into my-branch, you should
 404use 'git rebase' to update your work branch instead of 'git pull' or
 405'git merge'.  'pull/merge' can cause non-linear history to be flattened
 406when committing into SVN, which can lead to merge commits reversing
 407previous commits in SVN.
 408
 409DESIGN PHILOSOPHY
 410-----------------
 411Merge tracking in Subversion is lacking and doing branched development
 412with Subversion is cumbersome as a result.  git-svn does not do
 413automated merge/branch tracking by default and leaves it entirely up to
 414the user on the git side.
 415
 416[[tracking-multiple-repos]]
 417TRACKING MULTIPLE REPOSITORIES OR BRANCHES
 418------------------------------------------
 419Because git-svn does not care about relationships between different
 420branches or directories in a Subversion repository, git-svn has a simple
 421hack to allow it to track an arbitrary number of related _or_ unrelated
 422SVN repositories via one git repository.  Simply use the --id/-i flag or
 423set the GIT_SVN_ID environment variable to a name other other than
 424"git-svn" (the default) and git-svn will ignore the contents of the
 425$GIT_DIR/svn/git-svn directory and instead do all of its work in
 426$GIT_DIR/svn/$GIT_SVN_ID for that invocation.  The interface branch will
 427be remotes/$GIT_SVN_ID, instead of remotes/git-svn.  Any
 428remotes/$GIT_SVN_ID branch should never be modified by the user outside
 429of git-svn commands.
 430
 431If you're tracking a directory that has moved, or otherwise been
 432branched or tagged off of another directory in the repository and you
 433care about the full history of the project, then you can use
 434the --follow-parent option.
 435
 436------------------------------------------------
 437        git-svn fetch --follow-parent
 438------------------------------------------------
 439
 440BUGS
 441----
 442
 443We ignore all SVN properties except svn:executable.  Too difficult to
 444map them since we rely heavily on git write-tree being _exactly_ the
 445same on both the SVN and git working trees and I prefer not to clutter
 446working trees with metadata files.
 447
 448Renamed and copied directories are not detected by git and hence not
 449tracked when committing to SVN.  I do not plan on adding support for
 450this as it's quite difficult and time-consuming to get working for all
 451the possible corner cases (git doesn't do it, either).  Renamed and
 452copied files are fully supported if they're similar enough for git to
 453detect them.
 454
 455SEE ALSO
 456--------
 457gitlink:git-rebase[1]
 458
 459Author
 460------
 461Written by Eric Wong <normalperson@yhbt.net>.
 462
 463Documentation
 464-------------
 465Written by Eric Wong <normalperson@yhbt.net>.