From f359ae42ac102ef98d5708f1dc8b06e6af2701c1 Mon Sep 17 00:00:00 2001 From: Alexander Litvinov Date: Wed, 23 Nov 2005 16:19:41 +0600 Subject: git-mv is not able to handle big directories Use update-index --stdin to handle large number of files without breaking exec() argument storage limit. [jc: with minor cleanup from the version posted on the list] Signed-off-by: Junio C Hamano --- git-mv.perl | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index bf54c38413..b2eace5b26 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -193,14 +193,27 @@ if ($opt_n) { exit(1); } -my $rc; -if (scalar @changedfiles >0) { - $rc = system("git-update-index","--",@changedfiles); - die "git-update-index failed to update changed files with code $?\n" if $rc; +if (@changedfiles) { + open(H, "| git-update-index -z --stdin") + or die "git-update-index failed to update changed files with code $!\n"; + foreach my $fileName (@changedfiles) { + print H "$fileName\0"; + } + close(H); +} +if (@addedfiles) { + open(H, "| git-update-index --add -z --stdin") + or die "git-update-index failed to add new names with code $!\n"; + foreach my $fileName (@addedfiles) { + print H "$fileName\0"; + } + close(H); } -if (scalar @addedfiles >0) { - $rc = system("git-update-index","--add","--",@addedfiles); - die "git-update-index failed to add new names with code $?\n" if $rc; +if (@deletedfiles) { + open(H, "| git-update-index --remove -z --stdin") + or die "git-update-index failed to remove old names with code $!\n"; + foreach my $fileName (@deletedfiles) { + print H "$fileName\0"; + } + close(H); } -$rc = system("git-update-index","--remove","--",@deletedfiles); -die "git-update-index failed to remove old names with code $?\n" if $rc; -- cgit v1.2.3 From 3ae64dff6894adc995c913aaf7fe2d65c78c3529 Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Sun, 27 Nov 2005 21:58:52 +0100 Subject: git-mv: shrink usage, no usage on error Small fixes to be consistent with other git scripts: - usage message is only about options and arguments - on error, exit(1) without the usage message Additionally, "beautifies" output with -n a little bit Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano --- git-mv.perl | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index b2eace5b26..990bec5034 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -13,22 +13,8 @@ use Getopt::Std; sub usage() { print < -$0 [-f] [-k] [-n] ... - -In the first form, source must exist and be either a file, -symlink or directory, dest must not exist. It renames source to dest. -In the second form, the last argument has to be an existing -directory; the given sources will be moved into this directory. - -Updates the git cache to reflect the change. -Use "git commit" to make the change permanently. - -Options: - -f Force renaming/moving, even if target exists - -k Continue on error by skipping - not-existing or not revision-controlled source - -n Do nothing; show what would happen +$0 [-f] [-n] +$0 [-f] [-n] [-k] ... EOT exit(1); } @@ -38,8 +24,8 @@ my $GIT_DIR = $ENV{'GIT_DIR'} || ".git"; unless ( -d $GIT_DIR && -d $GIT_DIR . "/objects" && -d $GIT_DIR . "/objects/" && -d $GIT_DIR . "/refs") { - print "Git repository not found."; - usage(); + print "Error: git repository not found."; + exit(1); } @@ -70,7 +56,7 @@ else { print "Error: moving to directory '" . $ARGV[$argCount-1] . "' not possible; not exisiting\n"; - usage; + exit(1); } @srcArgs = ($ARGV[0]); @dstArgs = ($ARGV[1]); @@ -148,7 +134,7 @@ while(scalar @srcArgs > 0) { next; } print "Error: $bad\n"; - usage(); + exit(1); } push @srcs, $src; push @dsts, $dst; @@ -187,33 +173,39 @@ while(scalar @srcs > 0) { } if ($opt_n) { + if (@changedfiles) { print "Changed : ". join(", ", @changedfiles) ."\n"; + } + if (@addedfiles) { print "Adding : ". join(", ", @addedfiles) ."\n"; + } + if (@deletedfiles) { print "Deleting : ". join(", ", @deletedfiles) ."\n"; - exit(1); + } } - -if (@changedfiles) { +else { + if (@changedfiles) { open(H, "| git-update-index -z --stdin") or die "git-update-index failed to update changed files with code $!\n"; foreach my $fileName (@changedfiles) { print H "$fileName\0"; } close(H); -} -if (@addedfiles) { + } + if (@addedfiles) { open(H, "| git-update-index --add -z --stdin") or die "git-update-index failed to add new names with code $!\n"; foreach my $fileName (@addedfiles) { print H "$fileName\0"; } close(H); -} -if (@deletedfiles) { + } + if (@deletedfiles) { open(H, "| git-update-index --remove -z --stdin") or die "git-update-index failed to remove old names with code $!\n"; foreach my $fileName (@deletedfiles) { print H "$fileName\0"; } close(H); + } } -- cgit v1.2.3 From f6bc189a457b2575587f26e27f1eabdd615b2d78 Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Sun, 27 Nov 2005 22:04:14 +0100 Subject: git-mv: keep git index consistent with file system on failed rename When doing multiple renames, and a rename in the middle fails, git-mv did not store the successful renames in the git index; this is fixed by delaying the error message on a failed rename to after the git updating. Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano --- git-mv.perl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index 990bec5034..ac19876fec 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -142,14 +142,17 @@ while(scalar @srcArgs > 0) { # Final pass: rename/move my (@deletedfiles,@addedfiles,@changedfiles); +$bad = ""; while(scalar @srcs > 0) { $src = shift @srcs; $dst = shift @dsts; if ($opt_n || $opt_v) { print "Renaming $src to $dst\n"; } if (!$opt_n) { - rename($src,$dst) - or die "rename failed: $!"; + if (!rename($src,$dst)) { + $bad = "renaming '$src' failed: $!"; + last; + } } $safesrc = quotemeta($src); @@ -209,3 +212,8 @@ else { close(H); } } + +if ($bad ne "") { + print "Error: $bad\n"; + exit(1); +} -- cgit v1.2.3 From ca203ee7db708baa278950501f8d01f29c5190be Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Sun, 27 Nov 2005 22:06:42 +0100 Subject: git-mv: fully detect 'directory moved into itself' This gives a better error message when trying to move a directory into some subdirectory of itself; ie. no real bug fix: renaming already failed before, but with a strange "invalid argument". Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano --- git-mv.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index ac19876fec..8d294d6529 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -108,7 +108,7 @@ while(scalar @srcArgs > 0) { } } - if (($bad eq "") && ($src eq $dstDir)) { + if (($bad eq "") && ($dst =~ /^$src\//)) { $bad = "can not move directory '$src' into itself"; } -- cgit v1.2.3 From 26169747b811b8ecd5693adfce4f5c7e322d2487 Mon Sep 17 00:00:00 2001 From: Josef Weidendorfer Date: Sun, 27 Nov 2005 22:11:33 +0100 Subject: git-mv: follow -k request even on failing renames -k requests to keep running on an error condition. Previously, git-mv stopped on failing renames even with -k. There are some error conditions which are not checked in the first phase of git-mv, eg. 'permission denied'. Still, option -k should work. Signed-off-by: Josef Weidendorfer Signed-off-by: Junio C Hamano --- git-mv.perl | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index 8d294d6529..65b1dcfdf2 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -151,6 +151,11 @@ while(scalar @srcs > 0) { if (!$opt_n) { if (!rename($src,$dst)) { $bad = "renaming '$src' failed: $!"; + if ($opt_k) { + print "Warning: skipped: $bad\n"; + $bad = ""; + next; + } last; } } -- cgit v1.2.3 From 90109b320d45520cf5721de08d761ad06c0445ab Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 28 Nov 2005 02:54:05 -0800 Subject: git-mv: quote $src in regexp properly. Noticed and fixed by Matthias Urlichs and Josef Weidendorfer. Signed-off-by: Junio C Hamano --- git-mv.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index 65b1dcfdf2..53046bafd6 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -108,7 +108,7 @@ while(scalar @srcArgs > 0) { } } - if (($bad eq "") && ($dst =~ /^$src\//)) { + if (($bad eq "") && ($dst =~ /^$safesrc\//)) { $bad = "can not move directory '$src' into itself"; } -- cgit v1.2.3 From 4518bb88392fcd44bacae640754e7326a8fdf477 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 25 Nov 2005 18:45:52 -0800 Subject: [PATCH] Make git-mv work in subdirectories, too Turns out, all git programs git-mv uses are capable of operating in a subdirectory just fine. So don't complain about it. [jc: I think that sounds sane. You need to grab the exit status from `git-rev-parse --git-dir`, which I added. Alex Riesen says this worked fine.] Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- git-mv.perl | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'git-mv.perl') diff --git a/git-mv.perl b/git-mv.perl index 53046bafd6..b6c0b48818 100755 --- a/git-mv.perl +++ b/git-mv.perl @@ -19,15 +19,9 @@ EOT exit(1); } -# Sanity checks: -my $GIT_DIR = $ENV{'GIT_DIR'} || ".git"; - -unless ( -d $GIT_DIR && -d $GIT_DIR . "/objects" && - -d $GIT_DIR . "/objects/" && -d $GIT_DIR . "/refs") { - print "Error: git repository not found."; - exit(1); -} - +my $GIT_DIR = `git rev-parse --git-dir`; +exit 1 if $?; # rev-parse would have given "not a git dir" message. +chomp($GIT_DIR); our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v); getopts("hnfkv") || usage; -- cgit v1.2.3