git-svn: teach dcommit about svn auto-props
Subversion repositories often require files to have properties such as svn:mime-type and svn:eol-style set when they are added. Users typically set these properties automatically using the SVN auto-props feature with 'svn add'. This commit teaches dcommit to look at the user SVN configuration and apply matching auto-props entries for files added by a diff as it is applied to the SVN remote. Signed-off-by: Brad King <brad.king@kitware.com> Acked-by: Eric Wong <normalperson@yhbt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brad King committed
Jul 25, 2008 at 11:32 UTC
128de6576743901b11f243509753320038e74ba7
2 files changed
+139
git-svn.perl
+53
@@ -3340,6 +3340,7 @@ sub new {
3340
$self->{rm} = { };
3341
$self->{path_prefix} = length $self->{svn_path} ?
3342
"$self->{svn_path}/" : '';
3343
+ $self->{config} = $opts->{config};
3344
return $self;
3345
}
3346
@@ -3528,6 +3529,57 @@ sub ensure_path {
3529
return $bat->{$c};
3530
}
3531
3532
+# Subroutine to convert a globbing pattern to a regular expression.
3533
+# From perl cookbook.
3534
+sub glob2pat {
3535
+ my $globstr = shift;
3536
+ my %patmap = ('*' => '.*', '?' => '.', '[' => '[', ']' => ']');
3537
+ $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
3538
+ return '^' . $globstr . '$';
3539
+}
3540
+
3541
+sub check_autoprop {
3542
+ my ($self, $pattern, $properties, $file, $fbat) = @_;
3543
+ # Convert the globbing pattern to a regular expression.
3544
+ my $regex = glob2pat($pattern);
3545
+ # Check if the pattern matches the file name.
3546
+ if($file =~ m/($regex)/) {
3547
+ # Parse the list of properties to set.
3548
+ my @props = split(/;/, $properties);
3549
+ foreach my $prop (@props) {
3550
+ # Parse 'name=value' syntax and set the property.
3551
+ if ($prop =~ /([^=]+)=(.*)/) {
3552
+ my ($n,$v) = ($1,$2);
3553
+ for ($n, $v) {
3554
+ s/^\s+//; s/\s+$//;
3555
+ }
3556
+ $self->change_file_prop($fbat, $n, $v);
3557
+ }
3558
+ }
3559
+ }
3560
+}
3561
+
3562
+sub apply_autoprops {
3563
+ my ($self, $file, $fbat) = @_;
3564
+ my $conf_t = ${$self->{config}}{'config'};
3565
+ no warnings 'once';
3566
+ # Check [miscellany]/enable-auto-props in svn configuration.
3567
+ if (SVN::_Core::svn_config_get_bool(
3568
+ $conf_t,
3569
+ $SVN::_Core::SVN_CONFIG_SECTION_MISCELLANY,
3570
+ $SVN::_Core::SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS,
3571
+ 0)) {
3572
+ # Auto-props are enabled. Enumerate them to look for matches.
3573
+ my $callback = sub {
3574
+ $self->check_autoprop($_[0], $_[1], $file, $fbat);
3575
+ };
3576
+ SVN::_Core::svn_config_enumerate(
3577
+ $conf_t,
3578
+ $SVN::_Core::SVN_CONFIG_SECTION_AUTO_PROPS,
3579
+ $callback);
3580
+ }
3581
+}
3582
+
3583
sub A {
3584
my ($self, $m) = @_;
3585
my ($dir, $file) = split_path($m->{file_b});
@@ -3535,6 +3587,7 @@ sub A {
3587
my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,
3588
undef, -1);
3589
print "\tA\t$m->{file_b}\n" unless $::_q;
3590
+ $self->apply_autoprops($file, $fbat);
3591
$self->chg_file($fbat, $m);
3592
$self->close_file($fbat,undef,$self->{pool});
3593
}
t/t9124-git-svn-dcommit-auto-props.sh
new
+86
@@ -0,0 +1,86 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2008 Brad King
4
+
5
+test_description='git-svn dcommit honors auto-props'
6
+
7
+. ./lib-git-svn.sh
8
+
9
+generate_auto_props() {
10
+cat << EOF
11
+[miscellany]
12
+enable-auto-props=$1
13
+[auto-props]
14
+*.sh = svn:mime-type=application/x-shellscript; svn:eol-style=LF
15
+*.txt = svn:mime-type=text/plain; svn:eol-style = native
16
+EOF
17
+}
18
+
19
+test_expect_success 'initialize git-svn' '
20
+ mkdir import &&
21
+ (
22
+ cd import &&
23
+ echo foo >foo &&
24
+ svn import -m "import for git-svn" . "$svnrepo"
25
+ ) &&
26
+ rm -rf import &&
27
+ git-svn init "$svnrepo"
28
+ git-svn fetch
29
+'
30
+
31
+test_expect_success 'enable auto-props config' '
32
+ cd "$gittestrepo" &&
33
+ mkdir user &&
34
+ generate_auto_props yes >user/config
35
+'
36
+
37
+test_expect_success 'add files matching auto-props' '
38
+ cd "$gittestrepo" &&
39
+ echo "#!$SHELL_PATH" >exec1.sh &&
40
+ chmod +x exec1.sh &&
41
+ echo "hello" >hello.txt &&
42
+ echo bar >bar &&
43
+ git add exec1.sh hello.txt bar &&
44
+ git commit -m "files for enabled auto-props" &&
45
+ git svn dcommit --config-dir=user
46
+'
47
+
48
+test_expect_success 'disable auto-props config' '
49
+ cd "$gittestrepo" &&
50
+ generate_auto_props no >user/config
51
+'
52
+
53
+test_expect_success 'add files matching disabled auto-props' '
54
+ cd "$gittestrepo" &&
55
+ echo "#$SHELL_PATH" >exec2.sh &&
56
+ chmod +x exec2.sh &&
57
+ echo "world" >world.txt &&
58
+ echo zot >zot &&
59
+ git add exec2.sh world.txt zot &&
60
+ git commit -m "files for disabled auto-props" &&
61
+ git svn dcommit --config-dir=user
62
+'
63
+
64
+test_expect_success 'check resulting svn repository' '
65
+ mkdir work &&
66
+ cd work &&
67
+ svn co "$svnrepo" &&
68
+ cd svnrepo &&
69
+
70
+ # Check properties from first commit.
71
+ test "x$(svn propget svn:executable exec1.sh)" = "x*" &&
72
+ test "x$(svn propget svn:mime-type exec1.sh)" = \
73
+ "xapplication/x-shellscript" &&
74
+ test "x$(svn propget svn:mime-type hello.txt)" = "xtext/plain" &&
75
+ test "x$(svn propget svn:eol-style hello.txt)" = "xnative" &&
76
+ test "x$(svn propget svn:mime-type bar)" = "x" &&
77
+
78
+ # Check properties from second commit.
79
+ test "x$(svn propget svn:executable exec2.sh)" = "x*" &&
80
+ test "x$(svn propget svn:mime-type exec2.sh)" = "x" &&
81
+ test "x$(svn propget svn:mime-type world.txt)" = "x" &&
82
+ test "x$(svn propget svn:eol-style world.txt)" = "x" &&
83
+ test "x$(svn propget svn:mime-type zot)" = "x"
84
+'
85
+
86
+test_done