{"thread":{"id":"3516","subject":"[PATCH] contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD","startedAt":"2006-03-02T05:58:31Z","lastAt":"2006-03-02T21:17:03Z","messageCount":3,"participants":["Eric Wong","Nicolas Vilz 'niv'"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"17019","messageId":"20060302055831.GA16600@localdomain","threadId":"3516","inReplyTo":null,"subject":"[PATCH] contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-03-02T05:58:31Z","receivedAt":"2006-03-02T05:58:31Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"After reading a lengthy discussion on the list, I've come to the\nconclusion that creating a 'remotes' directory in refs isn't\nsuch a bad idea.\n\nYou can still branch from it by specifying remotes/git-svn (not\nneeding the leading 'refs/'), and the documentation has been\nupdated to reflect that.\n\nThe 'git-svn' part of the ref can of course be set to whatever\nyou want by using the GIT_SVN_ID environment variable, as\nbefore.\n\nI'm using refs/remotes/git-svn, and not going with something\nlike refs/remotes/git-svn/HEAD as it's redundant for Subversion\nwhere there's zero distinction between branches and directories.\n\nRun git-svn rebuild --upgrade to upgrade your repository to use\nthe new head.  git-svn-HEAD must be manually deleted for safety\nreasons.\n\nSide note: if you ever (and I hope you never) want to run\ngit-update-refs on a 'remotes/' ref, make sure you have the\n'refs/' prefix as you don't want to be clobbering your\n'remotes/' in $GIT_DIR (where remote URLs are stored).\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n\n---\n\n contrib/git-svn/git-svn.perl               |   63 +++++++++++++++++++++++-----\n contrib/git-svn/git-svn.txt                |   18 ++++----\n contrib/git-svn/t/t0000-contrib-git-svn.sh |   36 ++++++++--------\n 3 files changed, 78 insertions(+), 39 deletions(-)\n\n98158fd226f764a4d20a4a66b651f3a154a92bf2\ndiff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl\nindex 0b74165..0e092c5 100755\n--- a/contrib/git-svn/git-svn.perl\n+++ b/contrib/git-svn/git-svn.perl\n@@ -34,13 +34,14 @@ use POSIX qw/strftime/;\n my $sha1 = qr/[a-f\\d]{40}/;\n my $sha1_short = qr/[a-f\\d]{6,40}/;\n my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,\n-\t$_find_copies_harder, $_l, $_version);\n+\t$_find_copies_harder, $_l, $_version, $_upgrade);\n \n GetOptions(\t'revision|r=s' => \\$_revision,\n \t\t'no-ignore-externals' => \\$_no_ignore_ext,\n \t\t'stdin|' => \\$_stdin,\n \t\t'edit|e' => \\$_edit,\n \t\t'rmdir' => \\$_rmdir,\n+\t\t'upgrade' => \\$_upgrade,\n \t\t'help|H|h' => \\$_help,\n \t\t'find-copies-harder' => \\$_find_copies_harder,\n \t\t'l=i' => \\$_l,\n@@ -106,13 +107,18 @@ sub rebuild {\n \t$SVN_URL = shift or undef;\n \tmy $repo_uuid;\n \tmy $newest_rev = 0;\n+\tif ($_upgrade) {\n+\t\tsys('git-update-ref',\"refs/remotes/$GIT_SVN\",\"$GIT_SVN-HEAD\");\n+\t} else {\n+\t\tcheck_upgrade_needed();\n+\t}\n \n \tmy $pid = open(my $rev_list,'-|');\n \tdefined $pid or croak $!;\n \tif ($pid == 0) {\n-\t\texec(\"git-rev-list\",\"$GIT_SVN-HEAD\") or croak $!;\n+\t\texec(\"git-rev-list\",\"refs/remotes/$GIT_SVN\") or croak $!;\n \t}\n-\tmy $first;\n+\tmy $latest;\n \twhile (<$rev_list>) {\n \t\tchomp;\n \t\tmy $c = $_;\n@@ -132,18 +138,20 @@ sub rebuild {\n \t\t\t\t\t\"$c, $id\\n\";\n \t\t\t}\n \t\t}\n+\n+\t\t# if we merged or otherwise started elsewhere, this is\n+\t\t# how we break out of it\n+\t\tnext if (defined $repo_uuid && ($uuid ne $repo_uuid));\n+\t\tnext if (defined $SVN_URL && ($url ne $SVN_URL));\n+\n \t\tprint \"r$rev = $c\\n\";\n-\t\tunless (defined $first) {\n+\t\tunless (defined $latest) {\n \t\t\tif (!$SVN_URL && !$url) {\n \t\t\t\tcroak \"SVN repository location required: $url\\n\";\n \t\t\t}\n \t\t\t$SVN_URL ||= $url;\n-\t\t\t$repo_uuid = setup_git_svn();\n-\t\t\t$first = $rev;\n-\t\t}\n-\t\tif ($uuid ne $repo_uuid) {\n-\t\t\tcroak \"Repository UUIDs do not match!\\ngot: $uuid\\n\",\n-\t\t\t\t\t\t\"expected: $repo_uuid\\n\";\n+\t\t\t$repo_uuid ||= setup_git_svn();\n+\t\t\t$latest = $rev;\n \t\t}\n \t\tassert_revision_eq_or_unknown($rev, $c);\n \t\tsys('git-update-ref',\"$GIT_SVN/revs/$rev\",$c);\n@@ -151,7 +159,7 @@ sub rebuild {\n \t}\n \tclose $rev_list or croak $?;\n \tif (!chdir $SVN_WC) {\n-\t\tmy @svn_co = ('svn','co',\"-r$first\");\n+\t\tmy @svn_co = ('svn','co',\"-r$latest\");\n \t\tpush @svn_co, '--ignore-externals' unless $_no_ignore_ext;\n \t\tsys(@svn_co, $SVN_URL, $SVN_WC);\n \t\tchdir $SVN_WC or croak $!;\n@@ -168,6 +176,13 @@ sub rebuild {\n \t\texec('git-write-tree');\n \t}\n \twaitpid $pid, 0;\n+\n+\tif ($_upgrade) {\n+\t\tprint STDERR <<\"\";\n+Keeping deprecated refs/head/$GIT_SVN-HEAD for now.  Please remove it\n+when you have upgraded your tools and habits to use refs/remotes/$GIT_SVN\n+\n+\t}\n }\n \n sub init {\n@@ -180,6 +195,7 @@ sub init {\n \n sub fetch {\n \tmy (@parents) = @_;\n+\tcheck_upgrade_needed();\n \t$SVN_URL ||= file_to_s(\"$GIT_DIR/$GIT_SVN/info/url\");\n \tmy @log_args = -d $SVN_WC ? ($SVN_WC) : ($SVN_URL);\n \tunless ($_revision) {\n@@ -222,6 +238,7 @@ sub fetch {\n \n sub commit {\n \tmy (@commits) = @_;\n+\tcheck_upgrade_needed();\n \tif ($_stdin || !@commits) {\n \t\tprint \"Reading from stdin...\\n\";\n \t\t@commits = ();\n@@ -863,7 +880,7 @@ sub git_commit {\n \tif ($commit !~ /^$sha1$/o) {\n \t\tcroak \"Failed to commit, invalid sha1: $commit\\n\";\n \t}\n-\tmy @update_ref = ('git-update-ref',\"refs/heads/$GIT_SVN-HEAD\",$commit);\n+\tmy @update_ref = ('git-update-ref',\"refs/remotes/$GIT_SVN\",$commit);\n \tif (my $primary_parent = shift @exec_parents) {\n \t\tpush @update_ref, $primary_parent;\n \t}\n@@ -936,6 +953,28 @@ sub svn_check_ignore_externals {\n \t\t$_no_ignore_ext = 1;\n \t}\n }\n+\n+sub check_upgrade_needed {\n+\tmy $old = eval {\n+\t\tmy $pid = open my $child, '-|';\n+\t\tdefined $pid or croak $!;\n+\t\tif ($pid == 0) {\n+\t\t\tclose STDERR;\n+\t\t\texec('git-rev-parse',\"$GIT_SVN-HEAD\") or croak $?;\n+\t\t}\n+\t\tmy @ret = (<$child>);\n+\t\tclose $child or croak $?;\n+\t\tdie $? if $?; # just in case close didn't error out\n+\t\treturn wantarray ? @ret : join('',@ret);\n+\t};\n+\treturn unless $old;\n+\tmy $head = eval { safe_qx('git-rev-parse',\"refs/remotes/$GIT_SVN\") };\n+\tif ($@ || !$head) {\n+\t\tprint STDERR \"Please run: $0 rebuild --upgrade\\n\";\n+\t\texit 1;\n+\t}\n+}\n+\n __END__\n \n Data structures:\ndiff --git a/contrib/git-svn/git-svn.txt b/contrib/git-svn/git-svn.txt\nindex b290739..4102deb 100644\n--- a/contrib/git-svn/git-svn.txt\n+++ b/contrib/git-svn/git-svn.txt\n@@ -41,12 +41,12 @@ init::\n \n fetch::\n \tFetch unfetched revisions from the SVN_URL we are tracking.\n-\trefs/heads/git-svn-HEAD will be updated to the latest revision.\n+\trefs/heads/remotes/git-svn will be updated to the latest revision.\n \n-\tNote: You should never attempt to modify the git-svn-HEAD branch\n-\toutside of git-svn.  Instead, create a branch from git-svn-HEAD\n+\tNote: You should never attempt to modify the remotes/git-svn branch\n+\toutside of git-svn.  Instead, create a branch from remotes/git-svn\n \tand work on that branch.  Use the 'commit' command (see below)\n-\tto write git commits back to git-svn-HEAD.\n+\tto write git commits back to remotes/git-svn.\n \n commit::\n \tCommit specified commit or tree objects to SVN.  This relies on\n@@ -155,13 +155,13 @@ Tracking and contributing to an Subversi\n # Fetch remote revisions::\n \tgit-svn fetch\n # Create your own branch to hack on::\n-\tgit checkout -b my-branch git-svn-HEAD\n+\tgit checkout -b my-branch remotes/git-svn\n # Commit only the git commits you want to SVN::\n \tgit-svn commit <tree-ish> [<tree-ish_2> ...]\n # Commit all the git commits from my-branch that don't exist in SVN::\n-\tgit-svn commit git-svn-HEAD..my-branch\n+\tgit-svn commit remotes/git-svn..my-branch\n # Something is committed to SVN, pull the latest into your branch::\n-\tgit-svn fetch && git pull . git-svn-HEAD\n+\tgit-svn fetch && git pull . remotes/git-svn\n # Append svn:ignore settings to the default git exclude file:\n \tgit-svn show-ignore >> .git/info/exclude\n \n@@ -184,8 +184,8 @@ SVN repositories via one git repository.\n environment variable to a name other other than \"git-svn\" (the default)\n and git-svn will ignore the contents of the $GIT_DIR/git-svn directory\n and instead do all of its work in $GIT_DIR/$GIT_SVN_ID for that\n-invocation.  The interface branch will be $GIT_SVN_ID-HEAD, instead of\n-git-svn-HEAD.  Any $GIT_SVN_ID-HEAD branch should never be modified\n+invocation.  The interface branch will be remotes/$GIT_SVN_ID, instead of\n+remotes/git-svn.  Any remotes/$GIT_SVN_ID branch should never be modified\n by the user outside of git-svn commands.\n \n ADDITIONAL FETCH ARGUMENTS\ndiff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/contrib/git-svn/t/t0000-contrib-git-svn.sh\nindex 181dfe0..80ad357 100644\n--- a/contrib/git-svn/t/t0000-contrib-git-svn.sh\n+++ b/contrib/git-svn/t/t0000-contrib-git-svn.sh\n@@ -71,14 +71,14 @@ test_expect_success \\\n \n \n name='try a deep --rmdir with a commit'\n-git checkout -b mybranch git-svn-HEAD\n+git checkout -b mybranch remotes/git-svn\n mv dir/a/b/c/d/e/file dir/file\n cp dir/file file\n git update-index --add --remove dir/a/b/c/d/e/file dir/file file\n git commit -m \"$name\"\n \n test_expect_success \"$name\" \\\n-    \"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch &&\n+    \"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch &&\n      test -d $SVN_TREE/dir && test ! -d $SVN_TREE/dir/a\"\n \n \n@@ -91,13 +91,13 @@ git update-index --add dir/file/file\n git commit -m \"$name\"\n \n test_expect_code 1 \"$name\" \\\n-    'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch' \\\n+    'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch' \\\n     || true\n \n \n name='detect node change from directory to file #1'\n rm -rf dir $GIT_DIR/index\n-git checkout -b mybranch2 git-svn-HEAD\n+git checkout -b mybranch2 remotes/git-svn\n mv bar/zzz zzz\n rm -rf bar\n mv zzz bar\n@@ -106,13 +106,13 @@ git update-index --add -- bar\n git commit -m \"$name\"\n \n test_expect_code 1 \"$name\" \\\n-    'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch2' \\\n+    'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch2' \\\n     || true\n \n \n name='detect node change from file to directory #2'\n rm -f $GIT_DIR/index\n-git checkout -b mybranch3 git-svn-HEAD\n+git checkout -b mybranch3 remotes/git-svn\n rm bar/zzz\n git-update-index --remove bar/zzz\n mkdir bar/zzz\n@@ -121,13 +121,13 @@ git-update-index --add bar/zzz/yyy\n git commit -m \"$name\"\n \n test_expect_code 1 \"$name\" \\\n-    'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch3' \\\n+    'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch3' \\\n     || true\n \n \n name='detect node change from directory to file #2'\n rm -f $GIT_DIR/index\n-git checkout -b mybranch4 git-svn-HEAD\n+git checkout -b mybranch4 remotes/git-svn\n rm -rf dir\n git update-index --remove -- dir/file\n touch dir\n@@ -136,19 +136,19 @@ git update-index --add -- dir\n git commit -m \"$name\"\n \n test_expect_code 1 \"$name\" \\\n-    'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch4' \\\n+    'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch4' \\\n     || true\n \n \n name='remove executable bit from a file'\n rm -f $GIT_DIR/index\n-git checkout -b mybranch5 git-svn-HEAD\n+git checkout -b mybranch5 remotes/git-svn\n chmod -x exec.sh\n git update-index exec.sh\n git commit -m \"$name\"\n \n test_expect_success \"$name\" \\\n-    \"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&\n+    \"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&\n      test ! -x $SVN_TREE/exec.sh\"\n \n \n@@ -158,7 +158,7 @@ git update-index exec.sh\n git commit -m \"$name\"\n \n test_expect_success \"$name\" \\\n-    \"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&\n+    \"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&\n      test -x $SVN_TREE/exec.sh\"\n \n \n@@ -170,7 +170,7 @@ git update-index exec.sh\n git commit -m \"$name\"\n \n test_expect_success \"$name\" \\\n-    \"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&\n+    \"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&\n      test -L $SVN_TREE/exec.sh\"\n \n \n@@ -182,7 +182,7 @@ git update-index --add bar/zzz exec-2.sh\n git commit -m \"$name\"\n \n test_expect_success \"$name\" \\\n-    \"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&\n+    \"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&\n      test -x $SVN_TREE/bar/zzz &&\n      test -L $SVN_TREE/exec-2.sh\"\n \n@@ -196,7 +196,7 @@ git update-index exec-2.sh\n git commit -m \"$name\"\n \n test_expect_success \"$name\" \\\n-    \"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&\n+    \"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&\n      test -f $SVN_TREE/exec-2.sh &&\n      test ! -L $SVN_TREE/exec-2.sh &&\n      diff -u help $SVN_TREE/exec-2.sh\"\n@@ -207,9 +207,9 @@ name='test fetch functionality (svn => g\n GIT_SVN_ID=alt\n export GIT_SVN_ID\n test_expect_success \"$name\" \\\n-    \"git-svn init $svnrepo && git-svn fetch -v &&\n-     git-rev-list --pretty=raw git-svn-HEAD | grep ^tree | uniq > a &&\n-     git-rev-list --pretty=raw alt-HEAD | grep ^tree | uniq > b &&\n+    \"git-svn init $svnrepo && git-svn fetch &&\n+     git-rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&\n+     git-rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&\n      diff -u a b\"\n \n test_done\n-- \n1.2.3.g4676\n"},{"id":"17068","messageId":"20060302202317.GA6708@hand.yhbt.net","threadId":"3516","inReplyTo":"20060302055831.GA16600@localdomain","subject":"[PATCH] git-branch: add -r switch to list refs/remotes/*","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2006-03-02T20:23:17Z","receivedAt":"2006-03-02T20:23:17Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"If we decide to use refs/remotes/, having a convenient way to\nlist them would be nice.\n\nSigned-off-by: Eric Wong <normalperson@yhbt.net>\n\n---\n\n git-branch.sh |   10 ++++++++++\n 1 files changed, 10 insertions(+), 0 deletions(-)\n\n05fb74c2a8d4bf3692a7553c5225d25ab54f358a\ndiff --git a/git-branch.sh b/git-branch.sh\nindex 6ac961e..663a3a3 100755\n--- a/git-branch.sh\n+++ b/git-branch.sh\n@@ -48,6 +48,12 @@ If you are sure you want to delete it, r\n     exit 0\n }\n \n+ls_remote_branches () {\n+    git-rev-parse --symbolic --all |\n+    sed -ne 's|^refs/\\(remotes/\\)|\\1|p' |\n+    sort\n+}\n+\n force=\n while case \"$#,$1\" in 0,*) break ;; *,-*) ;; *) break ;; esac\n do\n@@ -56,6 +62,10 @@ do\n \t\tdelete_branch \"$@\"\n \t\texit\n \t\t;;\n+\t-r)\n+\t\tls_remote_branches\n+\t\texit\n+\t\t;;\n \t-f)\n \t\tforce=\"$1\"\n \t\t;;\n-- \n1.2.3.gc55f\n"},{"id":"17070","messageId":"62157.84.163.95.215.1141334223.squirrel@mail.geht-ab-wie-schnitzel.de","threadId":"3516","inReplyTo":"20060302055831.GA16600@localdomain","subject":"Re: [PATCH] contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD","fromName":"Nicolas Vilz 'niv'","fromEmail":"nicolas@vilz.de","sentAt":"2006-03-02T21:17:03Z","receivedAt":"2006-03-02T21:17:03Z","isPatch":true,"sender":{"key":"nicolas@vilz.de","avatar":null},"body":"> After reading a lengthy discussion on the list, I've come to the\n> conclusion that creating a 'remotes' directory in refs isn't\n> such a bad idea.\n>\n> You can still branch from it by specifying remotes/git-svn (not\n> needing the leading 'refs/'), and the documentation has been\n> updated to reflect that.\n\ni got stuck in that.\n\ngit-svn does the remotes/svn-git reference good, git pull hasn't\nrecognized it, yet. So i had to do a symlink from .git/refs/remotes to\n.git/refs/heads/ to do the git pull...\n\nthen i got a bit stuck because of conflicts.... which i resolved (thank god).\n\nthe third thing is that the git-svn commit command does deletions of\ncertain files very often, when i commit some patches i pulled into my\nprivate-talk-to-svn-branch. in on of the next commits the same files are\nadded again.. but i thought \"o my god, i am screwed\", when i saw the\nscheduled deletions the first time... that is a bit confusing for the\nusers.\n\nso in conclusion, i think, you should teach git pull to recognize\nrefs/remotes as heads to be pulled from (not to be pulled at)...\n\nbtw, i like the visualization of the remotes-refs in gitk.\n\nNicolas\n"}]}