Skip to content

Commit 112423e

Browse files
author
Eric Wong
committed
git-svn: "git worktree" awareness
git-svn internals were previously not aware of repository layout differences for users of the "git worktree" command. Introduce this awareness by using "git rev-parse --git-path" instead of relying on outdated uses of GIT_DIR and friends. Thanks-to: Duy Nguyen <[email protected]> Reported-by: Mathieu Arnold <[email protected]> Signed-off-by: Eric Wong <[email protected]>
1 parent b26098f commit 112423e

File tree

3 files changed

+42
-28
lines changed

3 files changed

+42
-28
lines changed

git-svn.perl

+5-4
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,7 @@ sub cmd_gc {
17001700
"files will not be compressed.\n";
17011701
}
17021702
File::Find::find({ wanted => \&gc_directory, no_chdir => 1},
1703-
"$ENV{GIT_DIR}/svn");
1703+
Git::SVN::svn_dir());
17041704
}
17051705

17061706
########################### utility functions #########################
@@ -1734,7 +1734,7 @@ sub post_fetch_checkout {
17341734
return unless verify_ref('HEAD^0');
17351735

17361736
return if $ENV{GIT_DIR} !~ m#^(?:.*/)?\.git$#;
1737-
my $index = $ENV{GIT_INDEX_FILE} || "$ENV{GIT_DIR}/index";
1737+
my $index = command_oneline(qw(rev-parse --git-path index));
17381738
return if -f $index;
17391739

17401740
return if command_oneline(qw/rev-parse --is-inside-work-tree/) eq 'false';
@@ -1836,8 +1836,9 @@ sub get_tree_from_treeish {
18361836
sub get_commit_entry {
18371837
my ($treeish) = shift;
18381838
my %log_entry = ( log => '', tree => get_tree_from_treeish($treeish) );
1839-
my $commit_editmsg = "$ENV{GIT_DIR}/COMMIT_EDITMSG";
1840-
my $commit_msg = "$ENV{GIT_DIR}/COMMIT_MSG";
1839+
my @git_path = qw(rev-parse --git-path);
1840+
my $commit_editmsg = command_oneline(@git_path, 'COMMIT_EDITMSG');
1841+
my $commit_msg = command_oneline(@git_path, 'COMMIT_MSG');
18411842
open my $log_fh, '>', $commit_editmsg or croak $!;
18421843

18431844
my $type = command_oneline(qw/cat-file -t/, $treeish);

perl/Git/SVN.pm

+15-9
Original file line numberDiff line numberDiff line change
@@ -807,10 +807,15 @@ sub get_fetch_range {
807807
(++$min, $max);
808808
}
809809

810+
sub svn_dir {
811+
command_oneline(qw(rev-parse --git-path svn));
812+
}
813+
810814
sub tmp_config {
811815
my (@args) = @_;
812-
my $old_def_config = "$ENV{GIT_DIR}/svn/config";
813-
my $config = "$ENV{GIT_DIR}/svn/.metadata";
816+
my $svn_dir = svn_dir();
817+
my $old_def_config = "$svn_dir/config";
818+
my $config = "$svn_dir/.metadata";
814819
if (! -f $config && -f $old_def_config) {
815820
rename $old_def_config, $config or
816821
die "Failed rename $old_def_config => $config: $!\n";
@@ -1671,7 +1676,7 @@ sub tie_for_persistent_memoization {
16711676
return if $memoized;
16721677
$memoized = 1;
16731678

1674-
my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
1679+
my $cache_path = svn_dir() . '/.caches/';
16751680
mkpath([$cache_path]) unless -d $cache_path;
16761681

16771682
my %lookup_svn_merge_cache;
@@ -1712,7 +1717,7 @@ sub tie_for_persistent_memoization {
17121717
sub clear_memoized_mergeinfo_caches {
17131718
die "Only call this method in non-memoized context" if ($memoized);
17141719

1715-
my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
1720+
my $cache_path = svn_dir() . '/.caches/';
17161721
return unless -d $cache_path;
17171722

17181723
for my $cache_file (("$cache_path/lookup_svn_merge",
@@ -2446,12 +2451,13 @@ sub _new {
24462451
"refs/remotes/$prefix$default_ref_id";
24472452
}
24482453
$_[1] = $repo_id;
2449-
my $dir = "$ENV{GIT_DIR}/svn/$ref_id";
2454+
my $svn_dir = svn_dir();
2455+
my $dir = "$svn_dir/$ref_id";
24502456

2451-
# Older repos imported by us used $GIT_DIR/svn/foo instead of
2452-
# $GIT_DIR/svn/refs/remotes/foo when tracking refs/remotes/foo
2457+
# Older repos imported by us used $svn_dir/foo instead of
2458+
# $svn_dir/refs/remotes/foo when tracking refs/remotes/foo
24532459
if ($ref_id =~ m{^refs/remotes/(.+)}) {
2454-
my $old_dir = "$ENV{GIT_DIR}/svn/$1";
2460+
my $old_dir = "$svn_dir/$1";
24552461
if (-d $old_dir && ! -d $dir) {
24562462
$dir = $old_dir;
24572463
}
@@ -2461,7 +2467,7 @@ sub _new {
24612467
mkpath([$dir]);
24622468
my $obj = bless {
24632469
ref_id => $ref_id, dir => $dir, index => "$dir/index",
2464-
config => "$ENV{GIT_DIR}/svn/config",
2470+
config => "$svn_dir/config",
24652471
map_root => "$dir/.rev_map", repo_id => $repo_id }, $class;
24662472

24672473
# Ensure it gets canonicalized

perl/Git/SVN/Migration.pm

+22-15
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ use Git qw(
4444
command_noisy
4545
command_output_pipe
4646
command_close_pipe
47+
command_oneline
4748
);
49+
use Git::SVN;
4850

4951
sub migrate_from_v0 {
5052
my $git_dir = $ENV{GIT_DIR};
@@ -55,7 +57,9 @@ sub migrate_from_v0 {
5557
chomp;
5658
my ($id, $orig_ref) = ($_, $_);
5759
next unless $id =~ s#^refs/heads/(.+)-HEAD$#$1#;
58-
next unless -f "$git_dir/$id/info/url";
60+
my $info_url = command_oneline(qw(rev-parse --git-path),
61+
"$id/info/url");
62+
next unless -f $info_url;
5963
my $new_ref = "refs/remotes/$id";
6064
if (::verify_ref("$new_ref^0")) {
6165
print STDERR "W: $orig_ref is probably an old ",
@@ -82,7 +86,7 @@ sub migrate_from_v1 {
8286
my $git_dir = $ENV{GIT_DIR};
8387
my $migrated = 0;
8488
return $migrated unless -d $git_dir;
85-
my $svn_dir = "$git_dir/svn";
89+
my $svn_dir = Git::SVN::svn_dir();
8690

8791
# just in case somebody used 'svn' as their $id at some point...
8892
return $migrated if -d $svn_dir && ! -f "$svn_dir/info/url";
@@ -97,27 +101,28 @@ sub migrate_from_v1 {
97101
my $x = $_;
98102
next unless $x =~ s#^refs/remotes/##;
99103
chomp $x;
100-
next unless -f "$git_dir/$x/info/url";
101-
my $u = eval { ::file_to_s("$git_dir/$x/info/url") };
104+
my $info_url = command_oneline(qw(rev-parse --git-path),
105+
"$x/info/url");
106+
next unless -f $info_url;
107+
my $u = eval { ::file_to_s($info_url) };
102108
next unless $u;
103-
my $dn = dirname("$git_dir/svn/$x");
109+
my $dn = dirname("$svn_dir/$x");
104110
mkpath([$dn]) unless -d $dn;
105111
if ($x eq 'svn') { # they used 'svn' as GIT_SVN_ID:
106-
mkpath(["$git_dir/svn/svn"]);
112+
mkpath(["$svn_dir/svn"]);
107113
print STDERR " - $git_dir/$x/info => ",
108-
"$git_dir/svn/$x/info\n";
109-
rename "$git_dir/$x/info", "$git_dir/svn/$x/info" or
114+
"$svn_dir/$x/info\n";
115+
rename "$git_dir/$x/info", "$svn_dir/$x/info" or
110116
croak "$!: $x";
111117
# don't worry too much about these, they probably
112118
# don't exist with repos this old (save for index,
113119
# and we can easily regenerate that)
114120
foreach my $f (qw/unhandled.log index .rev_db/) {
115-
rename "$git_dir/$x/$f", "$git_dir/svn/$x/$f";
121+
rename "$git_dir/$x/$f", "$svn_dir/$x/$f";
116122
}
117123
} else {
118-
print STDERR " - $git_dir/$x => $git_dir/svn/$x\n";
119-
rename "$git_dir/$x", "$git_dir/svn/$x" or
120-
croak "$!: $x";
124+
print STDERR " - $git_dir/$x => $svn_dir/$x\n";
125+
rename "$git_dir/$x", "$svn_dir/$x" or croak "$!: $x";
121126
}
122127
$migrated++;
123128
}
@@ -139,9 +144,10 @@ sub read_old_urls {
139144
push @dir, $_;
140145
}
141146
}
147+
my $svn_dir = Git::SVN::svn_dir();
142148
foreach (@dir) {
143149
my $x = $_;
144-
$x =~ s!^\Q$ENV{GIT_DIR}\E/svn/!!o;
150+
$x =~ s!^\Q$svn_dir\E/!!o;
145151
read_old_urls($l_map, $x, $_);
146152
}
147153
}
@@ -150,7 +156,7 @@ sub migrate_from_v2 {
150156
my @cfg = command(qw/config -l/);
151157
return if grep /^svn-remote\..+\.url=/, @cfg;
152158
my %l_map;
153-
read_old_urls(\%l_map, '', "$ENV{GIT_DIR}/svn");
159+
read_old_urls(\%l_map, '', Git::SVN::svn_dir());
154160
my $migrated = 0;
155161

156162
require Git::SVN;
@@ -239,7 +245,8 @@ sub minimize_connections {
239245
}
240246
}
241247
if (@emptied) {
242-
my $file = $ENV{GIT_CONFIG} || "$ENV{GIT_DIR}/config";
248+
my $file = $ENV{GIT_CONFIG} ||
249+
command_oneline(qw(rev-parse --git-path config));
243250
print STDERR <<EOF;
244251
The following [svn-remote] sections in your config file ($file) are empty
245252
and can be safely removed:

0 commit comments

Comments
 (0)