static struct cache_entry *read_one_ent(const char *which, unsigned char *ent, const char *path, int namelen, int stage) { unsigned mode; unsigned char sha1[20]; int size; struct cache_entry *ce; if (get_tree_entry(ent, path, sha1, &mode)) { if (which) error("%s: not in %s branch.", path, which); return NULL; } if (mode == S_IFDIR) { if (which) error("%s: not a blob in %s branch.", path, which); return NULL; } size = cache_entry_size(namelen); ce = xcalloc(1, size); hashcpy(ce->sha1, sha1); memcpy(ce->name, path, namelen); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = namelen; ce->ce_mode = create_ce_mode(mode); return ce; }
static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st) { int option, size; struct cache_entry *ce; /* Was the old index entry already up-to-date? */ if (old && !ce_stage(old) && !ce_match_stat(old, st, 0)) return 0; size = cache_entry_size(len); ce = xcalloc(1, size); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(0); ce->ce_namelen = len; fill_stat_cache_info(ce, st); ce->ce_mode = ce_mode_from_stat(old, st->st_mode); if (index_path(ce->sha1, path, st, info_only ? 0 : HASH_WRITE_OBJECT)) { free(ce); return -1; } option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; if (add_cache_entry(ce, option)) return error("%s: cannot add to the index - missing --add option?", path); return 0; }
static struct cache_entry *read_one_ent(const char *which, struct object_id *ent, const char *path, int namelen, int stage) { unsigned mode; struct object_id oid; struct cache_entry *ce; if (get_tree_entry(ent, path, &oid, &mode)) { if (which) error("%s: not in %s branch.", path, which); return NULL; } if (mode == S_IFDIR) { if (which) error("%s: not a blob in %s branch.", path, which); return NULL; } ce = make_empty_cache_entry(&the_index, namelen); oidcpy(&ce->oid, &oid); memcpy(ce->name, path, namelen); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = namelen; ce->ce_mode = create_ce_mode(mode); return ce; }
static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, const char *path, int stage) { int size, len, option; struct cache_entry *ce; if (!verify_path(path)) return error("Invalid path '%s'", path); len = strlen(path); size = cache_entry_size(len); ce = xcalloc(1, size); hashcpy(ce->sha1, sha1); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); if (assume_unchanged) ce->ce_flags |= CE_VALID; option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; if (add_cache_entry(ce, option)) return error("%s: cannot add to the index - missing --add option?", path); report("add '%s'", path); return 0; }
static int add_cacheinfo(unsigned int mode, const struct object_id *oid, const char *path, int stage) { int len, option; struct cache_entry *ce; if (!verify_path(path, mode)) return error("Invalid path '%s'", path); len = strlen(path); ce = make_empty_cache_entry(&the_index, len); oidcpy(&ce->oid, oid); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); if (assume_unchanged) ce->ce_flags |= CE_VALID; option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; if (add_cache_entry(ce, option)) return error("%s: cannot add to the index - missing --add option?", path); report("add '%s'", path); return 0; }
static struct cache_entry *create_ce_entry(const struct traverse_info *info, const struct name_entry *n, int stage) { int len = traverse_path_len(info, n); struct cache_entry *ce = xcalloc(1, cache_entry_size(len)); ce->ce_mode = create_ce_mode(n->mode); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = len; hashcpy(ce->sha1, n->sha1); make_traverse_path(ce->name, info, n); return ce; }
static int update_some(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context) { struct cache_entry *ce; ce = (struct cache_entry *)context; if (S_ISDIR(mode)) return READ_TREE_RECURSIVE; hashcpy(ce->sha1, sha1); memcpy(ce->name, base, baselen); memcpy(ce->name + baselen, pathname, strlen(pathname)); ce->ce_flags = create_ce_flags(strlen(pathname)+baselen, 0); ce->ce_mode = create_ce_mode(mode); return 0; }
static int update_some(const unsigned char* sha1, struct strbuf* base, const char *pathname, unsigned mode, int stage, void *context) { struct cache_entry *ce; UNREFERENCED_PARAMETER(stage); ce = (struct cache_entry *)context; if (S_ISDIR(mode)) return READ_TREE_RECURSIVE; hashcpy(ce->oid.hash, sha1); memcpy(ce->name, base->buf, base->len); memcpy(ce->name + base->len, pathname, strlen(pathname)); ce->ce_flags = create_ce_flags((unsigned int)(strlen(pathname) + base->len)); ce->ce_mode = create_ce_mode(mode); return 0; }
static int read_one_entry_opt(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, int opt) { int len; unsigned int size; struct cache_entry *ce; if (S_ISDIR(mode)) return READ_TREE_RECURSIVE; len = strlen(pathname); size = cache_entry_size(baselen + len); ce = xcalloc(1, size); ce->ce_mode = create_ce_mode(mode); ce->ce_flags = create_ce_flags(baselen + len, stage); memcpy(ce->name, base, baselen); memcpy(ce->name + baselen, pathname, len+1); hashcpy(ce->sha1, sha1); return add_cache_entry(ce, opt); }
static int update_some(const struct object_id *oid, struct strbuf *base, const char *pathname, unsigned mode, int stage, void *context) { int len; struct cache_entry *ce; int pos; if (S_ISDIR(mode)) return READ_TREE_RECURSIVE; len = base->len + strlen(pathname); ce = make_empty_cache_entry(&the_index, len); oidcpy(&ce->oid, oid); memcpy(ce->name, base->buf, base->len); memcpy(ce->name + base->len, pathname, len - base->len); ce->ce_flags = create_ce_flags(0) | CE_UPDATE; ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); /* * If the entry is the same as the current index, we can leave the old * entry in place. Whether it is UPTODATE or not, checkout_entry will * do the right thing. */ pos = cache_name_pos(ce->name, ce->ce_namelen); if (pos >= 0) { struct cache_entry *old = active_cache[pos]; if (ce->ce_mode == old->ce_mode && oideq(&ce->oid, &old->oid)) { old->ce_flags |= CE_UPDATE; discard_cache_entry(ce); return 0; } } add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE); return 0; }
/* * Prepare a dummy commit that represents the work tree (or staged) item. * Note that annotating work tree item never works in the reverse. */ static struct commit *fake_working_tree_commit(struct diff_options *opt, const char *path, const char *contents_from) { struct commit *commit; struct blame_origin *origin; struct commit_list **parent_tail, *parent; struct object_id head_oid; struct strbuf buf = STRBUF_INIT; const char *ident; time_t now; int size, len; struct cache_entry *ce; unsigned mode; struct strbuf msg = STRBUF_INIT; read_cache(); time(&now); commit = alloc_commit_node(); commit->object.parsed = 1; commit->date = now; parent_tail = &commit->parents; if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL)) die("no such ref: HEAD"); parent_tail = append_parent(parent_tail, &head_oid); append_merge_parents(parent_tail); verify_working_tree_path(commit, path); origin = make_origin(commit, path); ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, 0); strbuf_addstr(&msg, "tree 0000000000000000000000000000000000000000\n"); for (parent = commit->parents; parent; parent = parent->next) strbuf_addf(&msg, "parent %s\n", oid_to_hex(&parent->item->object.oid)); strbuf_addf(&msg, "author %s\n" "committer %s\n\n" "Version of %s from %s\n", ident, ident, path, (!contents_from ? path : (!strcmp(contents_from, "-") ? "standard input" : contents_from))); set_commit_buffer_from_strbuf(commit, &msg); if (!contents_from || strcmp("-", contents_from)) { struct stat st; const char *read_from; char *buf_ptr; unsigned long buf_len; if (contents_from) { if (stat(contents_from, &st) < 0) die_errno("Cannot stat '%s'", contents_from); read_from = contents_from; } else { if (lstat(path, &st) < 0) die_errno("Cannot lstat '%s'", path); read_from = path; } mode = canon_mode(st.st_mode); switch (st.st_mode & S_IFMT) { case S_IFREG: if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && textconv_object(read_from, mode, &null_oid, 0, &buf_ptr, &buf_len)) strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1); else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) die_errno("cannot open or read '%s'", read_from); break; case S_IFLNK: if (strbuf_readlink(&buf, read_from, st.st_size) < 0) die_errno("cannot readlink '%s'", read_from); break; default: die("unsupported file type %s", read_from); } } else { /* Reading from stdin */ mode = 0; if (strbuf_read(&buf, 0, 0) < 0) die_errno("failed to read from stdin"); } convert_to_git(path, buf.buf, buf.len, &buf, 0); origin->file.ptr = buf.buf; origin->file.size = buf.len; pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_oid.hash); /* * Read the current index, replace the path entry with * origin->blob_sha1 without mucking with its mode or type * bits; we are not going to write this index out -- we just * want to run "diff-index --cached". */ discard_cache(); read_cache(); len = strlen(path); if (!mode) { int pos = cache_name_pos(path, len); if (0 <= pos) mode = active_cache[pos]->ce_mode; else /* Let's not bother reading from HEAD tree */ mode = S_IFREG | 0644; } size = cache_entry_size(len); ce = xcalloc(1, size); oidcpy(&ce->oid, &origin->blob_oid); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(0); ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); cache_tree_invalidate_path(&the_index, path); return commit; }