From 60786bd41a575126c0735c55b46e1d0ee2b358cc Mon Sep 17 00:00:00 2001 From: Nicolas Vigier Date: Mon, 30 Sep 2013 16:46:14 +0200 Subject: [PATCH 1/7] git-svn: fix signed commit parsing When parsing a commit object, git-svn wrongly think that a line containing spaces means the end of headers and the start of the commit message. In case of signed commit, the gpgsig entry contains a line with one space, so "git svn dcommit" will include part of the signature in the commit message. An example of such problem : http://svnweb.mageia.org/treasurer?view=revision&revision=86 This commit changes the regex to only match an empty line as separator between the headers and the commit message. Signed-off-by: Nicolas Vigier Reviewed-by: Jonathan Nieder Signed-off-by: Eric Wong --- git-svn.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index ff1ce3d35..1823db135 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1759,7 +1759,7 @@ sub get_commit_entry { my $msgbuf = ""; while (<$msg_fh>) { if (!$in_msg) { - $in_msg = 1 if (/^\s*$/); + $in_msg = 1 if (/^$/); $author = $1 if (/^author (.*>)/); } elsif (/^git-svn-id: /) { # skip this for now, we regenerate the From 9ebeb3392b6dd674d738cfa019364f61ab73b925 Mon Sep 17 00:00:00 2001 From: Keshav Kini Date: Sun, 29 Sep 2013 18:45:57 -0500 Subject: [PATCH 2/7] git-svn.txt: fix AsciiDoc formatting error As asterisks are used to indicate bold text in AsciiDoc, shell glob expressions must be escaped appropriately. Signed-off-by: Keshav Kini Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 4dd3bcb51..239c33c8f 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -684,7 +684,7 @@ svn-remote..noMetadata:: + This option can only be used for one-shot imports as 'git svn' will not be able to fetch again without metadata. Additionally, -if you lose your .git/svn/**/.rev_map.* files, 'git svn' will not +if you lose your .git/svn/\*\*/.rev_map.* files, 'git svn' will not be able to rebuild them. + The 'git svn log' command will not work on repositories using From e618c3960a07ec411466ee5aa4e87ea091a72b94 Mon Sep 17 00:00:00 2001 From: Keshav Kini Date: Sun, 29 Sep 2013 18:45:58 -0500 Subject: [PATCH 3/7] git-svn.txt: reword description of gc command It's redundant to say that $GIT_DIR/svn//unhandled.log or $GIT_DIR/svn//index is in .git/svn when $GIT_DIR is '.git', and is wrong when $GIT_DIR is not '.git' Also, a '/' was missing from the pathname $GIT_DIR/svn//index . Signed-off-by: Keshav Kini Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 239c33c8f..62ec72719 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -435,8 +435,8 @@ Any other arguments are passed directly to 'git log' specific revision. 'gc':: - Compress $GIT_DIR/svn//unhandled.log files in .git/svn - and remove $GIT_DIR/svn/index files in .git/svn. + Compress $GIT_DIR/svn//unhandled.log files and remove + $GIT_DIR/svn//index files. 'reset':: Undoes the effects of 'fetch' back to the specified revision. From 6fe7a30aec23eb8082f00b614dde3603b0754646 Mon Sep 17 00:00:00 2001 From: Keshav Kini Date: Sun, 29 Sep 2013 18:45:59 -0500 Subject: [PATCH 4/7] git-svn.txt: replace .git with $GIT_DIR As $GIT_DIR may not equal '.git', it's usually more generally correct to refer to files in $GIT_DIR rather than in .git . This will also allow me to link some of the occurrences of '.git' in git-svn.txt to a new reference target inside this file in an upcoming commit, because in AsciiDoc definitions apparently can't start with a '.' character. Signed-off-by: Keshav Kini Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 62ec72719..3ddf54560 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -104,8 +104,8 @@ COMMANDS 'fetch':: 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. + $GIT_DIR/config file may be specified as an optional + command-line argument. --localtime;; Store Git commit times in the local timezone instead of UTC. This @@ -684,7 +684,7 @@ svn-remote..noMetadata:: + This option can only be used for one-shot imports as 'git svn' will not be able to fetch again without metadata. Additionally, -if you lose your .git/svn/\*\*/.rev_map.* files, 'git svn' will not +if you lose your $GIT_DIR/svn/\*\*/.rev_map.* files, 'git svn' will not be able to rebuild them. + The 'git svn log' command will not work on repositories using @@ -977,8 +977,8 @@ When using multiple --branches or --tags, 'git svn' does not automatically handle name collisions (for example, if two branches from different paths have the same name, or if a branch and a tag have the same name). In these cases, use 'init' to set up your Git repository then, before your first 'fetch', edit -the .git/config file so that the branches and tags are associated with -different name spaces. For example: +the $GIT_DIR/config file so that the branches and tags are associated +with different name spaces. For example: branches = stable/*:refs/remotes/svn/stable/* branches = debug/*:refs/remotes/svn/debug/* @@ -1006,7 +1006,7 @@ CONFIGURATION ------------- 'git svn' stores [svn-remote] configuration information in the -repository .git/config file. It is similar the core Git +repository $GIT_DIR/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 @@ -1060,8 +1060,8 @@ $ git svn branch -d branches/server release-2-3-0 Note that git-svn keeps track of the highest revision in which a branch or tag has appeared. If the subset of branches or tags is changed after -fetching, then .git/svn/.metadata must be manually edited to remove (or -reset) branches-maxRev and/or tags-maxRev as appropriate. +fetching, then $GIT_DIR/svn/.metadata must be manually edited to remove +(or reset) branches-maxRev and/or tags-maxRev as appropriate. SEE ALSO -------- From 945b9c14ffd3e11c916ee2b2428a0b2be9645829 Mon Sep 17 00:00:00 2001 From: Keshav Kini Date: Sun, 29 Sep 2013 18:46:00 -0500 Subject: [PATCH 5/7] git-svn.txt: elaborate on rev_map files The man page for `git svn` describes a situation in which "'git svn' will not be able to rebuild" your $GIT_DIR/svn/**/.rev_map* files, but no mention is made of in what circumstances `git svn` *will* be able to do so, how to get `git svn` to do so, or even what these files are. This patch adds a FILES section to the man page with a description of what $GIT_DIR/svn/**/.rev_map* files are and how they are (re)built, and links to this description from various other parts of the man page. Signed-off-by: Keshav Kini Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 3ddf54560..5383496cb 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -106,6 +106,9 @@ COMMANDS tracking. The name of the [svn-remote "..."] section in the $GIT_DIR/config file may be specified as an optional command-line argument. ++ +This automatically updates the rev_map if needed (see +'$GIT_DIR/svn/\*\*/.rev_map.*' in the FILES section below for details). --localtime;; Store Git commit times in the local timezone instead of UTC. This @@ -201,6 +204,9 @@ accept. However, '--fetch-all' only fetches from the current + Like 'git rebase'; this requires that the working tree be clean and have no uncommitted changes. ++ +This automatically updates the rev_map if needed (see +'$GIT_DIR/svn/\*\*/.rev_map.*' in the FILES section below for details). -l;; --local;; @@ -449,9 +455,10 @@ Any other arguments are passed directly to 'git log' file cannot be ignored forever (with --ignore-paths) the only way to repair the repo is to use 'reset'. + -Only the rev_map and refs/remotes/git-svn are changed. Follow 'reset' -with a 'fetch' and then 'git reset' or 'git rebase' to move local -branches onto the new tree. +Only the rev_map and refs/remotes/git-svn are changed (see +'$GIT_DIR/svn/\*\*/.rev_map.*' in the FILES section below for details). +Follow 'reset' with a 'fetch' and then 'git reset' or 'git rebase' to +move local branches onto the new tree. -r ;; --revision=;; @@ -684,7 +691,7 @@ svn-remote..noMetadata:: + This option can only be used for one-shot imports as 'git svn' will not be able to fetch again without metadata. Additionally, -if you lose your $GIT_DIR/svn/\*\*/.rev_map.* files, 'git svn' will not +if you lose your '$GIT_DIR/svn/\*\*/.rev_map.*' files, 'git svn' will not be able to rebuild them. + The 'git svn log' command will not work on repositories using @@ -1063,6 +1070,19 @@ or tag has appeared. If the subset of branches or tags is changed after fetching, then $GIT_DIR/svn/.metadata must be manually edited to remove (or reset) branches-maxRev and/or tags-maxRev as appropriate. +FILES +----- +$GIT_DIR/svn/\*\*/.rev_map.*:: + Mapping between Subversion revision numbers and Git commit + names. In a repository where the noMetadata option is not set, + this can be rebuilt from the git-svn-id: lines that are at the + end of every commit (see the 'svn.noMetadata' section above for + details). ++ +'git svn fetch' and 'git svn rebase' automatically update the rev_map +if it is missing or not up to date. 'git svn reset' automatically +rewinds it. + SEE ALSO -------- linkgit:git-rebase[1] From 7091a2d0bfdea5a8e1c77027d746e06ae384bffa Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Fri, 11 Oct 2013 14:57:05 +0200 Subject: [PATCH 6/7] Documentation/git-svn: Promote the use of --prefix in docs + examples Currently, the git-svn defaults to using an empty prefix, which ends up placing the SVN-tracking refs directly in refs/remotes/*. This placement runs counter to Git's convention of placing remote-tracking branches in refs/remotes/$remote/*. Furthermore, combining git-svn with "regular" Git remotes run the risk of clobbering refs under refs/remotes (e.g. if you have a git remote called "tags" with a "v1" branch, it will overlap with the git-svn's tracking branch for the "v1" tag from Subversion. Even though the git-svn refs stored in refs/remotes/* are not "proper" remote-tracking branches (since they are not covered by a proper git remote's refspec), they clearly represent a similar concept, and would benefit from following the same convention. For example, if git-svn tracks Subversion branch "foo" at refs/remotes/foo, and you create a local branch refs/heads/foo to add some commits to be pushed back to Subversion (using "git svn dcommit), then it is clearly unhelpful of Git to throw warning: refname 'foo' is ambiguous. every time you checkout, rebase, or otherwise interact with the branch. At this time, the user is better off using the --prefix=foo/ (the trailing slash is important) to git svn init/clone, to cause the SVN-tracking refs to be placed at refs/remotes/foo/* instead of refs/remotes/*. This patch updates the documentation to encourage use of --prefix. This is also in preparation for changing the default value of --prefix at some point in the future. Cc: Eric Wong Signed-off-by: Johan Herland Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 5383496cb..f1417deb9 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -79,8 +79,13 @@ COMMANDS trailing slash, so be sure you include one in the argument if that is what you want. If --branches/-b is specified, the prefix must include a trailing slash. - Setting a prefix is useful if you wish to track multiple - projects that share a common repository. + Setting a prefix (with a trailing slash) is strongly + encouraged in any case, as your SVN-tracking refs will + then be located at "refs/remotes/$prefix/*", which is + compatible with Git's own remote-tracking ref layout + (refs/remotes/$remote/*). Setting a prefix is also useful + if you wish to track multiple projects that share a common + repository. --ignore-paths=;; When passed to 'init' or 'clone' this regular expression will be preserved as a config key. See 'fetch' for a description @@ -811,16 +816,16 @@ Tracking and contributing to an entire Subversion-managed project ------------------------------------------------------------------------ # Clone a repo with standard SVN directory layout (like git clone): - git svn clone http://svn.example.com/project --stdlayout + git svn clone http://svn.example.com/project --stdlayout --prefix svn/ # Or, if the repo uses a non-standard directory layout: - git svn clone http://svn.example.com/project -T tr -b branch -t tag + git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/ # View all branches and tags you have cloned: git branch -r # Create a new branch in SVN git svn branch waldo # Reset your master to trunk (or any other branch, replacing 'trunk' # with the appropriate name): - git reset --hard remotes/trunk + git reset --hard svn/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. ------------------------------------------------------------------------ @@ -834,7 +839,7 @@ have each person clone that repository with 'git clone': ------------------------------------------------------------------------ # Do the initial import on a server - ssh server "cd /pub && git svn clone http://svn.example.com/project + ssh server "cd /pub && git svn clone http://svn.example.com/project [options...]" # Clone locally - make sure the refs/remotes/ space matches the server mkdir project cd project @@ -847,8 +852,9 @@ have each person clone that repository with 'git clone': git config --remove-section remote.origin # Create a local branch from one of the branches just fetched git checkout -b master FETCH_HEAD -# Initialize 'git svn' locally (be sure to use the same URL and -T/-b/-t options as were used on server) - git svn init http://svn.example.com/project +# Initialize 'git svn' locally (be sure to use the same URL and +# --stdlayout/-T/-b/-t/--prefix options as were used on server) + git svn init http://svn.example.com/project [options...] # Pull the latest changes from Subversion git svn rebase ------------------------------------------------------------------------ @@ -980,6 +986,15 @@ without giving any repository layout options. If the full history with branches and tags is required, the options '--trunk' / '--branches' / '--tags' must be used. +When using the options for describing the repository layout (--trunk, +--tags, --branches, --stdlayout), please also specify the --prefix +option (e.g. '--prefix=origin/') to cause your SVN-tracking refs to be +placed at refs/remotes/origin/* rather than the default refs/remotes/*. +The former is more compatible with the layout of Git's "regular" +remote-tracking refs (refs/remotes/$remote/*), and may potentially +prevent similarly named SVN branches and Git remotes from clobbering +each other. + When using multiple --branches or --tags, 'git svn' does not automatically handle name collisions (for example, if two branches from different paths have the same name, or if a branch and a tag have the same name). In these cases, @@ -1042,8 +1057,8 @@ comma-separated list of names within braces. For example: [svn-remote "huge-project"] url = http://server.org/svn fetch = trunk/src:refs/remotes/trunk - branches = branches/{red,green}/src:refs/remotes/branches/* - tags = tags/{1.0,2.0}/src:refs/remotes/tags/* + branches = branches/{red,green}/src:refs/remotes/project-a/branches/* + tags = tags/{1.0,2.0}/src:refs/remotes/project-a/tags/* ------------------------------------------------------------------------ Multiple fetch, branches, and tags keys are supported: From f849bb6b3b4ccc7cc1a68f49d6ff1e9c508fdf17 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Fri, 11 Oct 2013 14:57:06 +0200 Subject: [PATCH 7/7] git-svn: Warn about changing default for --prefix in Git v2.0 In Git v2.0, we will change the default --prefix for init/clone from none/empty to "origin/" (which causes SVN-tracking branches to be placed at refs/remotes/origin/* instead of refs/remotes/*). This patch warns users about the upcoming change, both in the git-svn manual page, and on stderr when running init/clone in the "multi-mode" without providing a --prefix. Cc: Eric Wong Signed-off-by: Johan Herland Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 11 +++++- git-svn.perl | 12 ++++++- t/t9117-git-svn-init-clone.sh | 67 +++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index f1417deb9..2a3847649 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -86,6 +86,14 @@ COMMANDS (refs/remotes/$remote/*). Setting a prefix is also useful if you wish to track multiple projects that share a common repository. ++ +NOTE: In Git v2.0, the default prefix will CHANGE from "" (no prefix) +to "origin/". This is done to put SVN-tracking refs at +"refs/remotes/origin/*" instead of "refs/remotes/*", and make them +more compatible with how Git's own remote-tracking refs are organized +(i.e. refs/remotes/$remote/*). You can enjoy the same benefits today, +by using the --prefix option. + --ignore-paths=;; When passed to 'init' or 'clone' this regular expression will be preserved as a config key. See 'fetch' for a description @@ -993,7 +1001,8 @@ placed at refs/remotes/origin/* rather than the default refs/remotes/*. The former is more compatible with the layout of Git's "regular" remote-tracking refs (refs/remotes/$remote/*), and may potentially prevent similarly named SVN branches and Git remotes from clobbering -each other. +each other. In Git v2.0 the default prefix used (i.e. when no --prefix +is given) will change from "" (no prefix) to "origin/". When using multiple --branches or --tags, 'git svn' does not automatically handle name collisions (for example, if two branches from different paths have diff --git a/git-svn.perl b/git-svn.perl index 1823db135..7349ffea5 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1389,7 +1389,17 @@ sub cmd_multi_init { usage(1); } - $_prefix = '' unless defined $_prefix; + unless (defined $_prefix) { + $_prefix = ''; + warn <warning && + test_must_fail grep -q prefix warning && + rm -rf trunk && + rm -f warning + ' + +test_expect_success 'clone without -s/-T/-b/-t does not warn' ' + test ! -d trunk && + git svn clone "$svnrepo"/project/trunk 2>warning && + test_must_fail grep -q prefix warning && + rm -rf trunk && + rm -f warning + ' + +test_svn_configured_prefix () { + prefix=$1 && + cat >expect <>actual && + git --git-dir=project/.git config svn-remote.svn.branches >>actual && + git --git-dir=project/.git config svn-remote.svn.tags >>actual && + test_cmp expect actual && + rm -f expect actual +} + +test_expect_success 'init with -s/-T/-b/-t without --prefix warns' ' + test ! -d project && + git svn init -s "$svnrepo"/project project 2>warning && + grep -q prefix warning && + test_svn_configured_prefix "" && + rm -rf project && + rm -f warning + ' + +test_expect_success 'clone with -s/-T/-b/-t without --prefix warns' ' + test ! -d project && + git svn clone -s "$svnrepo"/project 2>warning && + grep -q prefix warning && + test_svn_configured_prefix "" && + rm -rf project && + rm -f warning + ' + +test_expect_success 'init with -s/-T/-b/-t and --prefix does not warn' ' + test ! -d project && + git svn init -s "$svnrepo"/project project --prefix="" 2>warning && + test_must_fail grep -q prefix warning && + test_svn_configured_prefix "" && + rm -rf project && + rm -f warning + ' + +test_expect_success 'clone with -s/-T/-b/-t and --prefix does not warn' ' + test ! -d project && + git svn clone -s "$svnrepo"/project --prefix="" 2>warning && + test_must_fail grep -q prefix warning && + test_svn_configured_prefix "" && + rm -rf project && + rm -f warning + ' + test_done