@@ -61,6 +61,46 @@ static const char *add_slash(const char *path)
6161static struct lock_file lock_file ;
6262#define SUBMODULE_WITH_GITDIR ((const char *)1)
6363
64+ static void prepare_move_submodule (const char * src , int first ,
65+ const char * * submodule_gitfile )
66+ {
67+ struct strbuf submodule_dotgit = STRBUF_INIT ;
68+ if (!S_ISGITLINK (active_cache [first ]-> ce_mode ))
69+ die (_ ("Directory %s is in index and no submodule?" ), src );
70+ if (!is_staging_gitmodules_ok ())
71+ die (_ ("Please stage your changes to .gitmodules or stash them to proceed" ));
72+ strbuf_addf (& submodule_dotgit , "%s/.git" , src );
73+ * submodule_gitfile = read_gitfile (submodule_dotgit .buf );
74+ if (* submodule_gitfile )
75+ * submodule_gitfile = xstrdup (* submodule_gitfile );
76+ else
77+ * submodule_gitfile = SUBMODULE_WITH_GITDIR ;
78+ strbuf_release (& submodule_dotgit );
79+ }
80+
81+ static int index_range_of_same_dir (const char * src , int length ,
82+ int * first_p , int * last_p )
83+ {
84+ const char * src_w_slash = add_slash (src );
85+ int first , last , len_w_slash = length + 1 ;
86+
87+ first = cache_name_pos (src_w_slash , len_w_slash );
88+ if (first >= 0 )
89+ die (_ ("%.*s is in index" ), len_w_slash , src_w_slash );
90+
91+ first = -1 - first ;
92+ for (last = first ; last < active_nr ; last ++ ) {
93+ const char * path = active_cache [last ]-> name ;
94+ if (strncmp (path , src_w_slash , len_w_slash ))
95+ break ;
96+ }
97+ if (src_w_slash != src )
98+ free ((char * )src_w_slash );
99+ * first_p = first ;
100+ * last_p = last ;
101+ return last - first ;
102+ }
103+
64104int cmd_mv (int argc , const char * * argv , const char * prefix )
65105{
66106 int i , gitmodules_modified = 0 ;
@@ -108,7 +148,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
108148 destination = internal_copy_pathspec (dest_path [0 ], argv , argc , DUP_BASENAME );
109149 } else {
110150 if (argc != 1 )
111- die ("destination '%s' is not a directory" , dest_path [0 ]);
151+ die (_ ( "destination '%s' is not a directory" ) , dest_path [0 ]);
112152 destination = dest_path ;
113153 }
114154
@@ -131,75 +171,36 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
131171 && lstat (dst , & st ) == 0 )
132172 bad = _ ("cannot move directory over file" );
133173 else if (src_is_dir ) {
134- int first = cache_name_pos (src , length );
135- if (first >= 0 ) {
136- struct strbuf submodule_dotgit = STRBUF_INIT ;
137- if (!S_ISGITLINK (active_cache [first ]-> ce_mode ))
138- die (_ ("Huh? Directory %s is in index and no submodule?" ), src );
139- if (!is_staging_gitmodules_ok ())
140- die (_ ("Please, stage your changes to .gitmodules or stash them to proceed" ));
141- strbuf_addf (& submodule_dotgit , "%s/.git" , src );
142- submodule_gitfile [i ] = read_gitfile (submodule_dotgit .buf );
143- if (submodule_gitfile [i ])
144- submodule_gitfile [i ] = xstrdup (submodule_gitfile [i ]);
145- else
146- submodule_gitfile [i ] = SUBMODULE_WITH_GITDIR ;
147- strbuf_release (& submodule_dotgit );
148- } else {
149- const char * src_w_slash = add_slash (src );
150- int last , len_w_slash = length + 1 ;
174+ int first = cache_name_pos (src , length ), last ;
151175
152- modes [i ] = WORKING_DIRECTORY ;
176+ if (first >= 0 )
177+ prepare_move_submodule (src , first ,
178+ submodule_gitfile + i );
179+ else if (index_range_of_same_dir (src , length ,
180+ & first , & last ) < 1 )
181+ bad = _ ("source directory is empty" );
182+ else { /* last - first >= 1 */
183+ int j , dst_len , n ;
153184
154- first = cache_name_pos (src_w_slash , len_w_slash );
155- if (first >= 0 )
156- die (_ ("Huh? %.*s is in index?" ),
157- len_w_slash , src_w_slash );
158-
159- first = -1 - first ;
160- for (last = first ; last < active_nr ; last ++ ) {
161- const char * path = active_cache [last ]-> name ;
162- if (strncmp (path , src_w_slash , len_w_slash ))
163- break ;
164- }
165- if (src_w_slash != src )
166- free ((char * )src_w_slash );
167-
168- if (last - first < 1 )
169- bad = _ ("source directory is empty" );
170- else {
171- int j , dst_len ;
172-
173- if (last - first > 0 ) {
174- source = xrealloc (source ,
175- (argc + last - first )
176- * sizeof (char * ));
177- destination = xrealloc (destination ,
178- (argc + last - first )
179- * sizeof (char * ));
180- modes = xrealloc (modes ,
181- (argc + last - first )
182- * sizeof (enum update_mode ));
183- submodule_gitfile = xrealloc (submodule_gitfile ,
184- (argc + last - first )
185- * sizeof (char * ));
186- }
185+ modes [i ] = WORKING_DIRECTORY ;
186+ n = argc + last - first ;
187+ source = xrealloc (source , n * sizeof (char * ));
188+ destination = xrealloc (destination , n * sizeof (char * ));
189+ modes = xrealloc (modes , n * sizeof (enum update_mode ));
190+ submodule_gitfile = xrealloc (submodule_gitfile , n * sizeof (char * ));
187191
188- dst = add_slash (dst );
189- dst_len = strlen (dst );
192+ dst = add_slash (dst );
193+ dst_len = strlen (dst );
190194
191- for (j = 0 ; j < last - first ; j ++ ) {
192- const char * path =
193- active_cache [first + j ]-> name ;
194- source [argc + j ] = path ;
195- destination [argc + j ] =
196- prefix_path (dst , dst_len ,
197- path + length + 1 );
198- modes [argc + j ] = INDEX ;
199- submodule_gitfile [argc + j ] = NULL ;
200- }
201- argc += last - first ;
195+ for (j = 0 ; j < last - first ; j ++ ) {
196+ const char * path = active_cache [first + j ]-> name ;
197+ source [argc + j ] = path ;
198+ destination [argc + j ] =
199+ prefix_path (dst , dst_len , path + length + 1 );
200+ modes [argc + j ] = INDEX ;
201+ submodule_gitfile [argc + j ] = NULL ;
202202 }
203+ argc += last - first ;
203204 }
204205 } else if (cache_name_pos (src , length ) < 0 )
205206 bad = _ ("not under version control" );
@@ -225,24 +226,22 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
225226 else
226227 string_list_insert (& src_for_dst , dst );
227228
228- if (bad ) {
229- if (ignore_errors ) {
230- if (-- argc > 0 ) {
231- memmove (source + i , source + i + 1 ,
232- (argc - i ) * sizeof (char * ));
233- memmove (destination + i ,
234- destination + i + 1 ,
235- (argc - i ) * sizeof (char * ));
236- memmove (modes + i , modes + i + 1 ,
237- (argc - i ) * sizeof (enum update_mode ));
238- memmove (submodule_gitfile + i ,
239- submodule_gitfile + i + 1 ,
240- (argc - i ) * sizeof (char * ));
241- i -- ;
242- }
243- } else
244- die (_ ("%s, source=%s, destination=%s" ),
245- bad , src , dst );
229+ if (!bad )
230+ continue ;
231+ if (!ignore_errors )
232+ die (_ ("%s, source=%s, destination=%s" ),
233+ bad , src , dst );
234+ if (-- argc > 0 ) {
235+ int n = argc - i ;
236+ memmove (source + i , source + i + 1 ,
237+ n * sizeof (char * ));
238+ memmove (destination + i , destination + i + 1 ,
239+ n * sizeof (char * ));
240+ memmove (modes + i , modes + i + 1 ,
241+ n * sizeof (enum update_mode ));
242+ memmove (submodule_gitfile + i , submodule_gitfile + i + 1 ,
243+ n * sizeof (char * ));
244+ i -- ;
246245 }
247246 }
248247
@@ -254,7 +253,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
254253 printf (_ ("Renaming %s to %s\n" ), src , dst );
255254 if (!show_only && mode != INDEX ) {
256255 if (rename (src , dst ) < 0 && !ignore_errors )
257- die_errno (_ ("renaming '%s' failed" ), src );
256+ die_errno (_ ("renaming '%s' failed" ), src );
258257 if (submodule_gitfile [i ]) {
259258 if (submodule_gitfile [i ] != SUBMODULE_WITH_GITDIR )
260259 connect_work_tree_and_git_dir (dst , submodule_gitfile [i ]);
@@ -275,10 +274,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
275274 if (gitmodules_modified )
276275 stage_updated_gitmodules ();
277276
278- if (active_cache_changed ) {
279- if (write_locked_index (& the_index , & lock_file , COMMIT_LOCK ))
280- die (_ ("Unable to write new index file" ));
281- }
277+ if (active_cache_changed &&
278+ write_locked_index (& the_index , & lock_file , COMMIT_LOCK ))
279+ die (_ ("Unable to write new index file" ));
282280
283281 return 0 ;
284282}
0 commit comments