X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=Documentation%2Fgit-svn.txt;h=87161aedd19bb7bebd0621fda6c381f9a936b7f5;hb=20f50f1670c18173d74a34527b0c538c3fbbfde3;hp=a764d1f8ee52742b85ce8edff22814a32be82dfb;hpb=45bf473a7bc2c40c8aea3d34a0eab7a41e77a8ff;p=git.git diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index a764d1f8e..87161aedd 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -3,7 +3,7 @@ git-svn(1) NAME ---- -git-svn - bidirectional operation between a single Subversion branch and git +git-svn - Bidirectional operation between a single Subversion branch and git SYNOPSIS -------- @@ -11,58 +11,111 @@ SYNOPSIS DESCRIPTION ----------- -git-svn is a simple conduit for changesets between a single Subversion -branch and git. It is not to be confused with gitlink:git-svnimport[1]. -They were designed with very different goals in mind. +git-svn is a simple conduit for changesets between Subversion and git. +It is not to be confused with gitlink:git-svnimport[1], which is +read-only. -git-svn is designed for an individual developer who wants a +git-svn was originally designed for an individual developer who wants a bidirectional flow of changesets between a single branch in Subversion -and an arbitrary number of branches in git. git-svnimport is designed -for read-only operation on repositories that match a particular layout -(albeit the recommended one by SVN developers). +and an arbitrary number of branches in git. Since its inception, +git-svn has gained the ability to track multiple branches in a manner +similar to git-svnimport. -For importing svn, git-svnimport is potentially more powerful when -operating on repositories organized under the recommended -trunk/branch/tags structure, and should be faster, too. - -git-svn mostly ignores the very limited view of branching that -Subversion has. This allows git-svn to be much easier to use, -especially on repositories that are not organized in a manner that -git-svnimport is designed for. +git-svn is especially useful when it comes to tracking repositories +not organized in the way Subversion developers recommend (trunk, +branches, tags directories). COMMANDS -------- -- 'init':: - Creates an empty git repository with additional metadata - directories for git-svn. The Subversion URL must be specified - as a command-line argument. Optionally, the target directory - to operate on can be specified as a second argument. Normally - this command initializes the current directory. - -'fetch':: + Initializes an empty git repository with additional + metadata directories for git-svn. The Subversion URL + may be specified as a command-line argument, or as full + URL arguments to -T/-t/-b. Optionally, the target + directory to operate on can be specified as a second + argument. Normally this command initializes the current + directory. + +-T:: +--trunk=:: +-t:: +--tags=:: +-b:: +--branches=:: + These are optional command-line options for init. Each of + these flags can point to a relative repository path + (--tags=project/tags') or a full url + (--tags=https://foo.org/project/tags) -Fetch unfetched revisions from the Subversion URL we are -tracking. refs/remotes/git-svn will be updated to the -latest revision. +--no-metadata:: + Set the 'noMetadata' option in the [svn-remote] config. +--use-svm-props:: + Set the 'useSvmProps' option in the [svn-remote] config. +--use-svnsync-props:: + Set the 'useSvnsyncProps' option in the [svn-remote] config. +--rewrite-root=:: + Set the 'rewriteRoot' option in the [svn-remote] config. +--username=:: + For transports that SVN handles authentication for (http, + https, and plain svn), specify the username. For other + transports (eg svn+ssh://), you must include the username in + the URL, eg svn+ssh://foo@svn.bar.com/project + +--prefix= + This allows one to specify a prefix which is prepended + to the names of remotes if trunk/branches/tags are + specified. The prefix does not automatically include a + trailing slash, so be sure you include one in the + argument if that is what you want. This is useful if + you wish to track multiple projects that share a common + repository. -Note: You should never attempt to modify the remotes/git-svn -branch outside of git-svn. Instead, create a branch from -remotes/git-svn and work on that branch. Use the 'commit' -command (see below) to write git commits back to -remotes/git-svn. +'fetch':: -See '<>' if you are interested in -manually joining branches on commit. + Fetch unfetched revisions from the Subversion remote we are + tracking. The name of the [svn-remote "..."] section in the + .git/config file may be specified as an optional command-line + argument. + +'clone':: + Runs 'init' and 'fetch'. It will automatically create a + directory based on the basename of the URL passed to it; + or if a second argument is passed; it will create a directory + and work within that. It accepts all arguments that the + 'init' and 'fetch' commands accept; with the exception of + '--fetch-all'. After a repository is cloned, the 'fetch' + command will be able to update revisions without affecting + the working tree; and the 'rebase' command will be able + to update the working tree with the latest changes. + +'rebase':: + This fetches revisions from the SVN parent of the current HEAD + and rebases the current (uncommitted to SVN) work against it. + + This works similarly to 'svn update' or 'git-pull' except that + it preserves linear history with 'git-rebase' instead of + 'git-merge' for ease of dcommit-ing with git-svn. + + This accepts all options that 'git-svn fetch' and 'git-rebase' + accepts. However '--fetch-all' only fetches from the current + [svn-remote], and not all [svn-remote] definitions. + + Like 'git-rebase'; this requires that the working tree be clean + and have no uncommitted changes. 'dcommit':: - Commit all diffs from the current HEAD directly to the SVN + Commit each diff from a specified head directly to the SVN repository, and then rebase or reset (depending on whether or - not there is a diff between SVN and HEAD). It is recommended - that you run git-svn fetch and rebase (not pull) your commits - against the latest changes in the SVN repository. - This is advantageous over 'commit' (below) because it produces + not there is a diff between SVN and head). This will create + a revision in SVN for each commit in git. + It is recommended that you run git-svn fetch and rebase (not + pull or merge) your commits against the latest changes in the + SVN repository. + An optional command-line argument may be specified as an + alternative to HEAD. + This is advantageous over 'set-tree' (below) because it produces cleaner, more linear history. 'log':: @@ -87,7 +140,7 @@ manually joining branches on commit. Any other arguments are passed directly to `git log' -'commit':: +'set-tree':: You should consider using 'dcommit' instead of this command. Commit specified commit or tree objects to SVN. This relies on your imported fetch data being up-to-date. This makes @@ -96,16 +149,6 @@ manually joining branches on commit. commit. All merging is assumed to have taken place independently of git-svn functions. -'rebuild':: - Not a part of daily usage, but this is a useful command if - you've just cloned a repository (using gitlink:git-clone[1]) that was - tracked with git-svn. Unfortunately, git-clone does not clone - git-svn metadata and the svn working tree that git-svn uses for - its operations. This rebuilds the metadata so git-svn can - resume fetch operations. A Subversion URL may be optionally - specified at the command-line if the directory/repository you're - tracking has moved or changed protocols. - 'show-ignore':: Recursively finds and lists the svn:ignore property on directories. The output is suitable for appending to @@ -113,7 +156,7 @@ manually joining branches on commit. 'commit-diff':: Commits the diff of two tree-ish arguments from the - command-line. This command is intended for interopability with + command-line. This command is intended for interoperability with git-svnimport and does not rely on being inside an git-svn init-ed repository. This command takes three arguments, (a) the original tree to diff against, (b) the new tree result, (c) the @@ -122,55 +165,34 @@ manually joining branches on commit. repository (that has been init-ed with git-svn). The -r option is required for this. -'graft-branches':: - This command attempts to detect merges/branches from already - imported history. Techniques used currently include regexes, - file copies, and tree-matches). This command generates (or - modifies) the $GIT_DIR/info/grafts file. This command is - considered experimental, and inherently flawed because - merge-tracking in SVN is inherently flawed and inconsistent - across different repositories. - -'multi-init':: - This command supports git-svnimport-like command-line syntax for - importing repositories that are layed out as recommended by the - SVN folks. This is a bit more tolerant than the git-svnimport - command-line syntax and doesn't require the user to figure out - where the repository URL ends and where the repository path - begins. - -'multi-fetch':: - This runs fetch on all known SVN branches we're tracking. This - will NOT discover new branches (unlike git-svnimport), so - multi-init will need to be re-run (it's idempotent). - -- OPTIONS ------- -- ---shared:: +--shared[={false|true|umask|group|all|world|everybody}]:: --template=:: Only used with the 'init' command. - These are passed directly to gitlink:git-init-db[1]. + These are passed directly to gitlink:git-init[1]. -r :: --revision :: -Only used with the 'fetch' command. +Used with the 'fetch' command. -Takes any valid -r svn would accept and passes it -directly to svn. -r: ranges and "{" DATE "}" syntax -is also supported. This is passed directly to svn, see svn -documentation for more details. +This allows revision ranges for partial/cauterized history +to be supported. $NUMBER, $NUMBER1:$NUMBER2 (numeric ranges), +$NUMBER:HEAD, and BASE:$NUMBER are all supported. -This can allow you to make partial mirrors when running fetch. +This can allow you to make partial mirrors when running fetch; +but is generally not recommended because history will be skipped +and lost. -:: --stdin:: -Only used with the 'commit' command. +Only used with the 'set-tree' command. Read a list of commits from stdin and commit them in reverse order. Only the leading sha1 is read from each line, so @@ -178,7 +200,7 @@ git-rev-list --pretty=oneline output can be used. --rmdir:: -Only used with the 'dcommit', 'commit' and 'commit-diff' commands. +Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. Remove directories from the SVN tree if there are no files left behind. SVN can version empty directories, and they are not @@ -186,30 +208,30 @@ removed by default if there are no files left in them. git cannot version empty directories. Enabling this flag will make the commit to SVN act like git. -repo-config key: svn.rmdir +config key: svn.rmdir -e:: --edit:: -Only used with the 'dcommit', 'commit' and 'commit-diff' commands. +Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. Edit the commit message before committing to SVN. This is off by default for objects that are commits, and forced on when committing tree objects. -repo-config key: svn.edit +config key: svn.edit -l:: --find-copies-harder:: -Only used with the 'dcommit', 'commit' and 'commit-diff' commands. +Only used with the 'dcommit', 'set-tree' and 'commit-diff' commands. They are both passed directly to git-diff-tree see gitlink:git-diff-tree[1] for more information. [verse] -repo-config key: svn.l -repo-config key: svn.findcopiesharder +config key: svn.l +config key: svn.findcopiesharder -A:: --authors-file=:: @@ -227,12 +249,11 @@ will abort operation. The user will then have to add the appropriate entry. Re-running the previous git-svn command after the authors-file is modified should continue operation. -repo-config key: svn.authorsfile +config key: svn.authorsfile -q:: --quiet:: - Make git-svn less verbose. This only affects git-svn if you - have the SVN::* libraries installed and are using them. + Make git-svn less verbose. --repack[=]:: --repack-flags= @@ -245,15 +266,15 @@ repo-config key: svn.authorsfile --repack-flags are passed directly to gitlink:git-repack[1]. -repo-config key: svn.repack -repo-config key: svn.repackflags +config key: svn.repack +config key: svn.repackflags -m:: --merge:: -s:: --strategy=:: -These are only used with the 'dcommit' command. +These are only used with the 'dcommit' and 'rebase' commands. Passed directly to git-rebase when using 'dcommit' if a 'git-reset' cannot be used (see dcommit). @@ -272,233 +293,184 @@ ADVANCED OPTIONS ---------------- -- --b:: ---branch :: -Used with 'fetch' or 'commit'. - -This can be used to join arbitrary git branches to remotes/git-svn -on new commits where the tree object is equivalent. - -When used with different GIT_SVN_ID values, tags and branches in -SVN can be tracked this way, as can some merges where the heads -end up having completely equivalent content. This can even be -used to track branches across multiple SVN _repositories_. - -This option may be specified multiple times, once for each -branch. - -repo-config key: svn.branch - -i:: --id :: -This sets GIT_SVN_ID (instead of using the environment). See the -section on -'<>' -for more information on using GIT_SVN_ID. +This sets GIT_SVN_ID (instead of using the environment). This +allows the user to override the default refname to fetch from +when tracking a single URL. The 'log' and 'dcommit' commands +no longer require this switch as an argument. + +-R:: +--svn-remote :: + Specify the [svn-remote ""] section to use, + this allows SVN multiple repositories to be tracked. + Default: "svn" --follow-parent:: This is especially helpful when we're tracking a directory that has been moved around within the repository, or if we started tracking a branch and never tracked the trunk it was - descended from. - - This relies on the SVN::* libraries to work. - -repo-config key: svn.followparent - ---no-metadata:: - This gets rid of the git-svn-id: lines at the end of every commit. + descended from. This feature is enabled by default, use + --no-follow-parent to disable it. - With this, you lose the ability to use the rebuild command. If - you ever lose your .git/svn/git-svn/.rev_db file, you won't be - able to fetch again, either. This is fine for one-shot imports. - - The 'git-svn log' command will not work on repositories using this, - either. - -repo-config key: svn.nometadata +config key: svn.followparent -- - -COMPATIBILITY OPTIONS ---------------------- +CONFIG FILE-ONLY OPTIONS +------------------------ -- ---upgrade:: -Only used with the 'rebuild' command. - -Run this if you used an old version of git-svn that used -"git-svn-HEAD" instead of "remotes/git-svn" as the branch -for tracking the remote. - ---no-ignore-externals:: -Only used with the 'fetch' and 'rebuild' command. - -This command has no effect when you are using the SVN::* -libraries with git, svn:externals are always avoided. - -By default, git-svn passes --ignore-externals to svn to avoid -fetching svn:external trees into git. Pass this flag to enable -externals tracking directly via git. - -Versions of svn that do not support --ignore-externals are -automatically detected and this flag will be automatically -enabled for them. - -Otherwise, do not enable this flag unless you know what you're -doing. - -repo-config key: svn.noignoreexternals - ---ignore-nodate:: -Only used with the 'fetch' command. - -By default git-svn will crash if it tries to import a revision -from SVN which has '(no date)' listed as the date of the revision. -This is repository corruption on SVN's part, plain and simple. -But sometimes you really need those revisions anyway. +svn.noMetadata:: +svn-remote..noMetadata:: + This gets rid of the git-svn-id: lines at the end of every commit. -If supplied git-svn will convert '(no date)' entries to the UNIX -epoch (midnight on Jan. 1, 1970). Yes, that's probably very wrong. -SVN was very wrong. + If you lose your .git/svn/git-svn/.rev_db file, git-svn will not + be able to rebuild it and you won't be able to fetch again, + either. This is fine for one-shot imports. + + The 'git-svn log' command will not work on repositories using + this, either. Using this conflicts with the 'useSvmProps' + option for (hopefully) obvious reasons. + +svn.useSvmProps:: +svn-remote..useSvmProps:: + This allows git-svn to re-map repository URLs and UUIDs from + mirrors created using SVN::Mirror (or svk) for metadata. + + If an SVN revision has a property, "svm:headrev", it is likely + that the revision was created by SVN::Mirror (also used by SVK). + The property contains a repository UUID and a revision. We want + to make it look like we are mirroring the original URL, so + introduce a helper function that returns the original identity + URL and UUID, and use it when generating metadata in commit + messages. + +svn.useSvnsyncProps:: +svn-remote..useSvnsyncprops:: + Similar to the useSvmProps option; this is for users + of the svnsync(1) command distributed with SVN 1.4.x and + later. + +svn-remote..rewriteRoot:: + This allows users to create repositories from alternate + URLs. For example, an administrator could run git-svn on the + server locally (accessing via file://) but wish to distribute + the repository with a public http:// or svn:// URL in the + metadata so users of it will see the public URL. + +Since the noMetadata, rewriteRoot, useSvnsyncProps and useSvmProps +options all affect the metadata generated and used by git-svn; they +*must* be set in the configuration file before any history is imported +and these settings should never be changed once they are set. + +Additionally, only one of these four options can be used per-svn-remote +section because they affect the 'git-svn-id:' metadata line. -- Basic Examples ~~~~~~~~~~~~~~ -Tracking and contributing to an Subversion managed-project: +Tracking and contributing to a the trunk of a Subversion-managed project: ------------------------------------------------------------------------ -# Initialize a repo (like git init-db): - git-svn init http://svn.foo.org/project/trunk -# Fetch remote revisions: - git-svn fetch -# Create your own branch to hack on: - git checkout -b my-branch remotes/git-svn -# Commit only the git commits you want to SVN: - git-svn commit [ ...] -# Commit all the git commits from my-branch that don't exist in SVN: - git-svn commit remotes/git-svn..my-branch -# Something is committed to SVN, rebase the latest into your branch: - git-svn fetch && git rebase remotes/git-svn +# Clone a repo (like git clone): + git-svn clone http://svn.foo.org/project/trunk +# Enter the newly cloned directory: + cd trunk +# You should be on master branch, double-check with git-branch + git branch +# Do some work and commit locally to git: + git commit ... +# Something is committed to SVN, rebase your local changes against the +# latest changes in SVN: + git-svn rebase +# Now commit your changes (that were committed previously using git) to SVN, +# as well as automatically updating your working HEAD: + git-svn dcommit # Append svn:ignore settings to the default git exclude file: git-svn show-ignore >> .git/info/exclude ------------------------------------------------------------------------ -REBASE VS. PULL ---------------- +Tracking and contributing to an entire Subversion-managed project +(complete with a trunk, tags and branches): + +------------------------------------------------------------------------ +# Clone a repo (like git clone): + git-svn clone http://svn.foo.org/project -T trunk -b branches -t tags +# View all branches and tags you have cloned: + git branch -r +# Reset your master to trunk (or any other branch, replacing 'trunk' +# with the appropriate name): + git reset --hard remotes/trunk +# You may only dcommit to one branch/tag/trunk at a time. The usage +# of dcommit/rebase/show-ignore should be the same as above. +------------------------------------------------------------------------ + +REBASE VS. PULL/MERGE +--------------------- Originally, git-svn recommended that the remotes/git-svn branch be -pulled from. This is because the author favored 'git-svn commit B' -to commit a single head rather than the 'git-svn commit A..B' notation -to commit multiple commits. +pulled or merged from. This is because the author favored +'git-svn set-tree B' to commit a single head rather than the +'git-svn set-tree A..B' notation to commit multiple commits. -If you use 'git-svn commit A..B' to commit several diffs and you do not -have the latest remotes/git-svn merged into my-branch, you should use -'git rebase' to update your work branch instead of 'git pull'. 'pull' -can cause non-linear history to be flattened when committing into SVN, -which can lead to merge commits reversing previous commits in SVN. +If you use 'git-svn set-tree A..B' to commit several diffs and you do +not have the latest remotes/git-svn merged into my-branch, you should +use 'git-svn rebase' to update your work branch instead of 'git pull' or +'git merge'. 'pull/merge' can cause non-linear history to be flattened +when committing into SVN, which can lead to merge commits reversing +previous commits in SVN. DESIGN PHILOSOPHY ----------------- Merge tracking in Subversion is lacking and doing branched development -with Subversion is cumbersome as a result. git-svn completely forgoes -any automated merge/branch tracking on the Subversion side and leaves it -entirely up to the user on the git side. It's simply not worth it to do -a useful translation when the original signal is weak. - -[[tracking-multiple-repos]] -TRACKING MULTIPLE REPOSITORIES OR BRANCHES ------------------------------------------- -This is for advanced users, most users should ignore this section. - -Because git-svn does not care about relationships between different -branches or directories in a Subversion repository, git-svn has a simple -hack to allow it to track an arbitrary number of related _or_ unrelated -SVN repositories via one git repository. Simply set the GIT_SVN_ID -environment variable to a name other other than "git-svn" (the default) -and git-svn will ignore the contents of the $GIT_DIR/svn/git-svn directory -and instead do all of its work in $GIT_DIR/svn/$GIT_SVN_ID for that -invocation. The interface branch will be remotes/$GIT_SVN_ID, instead of -remotes/git-svn. Any remotes/$GIT_SVN_ID branch should never be modified -by the user outside of git-svn commands. - -[[fetch-args]] -ADDITIONAL FETCH ARGUMENTS --------------------------- -This is for advanced users, most users should ignore this section. - -Unfetched SVN revisions may be imported as children of existing commits -by specifying additional arguments to 'fetch'. Additional parents may -optionally be specified in the form of sha1 hex sums at the -command-line. Unfetched SVN revisions may also be tied to particular -git commits with the following syntax: - ------------------------------------------------- - svn_revision_number=git_commit_sha1 ------------------------------------------------- - -This allows you to tie unfetched SVN revision 375 to your current HEAD: - ------------------------------------------------- - git-svn fetch 375=$(git-rev-parse HEAD) ------------------------------------------------- - -Advanced Example: Tracking a Reorganized Repository -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Note: this example is now obsolete if you have SVN::* libraries -installed. Simply use --follow-parent when fetching. - -If you're tracking a directory that has moved, or otherwise been -branched or tagged off of another directory in the repository and you -care about the full history of the project, then you can read this -section. - -This is how Yann Dirson tracked the trunk of the ufoai directory when -the /trunk directory of his repository was moved to /ufoai/trunk and -he needed to continue tracking /ufoai/trunk where /trunk left off. - ------------------------------------------------------------------------- - # This log message shows when the repository was reorganized: - r166 | ydirson | 2006-03-02 01:36:55 +0100 (Thu, 02 Mar 2006) | 1 line - Changed paths: - D /trunk - A /ufoai/trunk (from /trunk:165) - - # First we start tracking the old revisions: - GIT_SVN_ID=git-oldsvn git-svn init \ - https://svn.sourceforge.net/svnroot/ufoai/trunk - GIT_SVN_ID=git-oldsvn git-svn fetch -r1:165 - - # And now, we continue tracking the new revisions: - GIT_SVN_ID=git-newsvn git-svn init \ - https://svn.sourceforge.net/svnroot/ufoai/ufoai/trunk - GIT_SVN_ID=git-newsvn git-svn fetch \ - 166=`git-rev-parse refs/remotes/git-oldsvn` ------------------------------------------------------------------------- +with Subversion is cumbersome as a result. git-svn does not do +automated merge/branch tracking by default and leaves it entirely up to +the user on the git side. git-svn does however follow copy +history of the directory that it is tracking, however (much like +how 'svn log' works). BUGS ---- -If you are not using the SVN::* Perl libraries and somebody commits a -conflicting changeset to SVN at a bad moment (right before you commit) -causing a conflict and your commit to fail, your svn working tree -($GIT_DIR/git-svn/tree) may be dirtied. The easiest thing to do is -probably just to rm -rf $GIT_DIR/git-svn/tree and run 'rebuild'. - -We ignore all SVN properties except svn:executable. Too difficult to -map them since we rely heavily on git write-tree being _exactly_ the -same on both the SVN and git working trees and I prefer not to clutter -working trees with metadata files. +We ignore all SVN properties except svn:executable. Any unhandled +properties are logged to $GIT_DIR/svn//unhandled.log Renamed and copied directories are not detected by git and hence not tracked when committing to SVN. I do not plan on adding support for this as it's quite difficult and time-consuming to get working for all -the possible corner cases (git doesn't do it, either). Renamed and -copied files are fully supported if they're similar enough for git to -detect them. +the possible corner cases (git doesn't do it, either). Committing +renamed and copied files are fully supported if they're similar enough +for git to detect them. + +CONFIGURATION +------------- + +git-svn stores [svn-remote] configuration information in the +repository .git/config file. It is similar the core git +[remote] sections except 'fetch' keys do not accept glob +arguments; but they are instead handled by the 'branches' +and 'tags' keys. Since some SVN repositories are oddly +configured with multiple projects glob expansions such those +listed below are allowed: + +------------------------------------------------------------------------ +[svn-remote "project-a"] + url = http://server.org/svn + branches = branches/*/project-a:refs/remotes/project-a/branches/* + tags = tags/*/project-a:refs/remotes/project-a/tags/* + trunk = trunk/project-a:refs/remotes/project-a/trunk +------------------------------------------------------------------------ + +Keep in mind that the '*' (asterisk) wildcard of the local ref +(left of the ':') *must* be the farthest right path component; +however the remote wildcard may be anywhere as long as it's own +independent path componet (surrounded by '/' or EOL). This +type of configuration is not automatically created by 'init' and +should be manually entered with a text-editor or using +gitlink:git-config[1] SEE ALSO --------