2 * "git rm" builtin command
4 * Copyright (C) Linus Torvalds 2006
9 #include "cache-tree.h"
11 static const char builtin_rm_usage
[] =
12 "git-rm [-n] [-v] [-f] <filepattern>...";
19 static void add_list(const char *name
)
21 if (list
.nr
>= list
.alloc
) {
22 list
.alloc
= alloc_nr(list
.alloc
);
23 list
.name
= xrealloc(list
.name
, list
.alloc
* sizeof(const char *));
25 list
.name
[list
.nr
++] = name
;
28 static int remove_file(const char *name
)
34 if (!ret
&& (slash
= strrchr(name
, '/'))) {
35 char *n
= strdup(name
);
39 } while (!rmdir(name
) && (slash
= strrchr(name
, '/')));
44 static struct lock_file lock_file
;
46 int cmd_rm(int argc
, const char **argv
, char **envp
)
49 int verbose
= 0, show_only
= 0, force
= 0;
50 const char *prefix
= setup_git_directory();
51 const char **pathspec
;
54 git_config(git_default_config
);
56 newfd
= hold_lock_file_for_update(&lock_file
, get_index_file());
58 die("unable to create new index file");
61 die("index file corrupt");
63 for (i
= 1 ; i
< argc
; i
++) {
64 const char *arg
= argv
[i
];
68 if (!strcmp(arg
, "--")) {
72 if (!strcmp(arg
, "-n")) {
76 if (!strcmp(arg
, "-v")) {
80 if (!strcmp(arg
, "-f")) {
84 die(builtin_rm_usage
);
87 usage(builtin_rm_usage
);
89 pathspec
= get_pathspec(prefix
, argv
+ i
);
91 for (i
= 0; pathspec
[i
] ; i
++)
96 for (i
= 0; i
< active_nr
; i
++) {
97 struct cache_entry
*ce
= active_cache
[i
];
98 if (!match_pathspec(pathspec
, ce
->name
, ce_namelen(ce
), 0, seen
))
105 for (i
= 0; (match
= pathspec
[i
]) != NULL
; i
++) {
106 if (*match
&& !seen
[i
])
107 die("pathspec '%s' did not match any files", match
);
112 * First remove the names from the index: we won't commit
113 * the index unless all of them succeed
115 for (i
= 0; i
< list
.nr
; i
++) {
116 const char *path
= list
.name
[i
];
117 printf("rm '%s'\n", path
);
119 if (remove_file_from_cache(path
))
120 die("git rm: unable to remove %s", path
);
121 cache_tree_invalidate_path(active_cache_tree
, path
);
128 * Then, if we used "-f", remove the filenames from the
129 * workspace. If we fail to remove the first one, we
130 * abort the "git rm" (but once we've successfully removed
131 * any file at all, we'll go ahead and commit to it all:
132 * by then we've already committed ourselves and can't fail
137 for (i
= 0; i
< list
.nr
; i
++) {
138 const char *path
= list
.name
[i
];
139 if (!remove_file(path
)) {
144 die("git rm: %s: %s", path
, strerror(errno
));
148 if (active_cache_changed
) {
149 if (write_cache(newfd
, active_cache
, active_nr
) ||
150 close(newfd
) || commit_lock_file(&lock_file
))
151 die("Unable to write new index file");