* git-svn vs. $Id$
@ 2006-05-16 17:33 Tommi Virtanen
2006-05-16 17:48 ` Linus Torvalds
2006-05-21 3:03 ` [PATCH] git-svn: ignore expansion of svn:keywords Eric Wong
0 siblings, 2 replies; 8+ messages in thread
From: Tommi Virtanen @ 2006-05-16 17:33 UTC (permalink / raw)
To: git
Hi. I just ran into trouble with git-svn, related to a file
containing $Id$. Yes, I know $Id$ sucks and should be avoided,
and I'll be removing them shortly, but that doesn't change the
fact that the history contains files with them.
Just wanted to let you know of a workaround:
manually edit the relevant file in .git/git-svn/tree/ to
undo the $Id$ change, and git-svn fetch works again.
$ git-svn fetch
Tree mismatch, Got: c242bb60d78c1dfce133e0bbaca7f13895de00b2, Expected:
07d35ac911cc56aabea86f4467cafc1d92b724c4
at /home/tv/bin/git-svn line 426
main::assert_tree('a5890d459de08dc8adbbe34cdfb4b1f44f377ad8')
called at /home/tv/bin/git-svn line 392
main::assert_svn_wc_clean(2039,
'a5890d459de08dc8adbbe34cdfb4b1f44f377ad8') called at
/home/tv/bin/git-svn line 262
main::fetch() called at /home/tv/bin/git-svn line 105
$ git diff-tree -p 07d35ac911cc56aabea86f4467cafc1d92b724c4 \
c242bb60d78c1dfce133e0bbaca7f13895de00b2
diff --git a/anonymized b/anonymized
index 16b3988..f43782a 100644
--- a/anonymized
+++ b/anonymized
@@ -1,4 +1,4 @@
-## $Id: anonymized 1775 2006-04-20 09:25:22Z tv $
+## $Id: anonymized 2025 2006-05-16 07:25:24Z tv $
blah
blah
So editing .git/git-svn/tree/anonymized and replacing
"1775 2006-04-20 09:25:22Z tv" with "2025 2006-05-16 07:25:24Z tv"
make git-svn happy again.
--
Inoi Oy, Tykistökatu 4 D (4. krs), FI-20520 Turku, Finland
http://www.inoi.fi/
Mobile +358 40 762 5656
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: git-svn vs. $Id$ 2006-05-16 17:33 git-svn vs. $Id$ Tommi Virtanen @ 2006-05-16 17:48 ` Linus Torvalds 2006-05-16 18:12 ` Tommi Virtanen 2006-05-21 3:03 ` [PATCH] git-svn: ignore expansion of svn:keywords Eric Wong 1 sibling, 1 reply; 8+ messages in thread From: Linus Torvalds @ 2006-05-16 17:48 UTC (permalink / raw) To: Tommi Virtanen; +Cc: git On Tue, 16 May 2006, Tommi Virtanen wrote: > > Just wanted to let you know of a workaround: > manually edit the relevant file in .git/git-svn/tree/ to > undo the $Id$ change, and git-svn fetch works again. Isn't there some flag to svn to avoid keyword expansion, like "-ko" to CVS? Any import script definitely should avoid keyword expansion (and that's true whether you end up wanting to use keywords or not). (And yes, CVS is probably a bad example. Those "substitution modes" are confusing as hell, and I don't know which one is the right one. Is it "-ko" or "-kk"? Don't ask me, I'm CVS-illiterate. I don't know why the current cvsimport uses -kk, and only does it conditionally. Whatever.) Linus ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: git-svn vs. $Id$ 2006-05-16 17:48 ` Linus Torvalds @ 2006-05-16 18:12 ` Tommi Virtanen 2006-05-21 1:12 ` Eric Wong 0 siblings, 1 reply; 8+ messages in thread From: Tommi Virtanen @ 2006-05-16 18:12 UTC (permalink / raw) To: Linus Torvalds; +Cc: git Linus Torvalds wrote: > Isn't there some flag to svn to avoid keyword expansion, like "-ko" to > CVS? > > Any import script definitely should avoid keyword expansion (and that's > true whether you end up wanting to use keywords or not). Well, yes, I agree. But, at least git-svn.txt says this: BUGS ---- ... svn:keywords can't be ignored in Subversion (at least I don't know of a way to ignore them). I guess one might be able to reach that information through the svn API. Or just propget svn:keywords and sed s/\$Id\(:[^$]*\)\$/$Id$/ all files with keywords, for all relevant keywords. Eww. -- Inoi Oy, Tykistökatu 4 D (4. krs), FI-20520 Turku, Finland http://www.inoi.fi/ Mobile +358 40 762 5656 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: git-svn vs. $Id$ 2006-05-16 18:12 ` Tommi Virtanen @ 2006-05-21 1:12 ` Eric Wong 0 siblings, 0 replies; 8+ messages in thread From: Eric Wong @ 2006-05-21 1:12 UTC (permalink / raw) To: Tommi Virtanen; +Cc: Linus Torvalds, git Tommi Virtanen <tv@inoi.fi> wrote: > Linus Torvalds wrote: > > Isn't there some flag to svn to avoid keyword expansion, like "-ko" to > > CVS? > > > > Any import script definitely should avoid keyword expansion (and that's > > true whether you end up wanting to use keywords or not). > > Well, yes, I agree. But, at least git-svn.txt says this: > > BUGS > ---- > ... > svn:keywords can't be ignored in Subversion (at least I don't know of > a way to ignore them). > > I guess one might be able to reach that information through the svn API. > > Or just propget svn:keywords and sed s/\$Id\(:[^$]*\)\$/$Id$/ all files > with keywords, for all relevant keywords. Eww. I'm working on a solution to this (using files in .svn/text-base). keyword expansion behavior seems inconsistent on some SVN repos and I can't reproduce it on my local repositories, so I think I will have to weaken some integrity checks[1] in git-svn to work around it... 1 - I don't think these integrity checks were ever tripped in the first place. -- Eric Wong ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] git-svn: ignore expansion of svn:keywords 2006-05-16 17:33 git-svn vs. $Id$ Tommi Virtanen 2006-05-16 17:48 ` Linus Torvalds @ 2006-05-21 3:03 ` Eric Wong 2006-05-24 2:23 ` git-svn vs. $Id$ Eric Wong 1 sibling, 1 reply; 8+ messages in thread From: Eric Wong @ 2006-05-21 3:03 UTC (permalink / raw) To: Tommi Virtanen; +Cc: git Can you try this patch? This weakens an integrity in order to work on certain repositories (see comments). It's probably safe to use, though... More testing and feedback would be nice. I've split out the test for this feature to make things easier to manage and test, too. Also changed assert_svn_wc_clean() to only work on svn, and require a separate call to assert_tree() to check wc integrity against git in preparation for another change I'm planning. Signed-off-by: Eric Wong <normalperson@yhbt.net> --- @Junio: please don't apply this to git.git just yet, thanks. contrib/git-svn/Makefile | 1 contrib/git-svn/git-svn.perl | 79 +++++++++++++++++----- contrib/git-svn/t/lib-git-svn.sh | 39 +++++++++++ contrib/git-svn/t/t0000-contrib-git-svn.sh | 43 +----------- contrib/git-svn/t/t0001-contrib-git-svn-props.sh | 51 ++++++++++++++ 5 files changed, 153 insertions(+), 60 deletions(-) create mode 100644 contrib/git-svn/t/lib-git-svn.sh create mode 100644 contrib/git-svn/t/t0001-contrib-git-svn-props.sh eb8f17257c7d15ec6815baf18208af06f72b3cdb diff --git a/contrib/git-svn/Makefile b/contrib/git-svn/Makefile index acedf73..48f60b3 100644 --- a/contrib/git-svn/Makefile +++ b/contrib/git-svn/Makefile @@ -30,6 +30,7 @@ git-svn.html : git-svn.txt -f ../../Documentation/asciidoc.conf $< test: git-svn cd t && $(SHELL) ./t0000-contrib-git-svn.sh + cd t && $(SHELL) ./t0001-contrib-git-svn-props.sh clean: rm -f git-svn *.xml *.html *.1 diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index de13a96..86b687a 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -26,6 +26,7 @@ use Carp qw/croak/; use IO::File qw//; use File::Basename qw/dirname basename/; use File::Path qw/mkpath/; +use File::Copy qw/cp/; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/; use File::Spec qw//; use POSIX qw/strftime/; @@ -207,7 +208,7 @@ sub rebuild { push @svn_up, '--ignore-externals' unless $_no_ignore_ext; sys(@svn_up,"-r$newest_rev"); $ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX; - git_addremove(); + index_changes(); exec('git-write-tree'); } waitpid $pid, 0; @@ -249,7 +250,7 @@ sub fetch { chdir $SVN_WC or croak $!; read_uuid(); $last_commit = git_commit($base, @parents); - assert_svn_wc_clean($base->{revision}, $last_commit); + assert_tree($last_commit); } else { chdir $SVN_WC or croak $!; read_uuid(); @@ -259,7 +260,11 @@ sub fetch { push @svn_up, '--ignore-externals' unless $_no_ignore_ext; my $last = $base; while (my $log_msg = next_log_entry($svn_log)) { - assert_svn_wc_clean($last->{revision}, $last_commit); + # this assertion is commented out because it breaks keywords + # on https://svn.musicpd.org/Jamming/trunk (r166:167), but + # I can't seem to reproduce something like that on a test... + # assert_svn_wc_clean($last->{revision}); + assert_tree($last_commit); if ($last->{revision} >= $log_msg->{revision}) { croak "Out of order: last >= current: ", "$last->{revision} >= $log_msg->{revision}\n"; @@ -268,7 +273,8 @@ sub fetch { $last_commit = git_commit($log_msg, $last_commit, @parents); $last = $log_msg; } - assert_svn_wc_clean($last->{revision}, $last_commit); + assert_svn_wc_clean($last->{revision}); + assert_tree($last_commit); unless (-e "$GIT_DIR/refs/heads/master") { sys(qw(git-update-ref refs/heads/master),$last_commit); } @@ -314,7 +320,6 @@ sub commit { $svn_current_rev = svn_commit_tree($svn_current_rev, $c); } print "Done committing ",scalar @revs," revisions to SVN\n"; - } sub show_ignore { @@ -367,13 +372,11 @@ sub setup_git_svn { } sub assert_svn_wc_clean { - my ($svn_rev, $treeish) = @_; + my ($svn_rev) = @_; croak "$svn_rev is not an integer!\n" unless ($svn_rev =~ /^\d+$/); - croak "$treeish is not a sha1!\n" unless ($treeish =~ /^$sha1$/o); my $lcr = svn_info('.')->{'Last Changed Rev'}; if ($svn_rev != $lcr) { print STDERR "Checking for copy-tree ... "; - # use my @diff = grep(/^Index: /,(safe_qx(qw(svn diff), "-r$lcr:$svn_rev"))); if (@diff) { @@ -389,7 +392,6 @@ sub assert_svn_wc_clean { print STDERR $_ foreach @status; croak; } - assert_tree($treeish); } sub assert_tree { @@ -416,7 +418,7 @@ sub assert_tree { unlink $tmpindex or croak $!; } $ENV{GIT_INDEX_FILE} = $tmpindex; - git_addremove(); + index_changes(1); chomp(my $tree = `git-write-tree`); if ($old_index) { $ENV{GIT_INDEX_FILE} = $old_index; @@ -426,6 +428,7 @@ sub assert_tree { if ($tree ne $expected) { croak "Tree mismatch, Got: $tree, Expected: $expected\n"; } + unlink $tmpindex; } sub parse_diff_tree { @@ -562,7 +565,8 @@ sub precommit_check { sub svn_checkout_tree { my ($svn_rev, $treeish) = @_; my $from = file_to_s("$REV_DIR/$svn_rev"); - assert_svn_wc_clean($svn_rev,$from); + assert_svn_wc_clean($svn_rev); + assert_tree($from); print "diff-tree $from $treeish\n"; my $pid = open my $diff_fh, '-|'; defined $pid or croak $!; @@ -852,13 +856,50 @@ sub svn_info { sub sys { system(@_) == 0 or croak $? } -sub git_addremove { - system( "git-diff-files --name-only -z ". - " | git-update-index --remove -z --stdin && ". - "git-ls-files -z --others ". - "'--exclude-from=$GIT_DIR/$GIT_SVN/info/exclude'". - " | git-update-index --add -z --stdin" - ) == 0 or croak $? +sub do_update_index { + my ($z_cmd, $cmd, $no_text_base) = @_; + + my $z = open my $p, '-|'; + defined $z or croak $!; + unless ($z) { exec @$z_cmd or croak $! } + + my $pid = open my $ui, '|-'; + defined $pid or croak $!; + unless ($pid) { + exec('git-update-index',"--$cmd",'-z','--stdin') or croak $!; + } + local $/ = "\0"; + while (my $x = <$p>) { + chomp $x; + if (!$no_text_base && lstat $x && ! -l _) { + my $mode = -x _ ? 0755 : 0644; + my ($v,$d,$f) = File::Spec->splitpath($x); + my $tb = File::Spec->catfile($d, '.svn', 'tmp', + 'text-base',"$f.svn-base"); + $tb =~ s#^/##; + unless (-f $tb) { + $tb = File::Spec->catfile($d, '.svn', + 'text-base',"$f.svn-base"); + $tb =~ s#^/##; + } + unlink $x or croak $!; + cp($tb, $x) or croak $!; + chmod(($mode &~ umask), $x) or croak $!; + } + print $ui $x,"\0"; + } + close $ui or croak $!; +} + +sub index_changes { + my $no_text_base = shift; + do_update_index([qw/git-diff-files --name-only -z/], + 'remove', + $no_text_base); + do_update_index([qw/git-ls-files -z --others/, + "--exclude-from=$GIT_DIR/$GIT_SVN/info/exclude"], + 'add', + $no_text_base); } sub s_to_file { @@ -936,7 +977,7 @@ sub git_commit { defined $pid or croak $!; if ($pid == 0) { $ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX; - git_addremove(); + index_changes(); chomp(my $tree = `git-write-tree`); croak if $?; if (exists $tree_map{$tree}) { diff --git a/contrib/git-svn/t/lib-git-svn.sh b/contrib/git-svn/t/lib-git-svn.sh new file mode 100644 index 0000000..a98e9d1 --- /dev/null +++ b/contrib/git-svn/t/lib-git-svn.sh @@ -0,0 +1,39 @@ +PATH=$PWD/../:$PATH +if test -d ../../../t +then + cd ../../../t +else + echo "Must be run in contrib/git-svn/t" >&2 + exit 1 +fi + +. ./test-lib.sh + +GIT_DIR=$PWD/.git +GIT_SVN_DIR=$GIT_DIR/git-svn +SVN_TREE=$GIT_SVN_DIR/tree + +svnadmin >/dev/null 2>&1 +if test $? != 1 +then + test_expect_success 'skipping contrib/git-svn test' : + test_done + exit +fi + +svn >/dev/null 2>&1 +if test $? != 1 +then + test_expect_success 'skipping contrib/git-svn test' : + test_done + exit +fi + +svnrepo=$PWD/svnrepo + +set -e + +svnadmin create $svnrepo +svnrepo="file://$svnrepo/test-git-svn" + + diff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/contrib/git-svn/t/t0000-contrib-git-svn.sh index 80ad357..8b3a0d9 100644 --- a/contrib/git-svn/t/t0000-contrib-git-svn.sh +++ b/contrib/git-svn/t/t0000-contrib-git-svn.sh @@ -3,48 +3,10 @@ # # Copyright (c) 2006 Eric Wong # - -PATH=$PWD/../:$PATH test_description='git-svn tests' -if test -d ../../../t -then - cd ../../../t -else - echo "Must be run in contrib/git-svn/t" >&2 - exit 1 -fi - -. ./test-lib.sh - -GIT_DIR=$PWD/.git -GIT_SVN_DIR=$GIT_DIR/git-svn -SVN_TREE=$GIT_SVN_DIR/tree - -svnadmin >/dev/null 2>&1 -if test $? != 1 -then - test_expect_success 'skipping contrib/git-svn test' : - test_done - exit -fi - -svn >/dev/null 2>&1 -if test $? != 1 -then - test_expect_success 'skipping contrib/git-svn test' : - test_done - exit -fi - -svnrepo=$PWD/svnrepo - -set -e - -svnadmin create $svnrepo -svnrepo="file://$svnrepo/test-git-svn" +. ./lib-git-svn.sh mkdir import - cd import echo foo > foo @@ -55,10 +17,9 @@ mkdir -p bar echo 'zzz' > bar/zzz echo '#!/bin/sh' > exec.sh chmod +x exec.sh -svn import -m 'import for git-svn' . $svnrepo >/dev/null +svn import -m 'import for git-svn' . "$svnrepo" >/dev/null cd .. - rm -rf import test_expect_success \ diff --git a/contrib/git-svn/t/t0001-contrib-git-svn-props.sh b/contrib/git-svn/t/t0001-contrib-git-svn-props.sh new file mode 100644 index 0000000..20c5c4e --- /dev/null +++ b/contrib/git-svn/t/t0001-contrib-git-svn-props.sh @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git-svn property tests' +. ./lib-git-svn.sh + +mkdir import + +cd import + cat >> kw.c <<'' +/* Make it look like somebody copied a file from CVS into SVN: */ +/* $Id: kw.c,v 1.1.1.1 1994/03/06 00:00:00 eric Exp $ */ + + svn import -m 'import for git-svn' . "$svnrepo" >/dev/null +cd .. + +rm -rf import +svn co "$svnrepo" test_wc + +cd test_wc + echo 'Greetings' >> kw.c + svn commit -m 'Not yet an $Id$' + svn up + + echo 'Hello world' >> kw.c + svn commit -m 'Modified file, but still not yet an $Id$' + svn up + + svn propset svn:keywords Id kw.c + svn commit -m 'Propset $Id$' + svn up +cd .. + +git-svn init "$svnrepo" +git-svn fetch + +git checkout -b mybranch remotes/git-svn +echo 'Hi again' >> kw.c +name='test svn:keywords ignoring' + +git commit -a -m "$name" +git-svn commit remotes/git-svn..mybranch +git pull . remotes/git-svn + +expect='/* $Id$ */' +got="`sed -ne 2p kw.c`" +test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'" + +test_done -- 1.3.2.g7d11 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: git-svn vs. $Id$ 2006-05-21 3:03 ` [PATCH] git-svn: ignore expansion of svn:keywords Eric Wong @ 2006-05-24 2:23 ` Eric Wong 2006-05-24 2:23 ` [PATCH] git-svn: starting a 1.1.0-pre development version Eric Wong 0 siblings, 1 reply; 8+ messages in thread From: Eric Wong @ 2006-05-24 2:23 UTC (permalink / raw) To: Tommi Virtanen; +Cc: Junio C Hamano, git Tommi: I'm reasonably confident about this patch, but I won't be getting much real-world usage since I rarely see repos that use svn:keywords, and I'm afflicted with RSI which prevents me from doing very much in front of a computer these days. So feedback/testing from you or any other git-svn guine^Wusers would be greatly appreciated. Junio: This is probably safe enough for next or even master, the one in pu is completely broken wrt svn:eol-style. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH] git-svn: starting a 1.1.0-pre development version 2006-05-24 2:23 ` git-svn vs. $Id$ Eric Wong @ 2006-05-24 2:23 ` Eric Wong 2006-05-24 2:23 ` [PATCH] git-svn: ignore expansion of svn:keywords Eric Wong 0 siblings, 1 reply; 8+ messages in thread From: Eric Wong @ 2006-05-24 2:23 UTC (permalink / raw) To: Tommi Virtanen; +Cc: Junio C Hamano, git, Eric Wong Some not-very-well-tested changes coming... Signed-off-by: Eric Wong <normalperson@yhbt.net> --- contrib/git-svn/git-svn.perl | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) 49967a4b7bc2c9938b0ebf0670cd47d4ccfe85a3 diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index de13a96..39471b5 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -8,7 +8,7 @@ use vars qw/ $AUTHOR $VERSION $GIT_SVN_INDEX $GIT_SVN $GIT_DIR $REV_DIR/; $AUTHOR = 'Eric Wong <normalperson@yhbt.net>'; -$VERSION = '1.0.0'; +$VERSION = '1.1.0-pre'; use Cwd qw/abs_path/; $GIT_DIR = abs_path($ENV{GIT_DIR} || '.git'); -- 1.3.2.g7d11 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH] git-svn: ignore expansion of svn:keywords 2006-05-24 2:23 ` [PATCH] git-svn: starting a 1.1.0-pre development version Eric Wong @ 2006-05-24 2:23 ` Eric Wong 0 siblings, 0 replies; 8+ messages in thread From: Eric Wong @ 2006-05-24 2:23 UTC (permalink / raw) To: Tommi Virtanen; +Cc: Junio C Hamano, git, Eric Wong Unlike my earlier test patch, this also checks svn:eol-style and makes sure it's applied to working copy updates. This is definitely more correct than my original attempt at killing keyword expansions, but I still haven't tested it enough to know. Feedback would be much appreciated. Also changed assert_svn_wc_clean() to only work on the svn working copy. This requires a separate call to assert_tree() to check wc integrity against git in preparation for another change I'm planning. Signed-off-by: Eric Wong <normalperson@yhbt.net> --- contrib/git-svn/Makefile | 1 contrib/git-svn/git-svn.perl | 106 +++++++++++++++---- contrib/git-svn/t/lib-git-svn.sh | 39 +++++++ contrib/git-svn/t/t0000-contrib-git-svn.sh | 43 -------- contrib/git-svn/t/t0001-contrib-git-svn-props.sh | 125 ++++++++++++++++++++++ 5 files changed, 254 insertions(+), 60 deletions(-) create mode 100644 contrib/git-svn/t/lib-git-svn.sh create mode 100644 contrib/git-svn/t/t0001-contrib-git-svn-props.sh b9ba79157fc4f92e14aac89d9a5f838539d6eede diff --git a/contrib/git-svn/Makefile b/contrib/git-svn/Makefile index acedf73..48f60b3 100644 --- a/contrib/git-svn/Makefile +++ b/contrib/git-svn/Makefile @@ -30,6 +30,7 @@ git-svn.html : git-svn.txt -f ../../Documentation/asciidoc.conf $< test: git-svn cd t && $(SHELL) ./t0000-contrib-git-svn.sh + cd t && $(SHELL) ./t0001-contrib-git-svn-props.sh clean: rm -f git-svn *.xml *.html *.1 diff --git a/contrib/git-svn/git-svn.perl b/contrib/git-svn/git-svn.perl index 39471b5..fc9b7ef 100755 --- a/contrib/git-svn/git-svn.perl +++ b/contrib/git-svn/git-svn.perl @@ -39,6 +39,10 @@ my $_svn_co_url_revs; my %fc_opts = ( 'no-ignore-externals' => \$_no_ignore_ext, 'branch|b=s' => \@_branch_from, 'authors-file|A=s' => \$_authors ); + +# yes, 'native' sets "\n". Patches to fix this for non-*nix systems welcome: +my %EOL = ( CR => "\015", LF => "\012", CRLF => "\015\012", native => "\012" ); + my %cmd = ( fetch => [ \&fetch, "Download new revisions from SVN", { 'revision|r=s' => \$_revision, %fc_opts } ], @@ -207,7 +211,7 @@ sub rebuild { push @svn_up, '--ignore-externals' unless $_no_ignore_ext; sys(@svn_up,"-r$newest_rev"); $ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX; - git_addremove(); + index_changes(); exec('git-write-tree'); } waitpid $pid, 0; @@ -249,7 +253,7 @@ sub fetch { chdir $SVN_WC or croak $!; read_uuid(); $last_commit = git_commit($base, @parents); - assert_svn_wc_clean($base->{revision}, $last_commit); + assert_tree($last_commit); } else { chdir $SVN_WC or croak $!; read_uuid(); @@ -259,16 +263,20 @@ sub fetch { push @svn_up, '--ignore-externals' unless $_no_ignore_ext; my $last = $base; while (my $log_msg = next_log_entry($svn_log)) { - assert_svn_wc_clean($last->{revision}, $last_commit); + assert_tree($last_commit); if ($last->{revision} >= $log_msg->{revision}) { croak "Out of order: last >= current: ", "$last->{revision} >= $log_msg->{revision}\n"; } + # Revert is needed for cases like: + # https://svn.musicpd.org/Jamming/trunk (r166:167), but + # I can't seem to reproduce something like that on a test... + sys(qw/svn revert -R ./); + assert_svn_wc_clean($last->{revision}); sys(@svn_up,"-r$log_msg->{revision}"); $last_commit = git_commit($log_msg, $last_commit, @parents); $last = $log_msg; } - assert_svn_wc_clean($last->{revision}, $last_commit); unless (-e "$GIT_DIR/refs/heads/master") { sys(qw(git-update-ref refs/heads/master),$last_commit); } @@ -314,7 +322,6 @@ sub commit { $svn_current_rev = svn_commit_tree($svn_current_rev, $c); } print "Done committing ",scalar @revs," revisions to SVN\n"; - } sub show_ignore { @@ -367,13 +374,11 @@ sub setup_git_svn { } sub assert_svn_wc_clean { - my ($svn_rev, $treeish) = @_; + my ($svn_rev) = @_; croak "$svn_rev is not an integer!\n" unless ($svn_rev =~ /^\d+$/); - croak "$treeish is not a sha1!\n" unless ($treeish =~ /^$sha1$/o); my $lcr = svn_info('.')->{'Last Changed Rev'}; if ($svn_rev != $lcr) { print STDERR "Checking for copy-tree ... "; - # use my @diff = grep(/^Index: /,(safe_qx(qw(svn diff), "-r$lcr:$svn_rev"))); if (@diff) { @@ -389,7 +394,6 @@ sub assert_svn_wc_clean { print STDERR $_ foreach @status; croak; } - assert_tree($treeish); } sub assert_tree { @@ -416,7 +420,7 @@ sub assert_tree { unlink $tmpindex or croak $!; } $ENV{GIT_INDEX_FILE} = $tmpindex; - git_addremove(); + index_changes(1); chomp(my $tree = `git-write-tree`); if ($old_index) { $ENV{GIT_INDEX_FILE} = $old_index; @@ -426,6 +430,7 @@ sub assert_tree { if ($tree ne $expected) { croak "Tree mismatch, Got: $tree, Expected: $expected\n"; } + unlink $tmpindex; } sub parse_diff_tree { @@ -562,7 +567,8 @@ sub precommit_check { sub svn_checkout_tree { my ($svn_rev, $treeish) = @_; my $from = file_to_s("$REV_DIR/$svn_rev"); - assert_svn_wc_clean($svn_rev,$from); + assert_svn_wc_clean($svn_rev); + assert_tree($from); print "diff-tree $from $treeish\n"; my $pid = open my $diff_fh, '-|'; defined $pid or croak $!; @@ -852,13 +858,75 @@ sub svn_info { sub sys { system(@_) == 0 or croak $? } -sub git_addremove { - system( "git-diff-files --name-only -z ". - " | git-update-index --remove -z --stdin && ". - "git-ls-files -z --others ". - "'--exclude-from=$GIT_DIR/$GIT_SVN/info/exclude'". - " | git-update-index --add -z --stdin" - ) == 0 or croak $? +sub eol_cp { + my ($from, $to) = @_; + my $es = safe_qx(qw/svn propget svn:eol-style/, $to); + open my $rfd, '<', $from or croak $!; + binmode $rfd or croak $!; + open my $wfd, '>', $to or croak $!; + binmode $wfd or croak $!; + + my $eol = $EOL{$es} or undef; + if ($eol) { + print "$eol: $from => $to\n"; + } + my $buf; + while (1) { + my ($r, $w, $t); + defined($r = sysread($rfd, $buf, 4096)) or croak $!; + return unless $r; + $buf =~ s/(?:\015|\012|\015\012)/$eol/gs if $eol; + for ($w = 0; $w < $r; $w += $t) { + $t = syswrite($wfd, $buf, $r - $w, $w) or croak $!; + } + } +} + +sub do_update_index { + my ($z_cmd, $cmd, $no_text_base) = @_; + + my $z = open my $p, '-|'; + defined $z or croak $!; + unless ($z) { exec @$z_cmd or croak $! } + + my $pid = open my $ui, '|-'; + defined $pid or croak $!; + unless ($pid) { + exec('git-update-index',"--$cmd",'-z','--stdin') or croak $!; + } + local $/ = "\0"; + while (my $x = <$p>) { + chomp $x; + if (!$no_text_base && lstat $x && ! -l _ && + safe_qx(qw/svn propget svn:keywords/,$x)) { + my $mode = -x _ ? 0755 : 0644; + my ($v,$d,$f) = File::Spec->splitpath($x); + my $tb = File::Spec->catfile($d, '.svn', 'tmp', + 'text-base',"$f.svn-base"); + $tb =~ s#^/##; + unless (-f $tb) { + $tb = File::Spec->catfile($d, '.svn', + 'text-base',"$f.svn-base"); + $tb =~ s#^/##; + } + unlink $x or croak $!; + eol_cp($tb, $x); + chmod(($mode &~ umask), $x) or croak $!; + } + print $ui $x,"\0"; + } + close $ui or croak $!; +} + +sub index_changes { + my $no_text_base = shift; + do_update_index([qw/git-diff-files --name-only -z/], + 'remove', + $no_text_base); + do_update_index([qw/git-ls-files -z --others/, + "--exclude-from=$GIT_DIR/$GIT_SVN/info/exclude"], + 'add', + $no_text_base); } sub s_to_file { @@ -936,7 +1004,7 @@ sub git_commit { defined $pid or croak $!; if ($pid == 0) { $ENV{GIT_INDEX_FILE} = $GIT_SVN_INDEX; - git_addremove(); + index_changes(); chomp(my $tree = `git-write-tree`); croak if $?; if (exists $tree_map{$tree}) { diff --git a/contrib/git-svn/t/lib-git-svn.sh b/contrib/git-svn/t/lib-git-svn.sh new file mode 100644 index 0000000..a98e9d1 --- /dev/null +++ b/contrib/git-svn/t/lib-git-svn.sh @@ -0,0 +1,39 @@ +PATH=$PWD/../:$PATH +if test -d ../../../t +then + cd ../../../t +else + echo "Must be run in contrib/git-svn/t" >&2 + exit 1 +fi + +. ./test-lib.sh + +GIT_DIR=$PWD/.git +GIT_SVN_DIR=$GIT_DIR/git-svn +SVN_TREE=$GIT_SVN_DIR/tree + +svnadmin >/dev/null 2>&1 +if test $? != 1 +then + test_expect_success 'skipping contrib/git-svn test' : + test_done + exit +fi + +svn >/dev/null 2>&1 +if test $? != 1 +then + test_expect_success 'skipping contrib/git-svn test' : + test_done + exit +fi + +svnrepo=$PWD/svnrepo + +set -e + +svnadmin create $svnrepo +svnrepo="file://$svnrepo/test-git-svn" + + diff --git a/contrib/git-svn/t/t0000-contrib-git-svn.sh b/contrib/git-svn/t/t0000-contrib-git-svn.sh index f400202..a07fbad 100644 --- a/contrib/git-svn/t/t0000-contrib-git-svn.sh +++ b/contrib/git-svn/t/t0000-contrib-git-svn.sh @@ -3,48 +3,10 @@ # # Copyright (c) 2006 Eric Wong # - -PATH=$PWD/../:$PATH test_description='git-svn tests' -if test -d ../../../t -then - cd ../../../t -else - echo "Must be run in contrib/git-svn/t" >&2 - exit 1 -fi - -. ./test-lib.sh - -GIT_DIR=$PWD/.git -GIT_SVN_DIR=$GIT_DIR/git-svn -SVN_TREE=$GIT_SVN_DIR/tree - -svnadmin >/dev/null 2>&1 -if test $? != 1 -then - test_expect_success 'skipping contrib/git-svn test' : - test_done - exit -fi - -svn >/dev/null 2>&1 -if test $? != 1 -then - test_expect_success 'skipping contrib/git-svn test' : - test_done - exit -fi - -svnrepo=$PWD/svnrepo - -set -e - -svnadmin create $svnrepo -svnrepo="file://$svnrepo/test-git-svn" +. ./lib-git-svn.sh mkdir import - cd import echo foo > foo @@ -55,10 +17,9 @@ mkdir -p bar echo 'zzz' > bar/zzz echo '#!/bin/sh' > exec.sh chmod +x exec.sh -svn import -m 'import for git-svn' . $svnrepo >/dev/null +svn import -m 'import for git-svn' . "$svnrepo" >/dev/null cd .. - rm -rf import test_expect_success \ diff --git a/contrib/git-svn/t/t0001-contrib-git-svn-props.sh b/contrib/git-svn/t/t0001-contrib-git-svn-props.sh new file mode 100644 index 0000000..6fa7889 --- /dev/null +++ b/contrib/git-svn/t/t0001-contrib-git-svn-props.sh @@ -0,0 +1,125 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git-svn property tests' +. ./lib-git-svn.sh + +mkdir import + +a_crlf= +a_lf= +a_cr= +a_ne_crlf= +a_ne_lf= +a_ne_cr= +a_empty= +a_empty_lf= +a_empty_cr= +a_empty_crlf= + +cd import + cat >> kw.c <<'' +/* Make it look like somebody copied a file from CVS into SVN: */ +/* $Id: kw.c,v 1.1.1.1 1994/03/06 00:00:00 eric Exp $ */ + + printf "Hello\r\nWorld\r\n" > crlf + a_crlf=`git-hash-object -w crlf` + printf "Hello\rWorld\r" > cr + a_cr=`git-hash-object -w cr` + printf "Hello\nWorld\n" > lf + a_lf=`git-hash-object -w lf` + + printf "Hello\r\nWorld" > ne_crlf + a_ne_crlf=`git-hash-object -w ne_crlf` + printf "Hello\nWorld" > ne_lf + a_ne_lf=`git-hash-object -w ne_lf` + printf "Hello\rWorld" > ne_cr + a_ne_cr=`git-hash-object -w ne_cr` + + touch empty + a_empty=`git-hash-object -w empty` + printf "\n" > empty_lf + a_empty_lf=`git-hash-object -w empty_lf` + printf "\r" > empty_cr + a_empty_cr=`git-hash-object -w empty_cr` + printf "\r\n" > empty_crlf + a_empty_crlf=`git-hash-object -w empty_crlf` + + svn import -m 'import for git-svn' . "$svnrepo" >/dev/null +cd .. + +rm -rf import +svn co "$svnrepo" test_wc + +cd test_wc + echo 'Greetings' >> kw.c + svn commit -m 'Not yet an $Id$' + svn up + + echo 'Hello world' >> kw.c + svn commit -m 'Modified file, but still not yet an $Id$' + svn up + + svn propset svn:keywords Id kw.c + svn commit -m 'Propset $Id$' + svn up +cd .. + +git-svn init "$svnrepo" +git-svn fetch + +git checkout -b mybranch remotes/git-svn +echo 'Hi again' >> kw.c +name='test svn:keywords ignoring' + +git commit -a -m "$name" +git-svn commit remotes/git-svn..mybranch +git pull . remotes/git-svn + +expect='/* $Id$ */' +got="`sed -ne 2p kw.c`" +test_expect_success 'raw $Id$ found in kw.c' "test '$expect' = '$got'" + +cd test_wc + svn propset svn:eol-style CR empty + svn propset svn:eol-style CR crlf + svn propset svn:eol-style CR ne_crlf + svn commit -m 'propset CR on crlf files' + svn up +cd .. + +git-svn fetch +git pull . remotes/git-svn + +svn co "$svnrepo" new_wc +for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf +do + test_expect_success "Comparing $i" "cmp $i new_wc/$i" +done + + +cd test_wc + printf '$Id$\rHello\rWorld\r' > cr + printf '$Id$\rHello\rWorld' > ne_cr + a_cr=`printf '$Id$\r\nHello\r\nWorld\r\n' | git-hash-object --stdin` + a_ne_cr=`printf '$Id$\r\nHello\r\nWorld' | git-hash-object --stdin` + svn propset svn:eol-style CRLF cr + svn propset svn:eol-style CRLF ne_cr + svn propset svn:keywords Id cr + svn propset svn:keywords Id ne_cr + svn commit -m 'propset CRLF on cr files' + svn up +cd .. + +git-svn fetch +git pull . remotes/git-svn + +b_cr="`git-hash-object cr`" +b_ne_cr="`git-hash-object ne_cr`" + +test_expect_success 'CRLF + $Id$' "test '$a_cr' = '$b_cr'" +test_expect_success 'CRLF + $Id$ (no newline)' "test '$a_ne_cr' = '$b_ne_cr'" + +test_done -- 1.3.2.g7d11 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-05-24 2:23 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-05-16 17:33 git-svn vs. $Id$ Tommi Virtanen 2006-05-16 17:48 ` Linus Torvalds 2006-05-16 18:12 ` Tommi Virtanen 2006-05-21 1:12 ` Eric Wong 2006-05-21 3:03 ` [PATCH] git-svn: ignore expansion of svn:keywords Eric Wong 2006-05-24 2:23 ` git-svn vs. $Id$ Eric Wong 2006-05-24 2:23 ` [PATCH] git-svn: starting a 1.1.0-pre development version Eric Wong 2006-05-24 2:23 ` [PATCH] git-svn: ignore expansion of svn:keywords Eric Wong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).