{"thread":{"id":"17360","subject":"[PATCH] git-svn: Add test for --ignore-paths parameter","startedAt":"2009-01-25T22:21:40Z","lastAt":"2009-01-25T22:21:42Z","messageCount":3,"participants":["Vitaly \"_Vi\" Shukela"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"101887","messageId":"1232922102-6144-1-git-send-email-public_vi@tut.by","threadId":"17360","inReplyTo":null,"subject":"[PATCH] git-svn: add --ignore-paths option for fetching","fromName":"Vitaly \"_Vi\" Shukela","fromEmail":"public_vi@tut.by","sentAt":"2009-01-25T22:21:40Z","receivedAt":"2009-01-25T22:21:40Z","isPatch":true,"sender":{"key":"vi0oss@gmail.com","avatar":"https://avatars.githubusercontent.com/u/173219?v=4"},"body":"This will be useful when somebody want to checkout something partially from\nrepository with some non-standart layout or exclude some files from it.\nExample: repository has structure /module-{a,b,c}/{trunk,branches,tags}/...\nModules are interdependent, and you want it to be single repostory (to commit\nto all modules simultaneously and view complete history), but do not want\nbranches and tags be checked out into working copy.\nOther use case is excluding some large blobs.\n\nThe quirk for now is that user must specify this option every fetch/rebase;\nin other case he may get extra files or \"file not found\" errors. It may be\nwill be resolved by adding regular expression to .git/config into\n[svn-remote ...] to make it persistent.\n\nSigned-off-by: Vitaly \"_Vi\" Shukela <public_vi@tut.by>\n---\n git-svn.perl |   43 +++++++++++++++++++++++++++----------------\n 1 files changed, 27 insertions(+), 16 deletions(-)\n\ndiff --git a/git-svn.perl b/git-svn.perl\nindex d4cb538..40b0e9e 100755\n--- a/git-svn.perl\n+++ b/git-svn.perl\n@@ -70,7 +70,8 @@ my ($_stdin, $_help, $_edit,\n $Git::SVN::_follow_parent = 1;\n my %remote_opts = ( 'username=s' => \\$Git::SVN::Prompt::_username,\n                     'config-dir=s' => \\$Git::SVN::Ra::config_dir,\n-                    'no-auth-cache' => \\$Git::SVN::Prompt::_no_auth_cache );\n+                    'no-auth-cache' => \\$Git::SVN::Prompt::_no_auth_cache,\n+                    'ignore-paths=s' => \\$SVN::Git::Fetcher::ignore_regex );\n my %fc_opts = ( 'follow-parent|follow!' => \\$Git::SVN::_follow_parent,\n \t\t'authors-file|A=s' => \\$_authors,\n \t\t'repack:i' => \\$Git::SVN::_repack,\n@@ -3245,6 +3246,21 @@ use warnings;\n use Carp qw/croak/;\n use File::Temp qw/tempfile/;\n use IO::File qw//;\n+use vars qw/ $ignore_regex/;\n+\n+# returns true if a given path is inside a \".git\" directory\n+sub in_dot_git($) {\n+\t$_[0] =~ m{(?:^|/)\\.git(?:/|$)};\n+}\n+\n+# 0 -- don't ignore, 1 -- ignore\n+sub is_path_ignored($) {\n+    my ($path) = @_;\n+    return 1 if in_dot_git($path);\n+    return 0 unless defined($ignore_regex);\n+    return 1 if $path =~ m!$ignore_regex!o;\n+    return 0;\n+}\n \n # file baton members: path, mode_a, mode_b, pool, fh, blob, base\n sub new {\n@@ -3292,11 +3308,6 @@ sub _mark_empty_symlinks {\n \t\\%ret;\n }\n \n-# returns true if a given path is inside a \".git\" directory\n-sub in_dot_git {\n-\t$_[0] =~ m{(?:^|/)\\.git(?:/|$)};\n-}\n-\n sub set_path_strip {\n \tmy ($self, $path) = @_;\n \t$self->{path_strip} = qr/^\\Q$path\\E(\\/|$)/ if length $path;\n@@ -3322,7 +3333,7 @@ sub git_path {\n \n sub delete_entry {\n \tmy ($self, $path, $rev, $pb) = @_;\n-\treturn undef if in_dot_git($path);\n+\treturn undef if is_path_ignored($path);\n \n \tmy $gpath = $self->git_path($path);\n \treturn undef if ($gpath eq '');\n@@ -3352,7 +3363,7 @@ sub open_file {\n \tmy ($self, $path, $pb, $rev) = @_;\n \tmy ($mode, $blob);\n \n-\tgoto out if in_dot_git($path);\n+\tgoto out if is_path_ignored($path);\n \n \tmy $gpath = $self->git_path($path);\n \t($mode, $blob) = (command('ls-tree', $self->{c}, '--', $gpath)\n@@ -3372,7 +3383,7 @@ sub add_file {\n \tmy ($self, $path, $pb, $cp_path, $cp_rev) = @_;\n \tmy $mode;\n \n-\tif (!in_dot_git($path)) {\n+\tif (!is_path_ignored($path)) {\n \t\tmy ($dir, $file) = ($path =~ m#^(.*?)/?([^/]+)$#);\n \t\tdelete $self->{empty}->{$dir};\n \t\t$mode = '100644';\n@@ -3383,7 +3394,7 @@ sub add_file {\n \n sub add_directory {\n \tmy ($self, $path, $cp_path, $cp_rev) = @_;\n-\tgoto out if in_dot_git($path);\n+\tgoto out if is_path_ignored($path);\n \tmy $gpath = $self->git_path($path);\n \tif ($gpath eq '') {\n \t\tmy ($ls, $ctx) = command_output_pipe(qw/ls-tree\n@@ -3407,7 +3418,7 @@ out:\n \n sub change_dir_prop {\n \tmy ($self, $db, $prop, $value) = @_;\n-\treturn undef if in_dot_git($db->{path});\n+\treturn undef if is_path_ignored($db->{path});\n \t$self->{dir_prop}->{$db->{path}} ||= {};\n \t$self->{dir_prop}->{$db->{path}}->{$prop} = $value;\n \tundef;\n@@ -3415,7 +3426,7 @@ sub change_dir_prop {\n \n sub absent_directory {\n \tmy ($self, $path, $pb) = @_;\n-\treturn undef if in_dot_git($pb->{path});\n+\treturn undef if is_path_ignored($path);\n \t$self->{absent_dir}->{$pb->{path}} ||= [];\n \tpush @{$self->{absent_dir}->{$pb->{path}}}, $path;\n \tundef;\n@@ -3423,7 +3434,7 @@ sub absent_directory {\n \n sub absent_file {\n \tmy ($self, $path, $pb) = @_;\n-\treturn undef if in_dot_git($pb->{path});\n+\treturn undef if is_path_ignored($path);\n \t$self->{absent_file}->{$pb->{path}} ||= [];\n \tpush @{$self->{absent_file}->{$pb->{path}}}, $path;\n \tundef;\n@@ -3431,7 +3442,7 @@ sub absent_file {\n \n sub change_file_prop {\n \tmy ($self, $fb, $prop, $value) = @_;\n-\treturn undef if in_dot_git($fb->{path});\n+\treturn undef if is_path_ignored($fb->{path});\n \tif ($prop eq 'svn:executable') {\n \t\tif ($fb->{mode_b} != 120000) {\n \t\t\t$fb->{mode_b} = defined $value ? 100755 : 100644;\n@@ -3447,7 +3458,7 @@ sub change_file_prop {\n \n sub apply_textdelta {\n \tmy ($self, $fb, $exp) = @_;\n-\treturn undef if (in_dot_git($fb->{path}));\n+\treturn undef if is_path_ignored($fb->{path});\n \tmy $fh = $::_repository->temp_acquire('svn_delta');\n \t# $fh gets auto-closed() by SVN::TxDelta::apply(),\n \t# (but $base does not,) so dup() it for reading in close_file\n@@ -3494,7 +3505,7 @@ sub apply_textdelta {\n \n sub close_file {\n \tmy ($self, $fb, $exp) = @_;\n-\treturn undef if (in_dot_git($fb->{path}));\n+\treturn undef if is_path_ignored($fb->{path});\n \n \tmy $hash;\n \tmy $path = $self->git_path($fb->{path});\n-- \n1.5.6.5\n"},{"id":"101886","messageId":"1232922102-6144-2-git-send-email-public_vi@tut.by","threadId":"17360","inReplyTo":"1232922102-6144-1-git-send-email-public_vi@tut.by","subject":"[PATCH] git-svn: documented --ignore-paths","fromName":"Vitaly \"_Vi\" Shukela","fromEmail":"public_vi@tut.by","sentAt":"2009-01-25T22:21:41Z","receivedAt":"2009-01-25T22:21:41Z","isPatch":true,"sender":{"key":"vi0oss@gmail.com","avatar":"https://avatars.githubusercontent.com/u/173219?v=4"},"body":"Documented --ignore-paths option of git-svn to inform users about\nthe feature and provide some examples.\n\nSigned-off-by: Vitaly \"_Vi\" Shukela <public_vi@tut.by>\n---\n Documentation/git-svn.txt |   13 +++++++++++++\n 1 files changed, 13 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt\nindex 63d2f5e..2215fcb 100644\n--- a/Documentation/git-svn.txt\n+++ b/Documentation/git-svn.txt\n@@ -103,6 +103,19 @@ repository to be able to interoperate with someone else's local Git\n repository, either don't use this option or you should both use it in\n the same local timezone.\n \n+--ignore-paths=<regex>;;\n+\tThis allows one to specify Perl regular expression that will\n+\tcause skipping of all matching paths from checkout from SVN.\n+\tExamples: \n+\n+\t--ignore-paths=\"^doc\" - skip \"doc*\" directory for every fetch.\n+\n+\t--ignore-paths=\"^[^/]+/(?:branches|tags)\" - skip \"branches\"\n+\t    and \"tags\" of first level directories.\n+\n+\tRegular expression is not persistent, you should specify\n+\tit every time when fetching.\n+\n 'clone'::\n \tRuns 'init' and 'fetch'.  It will automatically create a\n \tdirectory based on the basename of the URL passed to it;\n-- \n1.5.6.5\n"},{"id":"101885","messageId":"1232922102-6144-3-git-send-email-public_vi@tut.by","threadId":"17360","inReplyTo":"1232922102-6144-2-git-send-email-public_vi@tut.by","subject":"[PATCH] git-svn: Add test for --ignore-paths parameter","fromName":"Vitaly \"_Vi\" Shukela","fromEmail":"public_vi@tut.by","sentAt":"2009-01-25T22:21:42Z","receivedAt":"2009-01-25T22:21:42Z","isPatch":true,"sender":{"key":"vi0oss@gmail.com","avatar":"https://avatars.githubusercontent.com/u/173219?v=4"},"body":"Added a test for this option, similar to (and based on) t9133 about ignorance of .git directories\n\nSigned-off-by: Vitaly \"_Vi\" Shukela <public_vi@tut.by>\n---\n t/t9134-git-svn-ignore-paths.sh |   97 +++++++++++++++++++++++++++++++++++++++\n 1 files changed, 97 insertions(+), 0 deletions(-)\n create mode 100755 t/t9134-git-svn-ignore-paths.sh\n\ndiff --git a/t/t9134-git-svn-ignore-paths.sh b/t/t9134-git-svn-ignore-paths.sh\nnew file mode 100755\nindex 0000000..094cb6a\n--- /dev/null\n+++ b/t/t9134-git-svn-ignore-paths.sh\n@@ -0,0 +1,97 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2009 Eric Wong\n+#\n+\n+test_description='git svn property tests'\n+. ./lib-git-svn.sh\n+\n+test_expect_success 'setup test repository' '\n+\tsvn co \"$svnrepo\" s &&\n+\t(\n+\t\tcd s &&\n+\t\tmkdir qqq www &&\n+\t\techo test_qqq > qqq/test_qqq.txt &&\n+\t\techo test_www > www/test_www.txt &&\n+\t\tsvn add qqq &&\n+\t\tsvn add www &&\n+\t\tsvn commit -m \"create some files\" &&\n+\t\tsvn up &&\n+\t\techo hi >> www/test_www.txt &&\n+\t\tsvn commit -m \"modify www/test_www.txt\" &&\n+\t\tsvn up\n+\t)\n+'\n+\n+test_expect_success 'clone an SVN repository with ignored www directory' '\n+\tgit svn clone --ignore-paths=\"^www\" \"$svnrepo\" g &&\n+\techo test_qqq > expect &&\n+\tfor i in g/*/*.txt; do cat $i >> expect2; done &&\n+\ttest_cmp expect expect2\n+'\n+\n+test_expect_success 'SVN-side change outside of www' '\n+\t(\n+\t\tcd s &&\n+\t\techo b >> qqq/test_qqq.txt &&\n+\t\tsvn commit -m \"SVN-side change outside of www\" &&\n+\t\tsvn up &&\n+\t\tsvn log -v | fgrep \"SVN-side change outside of www\"\n+\t)\n+'\n+\n+test_expect_success 'update git svn-cloned repo' '\n+\t(\n+\t\tcd g &&\n+\t\tgit svn rebase --ignore-paths=\"^www\" &&\n+\t\techo -e \"test_qqq\\nb\" > expect &&\n+\t\tfor i in */*.txt; do cat $i >> expect2; done &&\n+\t\ttest_cmp expect2 expect &&\n+\t\trm expect expect2\n+\t)\n+'\n+\n+test_expect_success 'SVN-side change inside of ignored www' '\n+\t(\n+\t\tcd s &&\n+\t\techo zaq >> www/test_www.txt\n+\t\tsvn commit -m \"SVN-side change inside of www/test_www.txt\" &&\n+\t\tsvn up &&\n+\t\tsvn log -v | fgrep \"SVN-side change inside of www/test_www.txt\"\n+\t)\n+'\n+\n+test_expect_success 'update git svn-cloned repo' '\n+\t(\n+\t\tcd g &&\n+\t\tgit svn rebase --ignore-paths=\"^www\" &&\n+\t\techo -e \"test_qqq\\nb\" > expect &&\n+\t\tfor i in */*.txt; do cat $i >> expect2; done &&\n+\t\ttest_cmp expect2 expect &&\n+\t\trm expect expect2\n+\t)\n+'\n+\n+test_expect_success 'SVN-side change in and out of ignored www' '\n+\t(\n+\t\tcd s &&\n+\t\techo cvf >> www/test_www.txt\n+\t\techo ygg >> qqq/test_qqq.txt\n+\t\tsvn commit -m \"SVN-side change in and out of ignored www\" &&\n+\t\tsvn up &&\n+\t\tsvn log -v | fgrep \"SVN-side change in and out of ignored www\"\n+\t)\n+'\n+\n+test_expect_success 'update git svn-cloned repo again' '\n+\t(\n+\t\tcd g &&\n+\t\tgit svn rebase --ignore-paths=\"^www\" &&\n+\t\techo -e \"test_qqq\\nb\\nygg\" > expect &&\n+\t\tfor i in */*.txt; do cat $i >> expect2; done &&\n+\t\ttest_cmp expect2 expect &&\n+\t\trm expect expect2\n+\t)\n+'\n+\n+test_done\n-- \n1.5.6.5\n"}]}