Merge branch 'jl/submodule-mv'
"git mv A B" when moving a submodule A does "the right thing", inclusing relocating its working tree and adjusting the paths in the .gitmodules file. * jl/submodule-mv: (53 commits) rm: delete .gitmodules entry of submodules removed from the work tree mv: update the path entry in .gitmodules for moved submodules submodule.c: add .gitmodules staging helper functions mv: move submodules using a gitfile mv: move submodules together with their work trees rm: do not set a variable twice without intermediate reading. t6131 - skip tests if on case-insensitive file system parse_pathspec: accept :(icase)path syntax pathspec: support :(glob) syntax pathspec: make --literal-pathspecs disable pathspec magic pathspec: support :(literal) syntax for noglob pathspec kill limit_pathspec_to_literal() as it's only used by parse_pathspec() parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN parse_pathspec: make sure the prefix part is wildcard-free rename field "raw" to "_raw" in struct pathspec tree-diff: remove the use of pathspec's raw[] in follow-rename codepath remove match_pathspec() in favor of match_pathspec_depth() remove init_pathspec() in favor of parse_pathspec() remove diff_tree_{setup,release}_paths convert common_prefix() to use struct pathspec ...
This commit is contained in:
68
builtin/rm.c
68
builtin/rm.c
@ -11,6 +11,7 @@
|
||||
#include "parse-options.h"
|
||||
#include "string-list.h"
|
||||
#include "submodule.h"
|
||||
#include "pathspec.h"
|
||||
|
||||
static const char * const builtin_rm_usage[] = {
|
||||
N_("git rm [options] [--] <file>..."),
|
||||
@ -277,10 +278,11 @@ static struct option builtin_rm_options[] = {
|
||||
|
||||
int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i, newfd, seen_any;
|
||||
const char **pathspec, *match;
|
||||
int i, newfd;
|
||||
struct pathspec pathspec;
|
||||
char *seen;
|
||||
|
||||
gitmodules_config();
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
argc = parse_options(argc, argv, prefix, builtin_rm_options,
|
||||
@ -311,40 +313,45 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
}
|
||||
|
||||
pathspec = get_pathspec(prefix, argv);
|
||||
refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
|
||||
parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD, prefix, argv);
|
||||
refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);
|
||||
|
||||
for (i = 0; pathspec[i] ; i++)
|
||||
/* nothing */;
|
||||
seen = xcalloc(i, 1);
|
||||
seen = xcalloc(pathspec.nr, 1);
|
||||
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
const struct cache_entry *ce = active_cache[i];
|
||||
if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
|
||||
if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))
|
||||
continue;
|
||||
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
|
||||
list.entry[list.nr].name = ce->name;
|
||||
list.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode);
|
||||
list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
|
||||
if (list.entry[list.nr++].is_submodule &&
|
||||
!is_staging_gitmodules_ok())
|
||||
die (_("Please, stage your changes to .gitmodules or stash them to proceed"));
|
||||
}
|
||||
|
||||
|
||||
seen_any = 0;
|
||||
for (i = 0; (match = pathspec[i]) != NULL ; i++) {
|
||||
if (!seen[i]) {
|
||||
if (!ignore_unmatch) {
|
||||
die(_("pathspec '%s' did not match any files"),
|
||||
match);
|
||||
if (pathspec.nr) {
|
||||
const char *original;
|
||||
int seen_any = 0;
|
||||
for (i = 0; i < pathspec.nr; i++) {
|
||||
original = pathspec.items[i].original;
|
||||
if (!seen[i]) {
|
||||
if (!ignore_unmatch) {
|
||||
die(_("pathspec '%s' did not match any files"),
|
||||
original);
|
||||
}
|
||||
}
|
||||
else {
|
||||
seen_any = 1;
|
||||
}
|
||||
if (!recursive && seen[i] == MATCHED_RECURSIVELY)
|
||||
die(_("not removing '%s' recursively without -r"),
|
||||
*original ? original : ".");
|
||||
}
|
||||
else {
|
||||
seen_any = 1;
|
||||
}
|
||||
if (!recursive && seen[i] == MATCHED_RECURSIVELY)
|
||||
die(_("not removing '%s' recursively without -r"),
|
||||
*match ? match : ".");
|
||||
|
||||
if (!seen_any)
|
||||
exit(0);
|
||||
}
|
||||
if (!seen_any)
|
||||
exit(0);
|
||||
|
||||
/*
|
||||
* If not forced, the file, the index and the HEAD (if exists)
|
||||
@ -392,13 +399,15 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||
* in the middle)
|
||||
*/
|
||||
if (!index_only) {
|
||||
int removed = 0;
|
||||
int removed = 0, gitmodules_modified = 0;
|
||||
for (i = 0; i < list.nr; i++) {
|
||||
const char *path = list.entry[i].name;
|
||||
if (list.entry[i].is_submodule) {
|
||||
if (is_empty_dir(path)) {
|
||||
if (!rmdir(path)) {
|
||||
removed = 1;
|
||||
if (!remove_path_from_gitmodules(path))
|
||||
gitmodules_modified = 1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@ -406,9 +415,14 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||
strbuf_addstr(&buf, path);
|
||||
if (!remove_dir_recursively(&buf, 0)) {
|
||||
removed = 1;
|
||||
if (!remove_path_from_gitmodules(path))
|
||||
gitmodules_modified = 1;
|
||||
strbuf_release(&buf);
|
||||
continue;
|
||||
}
|
||||
} else if (!file_exists(path))
|
||||
/* Submodule was removed by user */
|
||||
if (!remove_path_from_gitmodules(path))
|
||||
gitmodules_modified = 1;
|
||||
strbuf_release(&buf);
|
||||
/* Fallthrough and let remove_path() fail. */
|
||||
}
|
||||
@ -420,6 +434,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
||||
if (!removed)
|
||||
die_errno("git rm: '%s'", path);
|
||||
}
|
||||
if (gitmodules_modified)
|
||||
stage_updated_gitmodules();
|
||||
}
|
||||
|
||||
if (active_cache_changed) {
|
||||
|
Reference in New Issue
Block a user