static int locate_in_src_index(const struct cache_entry *ce, struct unpack_trees_options *o) { struct index_state *index = o->src_index; int len = ce_namelen(ce); int pos = index_name_pos(index, ce->name, len); if (pos < 0) pos = -1 - pos; return pos; }
static void fsmonitor_refresh_callback(struct index_state *istate, const char *name) { int pos = index_name_pos(istate, name, strlen(name)); if (pos >= 0) { struct cache_entry *ce = istate->cache[pos]; ce->ce_flags &= ~CE_FSMONITOR_VALID; } /* * Mark the untracked cache dirty even if it wasn't found in the index * as it could be a new untracked file. */ trace_printf_key(&trace_fsmonitor, "fsmonitor_refresh_callback '%s'", name); untracked_cache_invalidate_path(istate, name, 0); }
static void add_same_unmerged(const struct cache_entry *ce, struct unpack_trees_options *o) { struct index_state *index = o->src_index; int len = ce_namelen(ce); int pos = index_name_pos(index, ce->name, len); if (0 <= pos) die("programming error in a caller of mark_ce_used_same_name"); for (pos = -pos - 1; pos < index->cache_nr; pos++) { struct cache_entry *next = index->cache[pos]; if (len != ce_namelen(next) || memcmp(ce->name, next->name, len)) break; add_entry(o, next, 0, 0); mark_ce_used(next, o); } }
static void *read_skip_worktree_file_from_index(const char *path, size_t *size) { int pos, len; unsigned long sz; enum object_type type; void *data; struct index_state *istate = &the_index; len = strlen(path); pos = index_name_pos(istate, path, len); if (pos < 0) return NULL; if (!ce_skip_worktree(istate->cache[pos])) return NULL; data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz); if (!data || type != OBJ_BLOB) { free(data); return NULL; } *size = xsize_t(sz); return data; }
static int would_lose_untracked(struct index_state *index, const char *path, const char *real_path) { int pos = index_name_pos(index, path, strlen(path)); if (pos < 0) pos = -1 - pos; while (pos < index->cache_nr && !strcmp(path, index->cache[pos]->name)) { /* * If stage #0, it is definitely tracked. * If it has stage #2 then it was tracked * before this merge started. All other * cases the path was not tracked. */ switch (ce_stage(index->cache[pos])) { case 0: case 2: return 0; } pos++; } return file_exists(real_path); }
static void verify_one(struct repository *r, struct index_state *istate, struct cache_tree *it, struct strbuf *path) { int i, pos, len = path->len; struct strbuf tree_buf = STRBUF_INIT; struct object_id new_oid; for (i = 0; i < it->subtree_nr; i++) { strbuf_addf(path, "%s/", it->down[i]->name); verify_one(r, istate, it->down[i]->cache_tree, path); strbuf_setlen(path, len); } if (it->entry_count < 0 || /* no verification on tests (t7003) that replace trees */ lookup_replace_object(r, &it->oid) != &it->oid) return; if (path->len) { pos = index_name_pos(istate, path->buf, path->len); pos = -pos - 1; } else { pos = 0; } i = 0; while (i < it->entry_count) { struct cache_entry *ce = istate->cache[pos + i]; const char *slash; struct cache_tree_sub *sub = NULL; const struct object_id *oid; const char *name; unsigned mode; int entlen; if (ce->ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE)) BUG("%s with flags 0x%x should not be in cache-tree", ce->name, ce->ce_flags); name = ce->name + path->len; slash = strchr(name, '/'); if (slash) { entlen = slash - name; sub = find_subtree(it, ce->name + path->len, entlen, 0); if (!sub || sub->cache_tree->entry_count < 0) BUG("bad subtree '%.*s'", entlen, name); oid = &sub->cache_tree->oid; mode = S_IFDIR; i += sub->cache_tree->entry_count; } else { oid = &ce->oid; mode = ce->ce_mode; entlen = ce_namelen(ce) - path->len; i++; } strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0'); strbuf_add(&tree_buf, oid->hash, the_hash_algo->rawsz); } hash_object_file(tree_buf.buf, tree_buf.len, tree_type, &new_oid); if (!oideq(&new_oid, &it->oid)) BUG("cache-tree for path %.*s does not match. " "Expected %s got %s", len, path->buf, oid_to_hex(&new_oid), oid_to_hex(&it->oid)); strbuf_setlen(path, len); strbuf_release(&tree_buf); }
static int handle_cache(struct index_state *istate, const char *path, unsigned char *hash, const char *output) { mmfile_t mmfile[3] = {{NULL}}; mmbuffer_t result = {NULL, 0}; const struct cache_entry *ce; int pos, len, i, has_conflicts; struct rerere_io_mem io; int marker_size = ll_merge_marker_size(istate, path); /* * Reproduce the conflicted merge in-core */ len = strlen(path); pos = index_name_pos(istate, path, len); if (0 <= pos) return -1; pos = -pos - 1; while (pos < istate->cache_nr) { enum object_type type; unsigned long size; ce = istate->cache[pos++]; if (ce_namelen(ce) != len || memcmp(ce->name, path, len)) break; i = ce_stage(ce) - 1; if (!mmfile[i].ptr) { mmfile[i].ptr = read_object_file(&ce->oid, &type, &size); mmfile[i].size = size; } } for (i = 0; i < 3; i++) if (!mmfile[i].ptr && !mmfile[i].size) mmfile[i].ptr = xstrdup(""); /* * NEEDSWORK: handle conflicts from merges with * merge.renormalize set, too? */ ll_merge(&result, path, &mmfile[0], NULL, &mmfile[1], "ours", &mmfile[2], "theirs", istate, NULL); for (i = 0; i < 3; i++) free(mmfile[i].ptr); memset(&io, 0, sizeof(io)); io.io.getline = rerere_mem_getline; if (output) io.io.output = fopen(output, "w"); else io.io.output = NULL; strbuf_init(&io.input, 0); strbuf_attach(&io.input, result.ptr, result.size, result.size); /* * Grab the conflict ID and optionally write the original * contents with conflict markers out. */ has_conflicts = handle_path(hash, (struct rerere_io *)&io, marker_size); strbuf_release(&io.input); if (io.io.output) fclose(io.io.output); return has_conflicts; }