mirror of
https://github.com/git/git
synced 2024-08-25 10:45:59 +00:00
contrib/git-svn: use refs/remotes/git-svn instead of git-svn-HEAD
After reading a lengthy discussion on the list, I've come to the conclusion that creating a 'remotes' directory in refs isn't such a bad idea. You can still branch from it by specifying remotes/git-svn (not needing the leading 'refs/'), and the documentation has been updated to reflect that. The 'git-svn' part of the ref can of course be set to whatever you want by using the GIT_SVN_ID environment variable, as before. I'm using refs/remotes/git-svn, and not going with something like refs/remotes/git-svn/HEAD as it's redundant for Subversion where there's zero distinction between branches and directories. Run git-svn rebuild --upgrade to upgrade your repository to use the new head. git-svn-HEAD must be manually deleted for safety reasons. Side note: if you ever (and I hope you never) want to run git-update-refs on a 'remotes/' ref, make sure you have the 'refs/' prefix as you don't want to be clobbering your 'remotes/' in $GIT_DIR (where remote URLs are stored). Signed-off-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
2486927d2e
commit
2beb3cdd18
|
@ -34,13 +34,14 @@
|
||||||
my $sha1 = qr/[a-f\d]{40}/;
|
my $sha1 = qr/[a-f\d]{40}/;
|
||||||
my $sha1_short = qr/[a-f\d]{6,40}/;
|
my $sha1_short = qr/[a-f\d]{6,40}/;
|
||||||
my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
|
my ($_revision,$_stdin,$_no_ignore_ext,$_no_stop_copy,$_help,$_rmdir,$_edit,
|
||||||
$_find_copies_harder, $_l, $_version);
|
$_find_copies_harder, $_l, $_version, $_upgrade);
|
||||||
|
|
||||||
GetOptions( 'revision|r=s' => \$_revision,
|
GetOptions( 'revision|r=s' => \$_revision,
|
||||||
'no-ignore-externals' => \$_no_ignore_ext,
|
'no-ignore-externals' => \$_no_ignore_ext,
|
||||||
'stdin|' => \$_stdin,
|
'stdin|' => \$_stdin,
|
||||||
'edit|e' => \$_edit,
|
'edit|e' => \$_edit,
|
||||||
'rmdir' => \$_rmdir,
|
'rmdir' => \$_rmdir,
|
||||||
|
'upgrade' => \$_upgrade,
|
||||||
'help|H|h' => \$_help,
|
'help|H|h' => \$_help,
|
||||||
'find-copies-harder' => \$_find_copies_harder,
|
'find-copies-harder' => \$_find_copies_harder,
|
||||||
'l=i' => \$_l,
|
'l=i' => \$_l,
|
||||||
|
@ -106,13 +107,18 @@ sub rebuild {
|
||||||
$SVN_URL = shift or undef;
|
$SVN_URL = shift or undef;
|
||||||
my $repo_uuid;
|
my $repo_uuid;
|
||||||
my $newest_rev = 0;
|
my $newest_rev = 0;
|
||||||
|
if ($_upgrade) {
|
||||||
|
sys('git-update-ref',"refs/remotes/$GIT_SVN","$GIT_SVN-HEAD");
|
||||||
|
} else {
|
||||||
|
check_upgrade_needed();
|
||||||
|
}
|
||||||
|
|
||||||
my $pid = open(my $rev_list,'-|');
|
my $pid = open(my $rev_list,'-|');
|
||||||
defined $pid or croak $!;
|
defined $pid or croak $!;
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
exec("git-rev-list","$GIT_SVN-HEAD") or croak $!;
|
exec("git-rev-list","refs/remotes/$GIT_SVN") or croak $!;
|
||||||
}
|
}
|
||||||
my $first;
|
my $latest;
|
||||||
while (<$rev_list>) {
|
while (<$rev_list>) {
|
||||||
chomp;
|
chomp;
|
||||||
my $c = $_;
|
my $c = $_;
|
||||||
|
@ -132,18 +138,20 @@ sub rebuild {
|
||||||
"$c, $id\n";
|
"$c, $id\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if we merged or otherwise started elsewhere, this is
|
||||||
|
# how we break out of it
|
||||||
|
next if (defined $repo_uuid && ($uuid ne $repo_uuid));
|
||||||
|
next if (defined $SVN_URL && ($url ne $SVN_URL));
|
||||||
|
|
||||||
print "r$rev = $c\n";
|
print "r$rev = $c\n";
|
||||||
unless (defined $first) {
|
unless (defined $latest) {
|
||||||
if (!$SVN_URL && !$url) {
|
if (!$SVN_URL && !$url) {
|
||||||
croak "SVN repository location required: $url\n";
|
croak "SVN repository location required: $url\n";
|
||||||
}
|
}
|
||||||
$SVN_URL ||= $url;
|
$SVN_URL ||= $url;
|
||||||
$repo_uuid = setup_git_svn();
|
$repo_uuid ||= setup_git_svn();
|
||||||
$first = $rev;
|
$latest = $rev;
|
||||||
}
|
|
||||||
if ($uuid ne $repo_uuid) {
|
|
||||||
croak "Repository UUIDs do not match!\ngot: $uuid\n",
|
|
||||||
"expected: $repo_uuid\n";
|
|
||||||
}
|
}
|
||||||
assert_revision_eq_or_unknown($rev, $c);
|
assert_revision_eq_or_unknown($rev, $c);
|
||||||
sys('git-update-ref',"$GIT_SVN/revs/$rev",$c);
|
sys('git-update-ref',"$GIT_SVN/revs/$rev",$c);
|
||||||
|
@ -151,7 +159,7 @@ sub rebuild {
|
||||||
}
|
}
|
||||||
close $rev_list or croak $?;
|
close $rev_list or croak $?;
|
||||||
if (!chdir $SVN_WC) {
|
if (!chdir $SVN_WC) {
|
||||||
my @svn_co = ('svn','co',"-r$first");
|
my @svn_co = ('svn','co',"-r$latest");
|
||||||
push @svn_co, '--ignore-externals' unless $_no_ignore_ext;
|
push @svn_co, '--ignore-externals' unless $_no_ignore_ext;
|
||||||
sys(@svn_co, $SVN_URL, $SVN_WC);
|
sys(@svn_co, $SVN_URL, $SVN_WC);
|
||||||
chdir $SVN_WC or croak $!;
|
chdir $SVN_WC or croak $!;
|
||||||
|
@ -168,6 +176,13 @@ sub rebuild {
|
||||||
exec('git-write-tree');
|
exec('git-write-tree');
|
||||||
}
|
}
|
||||||
waitpid $pid, 0;
|
waitpid $pid, 0;
|
||||||
|
|
||||||
|
if ($_upgrade) {
|
||||||
|
print STDERR <<"";
|
||||||
|
Keeping deprecated refs/head/$GIT_SVN-HEAD for now. Please remove it
|
||||||
|
when you have upgraded your tools and habits to use refs/remotes/$GIT_SVN
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub init {
|
sub init {
|
||||||
|
@ -180,6 +195,7 @@ sub init {
|
||||||
|
|
||||||
sub fetch {
|
sub fetch {
|
||||||
my (@parents) = @_;
|
my (@parents) = @_;
|
||||||
|
check_upgrade_needed();
|
||||||
$SVN_URL ||= file_to_s("$GIT_DIR/$GIT_SVN/info/url");
|
$SVN_URL ||= file_to_s("$GIT_DIR/$GIT_SVN/info/url");
|
||||||
my @log_args = -d $SVN_WC ? ($SVN_WC) : ($SVN_URL);
|
my @log_args = -d $SVN_WC ? ($SVN_WC) : ($SVN_URL);
|
||||||
unless ($_revision) {
|
unless ($_revision) {
|
||||||
|
@ -222,6 +238,7 @@ sub fetch {
|
||||||
|
|
||||||
sub commit {
|
sub commit {
|
||||||
my (@commits) = @_;
|
my (@commits) = @_;
|
||||||
|
check_upgrade_needed();
|
||||||
if ($_stdin || !@commits) {
|
if ($_stdin || !@commits) {
|
||||||
print "Reading from stdin...\n";
|
print "Reading from stdin...\n";
|
||||||
@commits = ();
|
@commits = ();
|
||||||
|
@ -863,7 +880,7 @@ sub git_commit {
|
||||||
if ($commit !~ /^$sha1$/o) {
|
if ($commit !~ /^$sha1$/o) {
|
||||||
croak "Failed to commit, invalid sha1: $commit\n";
|
croak "Failed to commit, invalid sha1: $commit\n";
|
||||||
}
|
}
|
||||||
my @update_ref = ('git-update-ref',"refs/heads/$GIT_SVN-HEAD",$commit);
|
my @update_ref = ('git-update-ref',"refs/remotes/$GIT_SVN",$commit);
|
||||||
if (my $primary_parent = shift @exec_parents) {
|
if (my $primary_parent = shift @exec_parents) {
|
||||||
push @update_ref, $primary_parent;
|
push @update_ref, $primary_parent;
|
||||||
}
|
}
|
||||||
|
@ -936,6 +953,28 @@ sub svn_check_ignore_externals {
|
||||||
$_no_ignore_ext = 1;
|
$_no_ignore_ext = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub check_upgrade_needed {
|
||||||
|
my $old = eval {
|
||||||
|
my $pid = open my $child, '-|';
|
||||||
|
defined $pid or croak $!;
|
||||||
|
if ($pid == 0) {
|
||||||
|
close STDERR;
|
||||||
|
exec('git-rev-parse',"$GIT_SVN-HEAD") or croak $?;
|
||||||
|
}
|
||||||
|
my @ret = (<$child>);
|
||||||
|
close $child or croak $?;
|
||||||
|
die $? if $?; # just in case close didn't error out
|
||||||
|
return wantarray ? @ret : join('',@ret);
|
||||||
|
};
|
||||||
|
return unless $old;
|
||||||
|
my $head = eval { safe_qx('git-rev-parse',"refs/remotes/$GIT_SVN") };
|
||||||
|
if ($@ || !$head) {
|
||||||
|
print STDERR "Please run: $0 rebuild --upgrade\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
Data structures:
|
Data structures:
|
||||||
|
|
|
@ -41,12 +41,12 @@ init::
|
||||||
|
|
||||||
fetch::
|
fetch::
|
||||||
Fetch unfetched revisions from the SVN_URL we are tracking.
|
Fetch unfetched revisions from the SVN_URL we are tracking.
|
||||||
refs/heads/git-svn-HEAD will be updated to the latest revision.
|
refs/heads/remotes/git-svn will be updated to the latest revision.
|
||||||
|
|
||||||
Note: You should never attempt to modify the git-svn-HEAD branch
|
Note: You should never attempt to modify the remotes/git-svn branch
|
||||||
outside of git-svn. Instead, create a branch from git-svn-HEAD
|
outside of git-svn. Instead, create a branch from remotes/git-svn
|
||||||
and work on that branch. Use the 'commit' command (see below)
|
and work on that branch. Use the 'commit' command (see below)
|
||||||
to write git commits back to git-svn-HEAD.
|
to write git commits back to remotes/git-svn.
|
||||||
|
|
||||||
commit::
|
commit::
|
||||||
Commit specified commit or tree objects to SVN. This relies on
|
Commit specified commit or tree objects to SVN. This relies on
|
||||||
|
@ -155,13 +155,13 @@ Tracking and contributing to an Subversion managed-project:
|
||||||
# Fetch remote revisions::
|
# Fetch remote revisions::
|
||||||
git-svn fetch
|
git-svn fetch
|
||||||
# Create your own branch to hack on::
|
# Create your own branch to hack on::
|
||||||
git checkout -b my-branch git-svn-HEAD
|
git checkout -b my-branch remotes/git-svn
|
||||||
# Commit only the git commits you want to SVN::
|
# Commit only the git commits you want to SVN::
|
||||||
git-svn commit <tree-ish> [<tree-ish_2> ...]
|
git-svn commit <tree-ish> [<tree-ish_2> ...]
|
||||||
# Commit all the git commits from my-branch that don't exist in SVN::
|
# Commit all the git commits from my-branch that don't exist in SVN::
|
||||||
git-svn commit git-svn-HEAD..my-branch
|
git-svn commit remotes/git-svn..my-branch
|
||||||
# Something is committed to SVN, pull the latest into your branch::
|
# Something is committed to SVN, pull the latest into your branch::
|
||||||
git-svn fetch && git pull . git-svn-HEAD
|
git-svn fetch && git pull . remotes/git-svn
|
||||||
# Append svn:ignore settings to the default git exclude file:
|
# Append svn:ignore settings to the default git exclude file:
|
||||||
git-svn show-ignore >> .git/info/exclude
|
git-svn show-ignore >> .git/info/exclude
|
||||||
|
|
||||||
|
@ -184,8 +184,8 @@ SVN repositories via one git repository. Simply set the GIT_SVN_ID
|
||||||
environment variable to a name other other than "git-svn" (the default)
|
environment variable to a name other other than "git-svn" (the default)
|
||||||
and git-svn will ignore the contents of the $GIT_DIR/git-svn directory
|
and git-svn will ignore the contents of the $GIT_DIR/git-svn directory
|
||||||
and instead do all of its work in $GIT_DIR/$GIT_SVN_ID for that
|
and instead do all of its work in $GIT_DIR/$GIT_SVN_ID for that
|
||||||
invocation. The interface branch will be $GIT_SVN_ID-HEAD, instead of
|
invocation. The interface branch will be remotes/$GIT_SVN_ID, instead of
|
||||||
git-svn-HEAD. Any $GIT_SVN_ID-HEAD branch should never be modified
|
remotes/git-svn. Any remotes/$GIT_SVN_ID branch should never be modified
|
||||||
by the user outside of git-svn commands.
|
by the user outside of git-svn commands.
|
||||||
|
|
||||||
ADDITIONAL FETCH ARGUMENTS
|
ADDITIONAL FETCH ARGUMENTS
|
||||||
|
|
|
@ -71,14 +71,14 @@ test_expect_success \
|
||||||
|
|
||||||
|
|
||||||
name='try a deep --rmdir with a commit'
|
name='try a deep --rmdir with a commit'
|
||||||
git checkout -b mybranch git-svn-HEAD
|
git checkout -b mybranch remotes/git-svn
|
||||||
mv dir/a/b/c/d/e/file dir/file
|
mv dir/a/b/c/d/e/file dir/file
|
||||||
cp dir/file file
|
cp dir/file file
|
||||||
git update-index --add --remove dir/a/b/c/d/e/file dir/file file
|
git update-index --add --remove dir/a/b/c/d/e/file dir/file file
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch &&
|
"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch &&
|
||||||
test -d $SVN_TREE/dir && test ! -d $SVN_TREE/dir/a"
|
test -d $SVN_TREE/dir && test ! -d $SVN_TREE/dir/a"
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,13 +91,13 @@ git update-index --add dir/file/file
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_code 1 "$name" \
|
test_expect_code 1 "$name" \
|
||||||
'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch' \
|
'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch' \
|
||||||
|| true
|
|| true
|
||||||
|
|
||||||
|
|
||||||
name='detect node change from directory to file #1'
|
name='detect node change from directory to file #1'
|
||||||
rm -rf dir $GIT_DIR/index
|
rm -rf dir $GIT_DIR/index
|
||||||
git checkout -b mybranch2 git-svn-HEAD
|
git checkout -b mybranch2 remotes/git-svn
|
||||||
mv bar/zzz zzz
|
mv bar/zzz zzz
|
||||||
rm -rf bar
|
rm -rf bar
|
||||||
mv zzz bar
|
mv zzz bar
|
||||||
|
@ -106,13 +106,13 @@ git update-index --add -- bar
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_code 1 "$name" \
|
test_expect_code 1 "$name" \
|
||||||
'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch2' \
|
'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch2' \
|
||||||
|| true
|
|| true
|
||||||
|
|
||||||
|
|
||||||
name='detect node change from file to directory #2'
|
name='detect node change from file to directory #2'
|
||||||
rm -f $GIT_DIR/index
|
rm -f $GIT_DIR/index
|
||||||
git checkout -b mybranch3 git-svn-HEAD
|
git checkout -b mybranch3 remotes/git-svn
|
||||||
rm bar/zzz
|
rm bar/zzz
|
||||||
git-update-index --remove bar/zzz
|
git-update-index --remove bar/zzz
|
||||||
mkdir bar/zzz
|
mkdir bar/zzz
|
||||||
|
@ -121,13 +121,13 @@ git-update-index --add bar/zzz/yyy
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_code 1 "$name" \
|
test_expect_code 1 "$name" \
|
||||||
'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch3' \
|
'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch3' \
|
||||||
|| true
|
|| true
|
||||||
|
|
||||||
|
|
||||||
name='detect node change from directory to file #2'
|
name='detect node change from directory to file #2'
|
||||||
rm -f $GIT_DIR/index
|
rm -f $GIT_DIR/index
|
||||||
git checkout -b mybranch4 git-svn-HEAD
|
git checkout -b mybranch4 remotes/git-svn
|
||||||
rm -rf dir
|
rm -rf dir
|
||||||
git update-index --remove -- dir/file
|
git update-index --remove -- dir/file
|
||||||
touch dir
|
touch dir
|
||||||
|
@ -136,19 +136,19 @@ git update-index --add -- dir
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_code 1 "$name" \
|
test_expect_code 1 "$name" \
|
||||||
'git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch4' \
|
'git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch4' \
|
||||||
|| true
|
|| true
|
||||||
|
|
||||||
|
|
||||||
name='remove executable bit from a file'
|
name='remove executable bit from a file'
|
||||||
rm -f $GIT_DIR/index
|
rm -f $GIT_DIR/index
|
||||||
git checkout -b mybranch5 git-svn-HEAD
|
git checkout -b mybranch5 remotes/git-svn
|
||||||
chmod -x exec.sh
|
chmod -x exec.sh
|
||||||
git update-index exec.sh
|
git update-index exec.sh
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&
|
"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
|
||||||
test ! -x $SVN_TREE/exec.sh"
|
test ! -x $SVN_TREE/exec.sh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ git update-index exec.sh
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&
|
"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
|
||||||
test -x $SVN_TREE/exec.sh"
|
test -x $SVN_TREE/exec.sh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ git update-index exec.sh
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&
|
"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
|
||||||
test -L $SVN_TREE/exec.sh"
|
test -L $SVN_TREE/exec.sh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ git update-index --add bar/zzz exec-2.sh
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&
|
"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
|
||||||
test -x $SVN_TREE/bar/zzz &&
|
test -x $SVN_TREE/bar/zzz &&
|
||||||
test -L $SVN_TREE/exec-2.sh"
|
test -L $SVN_TREE/exec-2.sh"
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ git update-index exec-2.sh
|
||||||
git commit -m "$name"
|
git commit -m "$name"
|
||||||
|
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn commit --find-copies-harder --rmdir git-svn-HEAD..mybranch5 &&
|
"git-svn commit --find-copies-harder --rmdir remotes/git-svn..mybranch5 &&
|
||||||
test -f $SVN_TREE/exec-2.sh &&
|
test -f $SVN_TREE/exec-2.sh &&
|
||||||
test ! -L $SVN_TREE/exec-2.sh &&
|
test ! -L $SVN_TREE/exec-2.sh &&
|
||||||
diff -u help $SVN_TREE/exec-2.sh"
|
diff -u help $SVN_TREE/exec-2.sh"
|
||||||
|
@ -207,9 +207,9 @@ name='test fetch functionality (svn => git) with alternate GIT_SVN_ID'
|
||||||
GIT_SVN_ID=alt
|
GIT_SVN_ID=alt
|
||||||
export GIT_SVN_ID
|
export GIT_SVN_ID
|
||||||
test_expect_success "$name" \
|
test_expect_success "$name" \
|
||||||
"git-svn init $svnrepo && git-svn fetch -v &&
|
"git-svn init $svnrepo && git-svn fetch &&
|
||||||
git-rev-list --pretty=raw git-svn-HEAD | grep ^tree | uniq > a &&
|
git-rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&
|
||||||
git-rev-list --pretty=raw alt-HEAD | grep ^tree | uniq > b &&
|
git-rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&
|
||||||
diff -u a b"
|
diff -u a b"
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue