🌐 AI搜索 & 代理 主页
blob: 83dc7e45cf205c7575512182bf29516914773209 [file] [log] [blame]
Josef Weidendorfer1114b262005-10-23 16:15:341#!/usr/bin/perl
2#
3# Copyright 2005, Ryan Anderson <ryan@michonline.com>
4# Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
5#
6# This file is licensed under the GPL v2, or a later version
7# at the discretion of Linus Torvalds.
8
9
10use warnings;
11use strict;
12use Getopt::Std;
13
14sub usage() {
15 print <<EOT;
Josef Weidendorfer3ae64df2005-11-27 20:58:5216$0 [-f] [-n] <source> <destination>
17$0 [-f] [-n] [-k] <source> ... <destination directory>
Josef Weidendorfer1114b262005-10-23 16:15:3418EOT
19 exit(1);
20}
21
Johannes Schindelin4518bb82005-11-26 02:45:5222my $GIT_DIR = `git rev-parse --git-dir`;
23exit 1 if $?; # rev-parse would have given "not a git dir" message.
24chomp($GIT_DIR);
Josef Weidendorfer1114b262005-10-23 16:15:3425
26our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v);
27getopts("hnfkv") || usage;
28usage() if $opt_h;
29@ARGV >= 1 or usage;
30
31my (@srcArgs, @dstArgs, @srcs, @dsts);
32my ($src, $dst, $base, $dstDir);
33
34my $argCount = scalar @ARGV;
35if (-d $ARGV[$argCount-1]) {
36 $dstDir = $ARGV[$argCount-1];
Josef Weidendorferf676fa72005-11-01 22:46:2737 # remove any trailing slash
38 $dstDir =~ s/\/$//;
Josef Weidendorfer1114b262005-10-23 16:15:3439 @srcArgs = @ARGV[0..$argCount-2];
40
41 foreach $src (@srcArgs) {
42 $base = $src;
43 $base =~ s/^.*\///;
44 $dst = "$dstDir/". $base;
45 push @dstArgs, $dst;
46 }
47}
48else {
49 if ($argCount != 2) {
50 print "Error: moving to directory '"
51 . $ARGV[$argCount-1]
52 . "' not possible; not exisiting\n";
Josef Weidendorfer3ae64df2005-11-27 20:58:5253 exit(1);
Josef Weidendorfer1114b262005-10-23 16:15:3454 }
55 @srcArgs = ($ARGV[0]);
56 @dstArgs = ($ARGV[1]);
57 $dstDir = "";
58}
59
60my (@allfiles,@srcfiles,@dstfiles);
61my $safesrc;
Josef Weidendorfer05ff5642005-10-25 12:20:4562my (%overwritten, %srcForDst);
Josef Weidendorfer1114b262005-10-23 16:15:3463
64$/ = "\0";
Junio C Hamano23c99d82005-12-06 02:14:3465open(F, 'git-ls-files -z |')
Josef Weidendorfer1114b262005-10-23 16:15:3466 or die "Failed to open pipe from git-ls-files: " . $!;
67
68@allfiles = map { chomp; $_; } <F>;
69close(F);
70
71
72my ($i, $bad);
73while(scalar @srcArgs > 0) {
74 $src = shift @srcArgs;
75 $dst = shift @dstArgs;
76 $bad = "";
77
78 if ($opt_v) {
79 print "Checking rename of '$src' to '$dst'\n";
80 }
81
82 unless (-f $src || -l $src || -d $src) {
83 $bad = "bad source '$src'";
84 }
85
Josef Weidendorfer073dab12005-11-23 11:04:2386 $safesrc = quotemeta($src);
87 @srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
88
Josef Weidendorfer1114b262005-10-23 16:15:3489 $overwritten{$dst} = 0;
90 if (($bad eq "") && -e $dst) {
91 $bad = "destination '$dst' already exists";
Josef Weidendorfer073dab12005-11-23 11:04:2392 if ($opt_f) {
93 # only files can overwrite each other: check both source and destination
94 if (-f $dst && (scalar @srcfiles == 1)) {
95 print "Warning: $bad; will overwrite!\n";
96 $bad = "";
97 $overwritten{$dst} = 1;
98 }
99 else {
100 $bad = "Can not overwrite '$src' with '$dst'";
101 }
Josef Weidendorfer1114b262005-10-23 16:15:34102 }
103 }
104
Junio C Hamano90109b32005-11-28 10:54:05105 if (($bad eq "") && ($dst =~ /^$safesrc\//)) {
Josef Weidendorfer1114b262005-10-23 16:15:34106 $bad = "can not move directory '$src' into itself";
107 }
108
109 if ($bad eq "") {
Josef Weidendorfer1114b262005-10-23 16:15:34110 if (scalar @srcfiles == 0) {
111 $bad = "'$src' not under version control";
112 }
113 }
114
Josef Weidendorfer05ff5642005-10-25 12:20:45115 if ($bad eq "") {
116 if (defined $srcForDst{$dst}) {
117 $bad = "can not move '$src' to '$dst'; already target of ";
118 $bad .= "'".$srcForDst{$dst}."'";
119 }
120 else {
121 $srcForDst{$dst} = $src;
122 }
123 }
124
Josef Weidendorfer1114b262005-10-23 16:15:34125 if ($bad ne "") {
126 if ($opt_k) {
127 print "Warning: $bad; skipping\n";
128 next;
129 }
130 print "Error: $bad\n";
Josef Weidendorfer3ae64df2005-11-27 20:58:52131 exit(1);
Josef Weidendorfer1114b262005-10-23 16:15:34132 }
133 push @srcs, $src;
134 push @dsts, $dst;
135}
136
137# Final pass: rename/move
138my (@deletedfiles,@addedfiles,@changedfiles);
Josef Weidendorferf6bc1892005-11-27 21:04:14139$bad = "";
Josef Weidendorfer1114b262005-10-23 16:15:34140while(scalar @srcs > 0) {
141 $src = shift @srcs;
142 $dst = shift @dsts;
143
144 if ($opt_n || $opt_v) { print "Renaming $src to $dst\n"; }
145 if (!$opt_n) {
Josef Weidendorferf6bc1892005-11-27 21:04:14146 if (!rename($src,$dst)) {
147 $bad = "renaming '$src' failed: $!";
Josef Weidendorfer26169742005-11-27 21:11:33148 if ($opt_k) {
149 print "Warning: skipped: $bad\n";
150 $bad = "";
151 next;
152 }
Josef Weidendorferf6bc1892005-11-27 21:04:14153 last;
154 }
Josef Weidendorfer1114b262005-10-23 16:15:34155 }
156
157 $safesrc = quotemeta($src);
158 @srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
159 @dstfiles = @srcfiles;
160 s/^$safesrc(\/|$)/$dst$1/ for @dstfiles;
161
162 push @deletedfiles, @srcfiles;
163 if (scalar @srcfiles == 1) {
Josef Weidendorfer073dab12005-11-23 11:04:23164 # $dst can be a directory with 1 file inside
Josef Weidendorfer1114b262005-10-23 16:15:34165 if ($overwritten{$dst} ==1) {
Josef Weidendorfer073dab12005-11-23 11:04:23166 push @changedfiles, $dstfiles[0];
167
Josef Weidendorfer1114b262005-10-23 16:15:34168 } else {
Josef Weidendorfer073dab12005-11-23 11:04:23169 push @addedfiles, $dstfiles[0];
Josef Weidendorfer1114b262005-10-23 16:15:34170 }
171 }
172 else {
173 push @addedfiles, @dstfiles;
174 }
175}
176
177if ($opt_n) {
Josef Weidendorfer3ae64df2005-11-27 20:58:52178 if (@changedfiles) {
Josef Weidendorfer1114b262005-10-23 16:15:34179 print "Changed : ". join(", ", @changedfiles) ."\n";
Josef Weidendorfer3ae64df2005-11-27 20:58:52180 }
181 if (@addedfiles) {
Josef Weidendorfer1114b262005-10-23 16:15:34182 print "Adding : ". join(", ", @addedfiles) ."\n";
Josef Weidendorfer3ae64df2005-11-27 20:58:52183 }
184 if (@deletedfiles) {
Josef Weidendorfer1114b262005-10-23 16:15:34185 print "Deleting : ". join(", ", @deletedfiles) ."\n";
Josef Weidendorfer3ae64df2005-11-27 20:58:52186 }
Josef Weidendorfer1114b262005-10-23 16:15:34187}
Josef Weidendorfer3ae64df2005-11-27 20:58:52188else {
189 if (@changedfiles) {
Alexander Litvinovf359ae42005-11-23 10:19:41190 open(H, "| git-update-index -z --stdin")
191 or die "git-update-index failed to update changed files with code $!\n";
192 foreach my $fileName (@changedfiles) {
193 print H "$fileName\0";
194 }
195 close(H);
Josef Weidendorfer3ae64df2005-11-27 20:58:52196 }
197 if (@addedfiles) {
Alexander Litvinovf359ae42005-11-23 10:19:41198 open(H, "| git-update-index --add -z --stdin")
199 or die "git-update-index failed to add new names with code $!\n";
200 foreach my $fileName (@addedfiles) {
201 print H "$fileName\0";
202 }
203 close(H);
Josef Weidendorfer3ae64df2005-11-27 20:58:52204 }
205 if (@deletedfiles) {
Alexander Litvinovf359ae42005-11-23 10:19:41206 open(H, "| git-update-index --remove -z --stdin")
207 or die "git-update-index failed to remove old names with code $!\n";
208 foreach my $fileName (@deletedfiles) {
209 print H "$fileName\0";
210 }
211 close(H);
Josef Weidendorfer3ae64df2005-11-27 20:58:52212 }
Alexander Litvinovf359ae42005-11-23 10:19:41213}
Josef Weidendorferf6bc1892005-11-27 21:04:14214
215if ($bad ne "") {
216 print "Error: $bad\n";
217 exit(1);
218}