static int add_file_to_cache(char *path)
{
- int size, namelen, option;
+ int size, namelen, option, status;
struct cache_entry *ce;
struct stat st;
int fd;
char *target;
- if (lstat(path, &st) < 0) {
- if (errno == ENOENT || errno == ENOTDIR) {
+ status = lstat(path, &st);
+ if (status < 0 || S_ISDIR(st.st_mode)) {
+ /* When we used to have "path" and now we want to add
+ * "path/file", we need a way to remove "path" before
+ * being able to add "path/file". However,
+ * "git-update-cache --remove path" would not work.
+ * --force-remove can be used but this is more user
+ * friendly, especially since we can do the opposite
+ * case just fine without --force-remove.
+ */
+ if (status == 0 || (errno == ENOENT || errno == ENOTDIR)) {
if (allow_remove)
return remove_file_from_cache(path);
}
- return -1;
+ return error("open(\"%s\"): %s", path, strerror(errno));
}
namelen = strlen(path);
size = cache_entry_size(namelen);
if (fd >= 0) {
void *buffer;
unsigned long size;
- char type[10];
+ char type[20];
buffer = read_sha1_file(ce->sha1, type, &size);
if (buffer) {
if (lstat(ce->name, &st) < 0)
return ERR_PTR(-errno);
- changed = cache_match_stat(ce, &st);
+ changed = ce_match_stat(ce, &st);
if (!changed)
return ce;
continue;
}
active_cache_changed = 1;
+ /* You can NOT just free active_cache[i] here, since it
+ * might not be necessarily malloc()ed but can also come
+ * from mmap(). */
active_cache[i] = new;
}
return has_errors;
continue;
}
if (!strcmp(path, "--cacheinfo")) {
- if (i+3 >= argc || add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
+ if (i+3 >= argc)
die("update-cache: --cacheinfo <mode> <sha1> <path>");
+ if (add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
+ die("update-cache: --cacheinfo cannot add %s", argv[i+3]);
i += 3;
continue;
}