diff options
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/read-cache.c b/read-cache.c index c14b562313..940ec76fdf 100644 --- a/read-cache.c +++ b/read-cache.c @@ -99,27 +99,21 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st) static int ce_compare_link(struct cache_entry *ce, size_t expected_size) { int match = -1; - char *target; void *buffer; unsigned long size; enum object_type type; - int len; + struct strbuf sb = STRBUF_INIT; - target = xmalloc(expected_size); - len = readlink(ce->name, target, expected_size); - if (len != expected_size) { - free(target); + if (strbuf_readlink(&sb, ce->name, expected_size)) return -1; - } + buffer = read_sha1_file(ce->sha1, &type, &size); - if (!buffer) { - free(target); - return -1; + if (buffer) { + if (size == sb.len) + match = memcmp(buffer, sb.buf, size); + free(buffer); } - if (size == expected_size) - match = memcmp(buffer, target, size); - free(buffer); - free(target); + strbuf_release(&sb); return match; } @@ -1580,6 +1574,26 @@ static void update_callback(struct diff_queue_struct *q, default: die("unexpected diff status %c", p->status); case DIFF_STATUS_UNMERGED: + /* + * ADD_CACHE_IGNORE_REMOVAL is unset if "git + * add -u" is calling us, In such a case, a + * missing work tree file needs to be removed + * if there is an unmerged entry at stage #2, + * but such a diff record is followed by + * another with DIFF_STATUS_DELETED (and if + * there is no stage #2, we won't see DELETED + * nor MODIFIED). We can simply continue + * either way. + */ + if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL)) + continue; + /* + * Otherwise, it is "git add path" is asking + * to explicitly add it; we fall through. A + * missing work tree file is an error and is + * caught by add_file_to_index() in such a + * case. + */ case DIFF_STATUS_MODIFIED: case DIFF_STATUS_TYPE_CHANGED: if (add_file_to_index(&the_index, path, data->flags)) { |