From: Junio C Hamano Date: Fri, 14 Mar 2014 21:26:29 +0000 (-0700) Subject: Merge branch 'mh/object-code-cleanup' X-Git-Tag: v2.0.0-rc0~117 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/060be00621dbac572ac71d07ae40884e0d4303f3?ds=inline;hp=-c Merge branch 'mh/object-code-cleanup' * mh/object-code-cleanup: sha1_file.c: document a bunch of functions defined in the file sha1_file_name(): declare to return a const string find_pack_entry(): document last_found_pack replace_object: use struct members instead of an array --- 060be00621dbac572ac71d07ae40884e0d4303f3 diff --combined cache.h index 5ce6dfeddb,d2ca541fcc..00ba6bf08e --- a/cache.h +++ b/cache.h @@@ -3,7 -3,7 +3,7 @@@ #include "git-compat-util.h" #include "strbuf.h" -#include "hash.h" +#include "hashmap.h" #include "advice.h" #include "gettext.h" #include "convert.h" @@@ -130,12 -130,12 +130,12 @@@ struct stat_data }; struct cache_entry { + struct hashmap_entry ent; struct stat_data ce_stat_data; unsigned int ce_mode; unsigned int ce_flags; unsigned int ce_namelen; unsigned char sha1[20]; - struct cache_entry *next; char name[FLEX_ARRAY]; /* more */ }; @@@ -159,6 -159,7 +159,6 @@@ #define CE_ADDED (1 << 19) #define CE_HASHED (1 << 20) -#define CE_UNHASHED (1 << 21) #define CE_WT_REMOVE (1 << 22) /* remove in work directory */ #define CE_CONFLICTED (1 << 23) @@@ -194,18 -195,17 +194,18 @@@ struct pathspec * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state! */ -#define CE_STATE_MASK (CE_HASHED | CE_UNHASHED) static inline void copy_cache_entry(struct cache_entry *dst, const struct cache_entry *src) { - unsigned int state = dst->ce_flags & CE_STATE_MASK; + unsigned int state = dst->ce_flags & CE_HASHED; /* Don't copy hash chain and name */ - memcpy(dst, src, offsetof(struct cache_entry, next)); + memcpy(&dst->ce_stat_data, &src->ce_stat_data, + offsetof(struct cache_entry, name) - + offsetof(struct cache_entry, ce_stat_data)); /* Restore the hash state */ - dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state; + dst->ce_flags = (dst->ce_flags & ~CE_HASHED) | state; } static inline unsigned create_ce_flags(unsigned stage) @@@ -277,8 -277,8 +277,8 @@@ struct index_state struct cache_time timestamp; unsigned name_hash_initialized : 1, initialized : 1; - struct hash_table name_hash; - struct hash_table dir_hash; + struct hashmap name_hash; + struct hashmap dir_hash; }; extern struct index_state the_index; @@@ -316,6 -316,7 +316,6 @@@ extern void free_name_hash(struct index #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen)) #define cache_file_exists(name, namelen, igncase) index_file_exists(&the_index, (name), (namelen), (igncase)) -#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase)) #define cache_name_is_other(name, namelen) index_name_is_other(&the_index, (name), (namelen)) #define resolve_undo_clear() resolve_undo_clear_index(&the_index) #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at) @@@ -433,7 -434,6 +433,7 @@@ extern int set_git_dir_init(const char extern int init_db(const char *template_dir, unsigned int flags); extern void sanitize_stdfds(void); +extern int daemonize(void); #define alloc_nr(x) (((x)+16)*3/2) @@@ -467,6 -467,7 +467,6 @@@ extern int unmerged_index(const struct extern int verify_path(const char *path); extern struct cache_entry *index_dir_exists(struct index_state *istate, const char *name, int namelen); extern struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int igncase); -extern struct cache_entry *index_name_exists(struct index_state *istate, const char *name, int namelen, int igncase); extern int index_name_pos(const struct index_state *, const char *name, int namelen); #define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */ #define ADD_CACHE_OK_TO_REPLACE 2 /* Ok to replace file/directory */ @@@ -483,11 -484,11 +483,11 @@@ extern int remove_file_from_index(struc #define ADD_CACHE_IGNORE_ERRORS 4 #define ADD_CACHE_IGNORE_REMOVAL 8 #define ADD_CACHE_INTENT 16 -#define ADD_CACHE_IMPLICIT_DOT 32 /* internal to "git add -u/-A" */ extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags); extern int add_file_to_index(struct index_state *, const char *path, int flags); -extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); +extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options); extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b); +extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce); extern int index_name_is_other(const struct index_state *, const char *, int); extern void *read_blob_data_from_index(struct index_state *, const char *, unsigned long *); @@@ -497,13 -498,11 +497,13 @@@ #define CE_MATCH_RACY_IS_DIRTY 02 /* do stat comparison even if CE_SKIP_WORKTREE is true */ #define CE_MATCH_IGNORE_SKIP_WORKTREE 04 +/* ignore non-existent files during stat update */ +#define CE_MATCH_IGNORE_MISSING 0x08 +/* enable stat refresh */ +#define CE_MATCH_REFRESH 0x10 extern int ie_match_stat(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int); extern int ie_modified(const struct index_state *, const struct cache_entry *, struct stat *, unsigned int); -extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec); - #define HASH_WRITE_OBJECT 1 #define HASH_FORMAT_CHECK 2 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); @@@ -660,9 -659,28 +660,28 @@@ extern char *git_path(const char *fmt, extern char *git_path_submodule(const char *path, const char *fmt, ...) __attribute__((format (printf, 2, 3))); - extern char *sha1_file_name(const unsigned char *sha1); + /* + * Return the name of the file in the local object database that would + * be used to store a loose object with the specified sha1. The + * return value is a pointer to a statically allocated buffer that is + * overwritten each time the function is called. + */ + extern const char *sha1_file_name(const unsigned char *sha1); + + /* + * Return the name of the (local) packfile with the specified sha1 in + * its name. The return value is a pointer to memory that is + * overwritten each time this function is called. + */ extern char *sha1_pack_name(const unsigned char *sha1); + + /* + * Return the name of the (local) pack index file with the specified + * sha1 in its name. The return value is a pointer to memory that is + * overwritten each time this function is called. + */ extern char *sha1_pack_index_name(const unsigned char *sha1); + extern const char *find_unique_abbrev(const unsigned char *sha1, int); extern const unsigned char null_sha1[20]; @@@ -809,7 -827,6 +828,7 @@@ extern int hash_sha1_file(const void *b extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1); extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *); extern int force_object_loose(const unsigned char *sha1, time_t mtime); +extern int git_open_noatime(const char *name); extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size); extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz); extern int parse_sha1_header(const char *hdr, unsigned long *sizep); @@@ -822,7 -839,19 +841,19 @@@ extern int check_sha1_signature(const u extern int move_temp_to_file(const char *tmpfile, const char *filename); extern int has_sha1_pack(const unsigned char *sha1); + + /* + * Return true iff we have an object named sha1, whether local or in + * an alternate object database, and whether packed or loose. This + * function does not respect replace references. + */ extern int has_sha1_file(const unsigned char *sha1); + + /* + * Return true iff an alternate object database has a loose object + * with the specified name. This function does not respect replace + * references. + */ extern int has_loose_object_nonlocal(const unsigned char *sha1); extern int has_pack_index(const unsigned char *sha1); @@@ -961,7 -990,6 +992,7 @@@ void datestamp(char *buf, int bufsize) unsigned long approxidate_careful(const char *, int *); unsigned long approxidate_relative(const char *date, const struct timeval *now); enum date_mode parse_date_format(const char *format); +int date_overflows(unsigned long date); #define IDENT_STRICT 1 #define IDENT_NO_DATE 2 @@@ -1086,17 -1114,46 +1117,46 @@@ extern struct packed_git *find_sha1_pac struct packed_git *packs); extern void pack_report(void); + + /* + * mmap the index file for the specified packfile (if it is not + * already mmapped). Return 0 on success. + */ extern int open_pack_index(struct packed_git *); + + /* + * munmap the index file for the specified packfile (if it is + * currently mmapped). + */ extern void close_pack_index(struct packed_git *); + extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *); extern void close_pack_windows(struct packed_git *); extern void unuse_pack(struct pack_window **); extern void free_pack_by_name(const char *); extern void clear_delta_base_cache(void); extern struct packed_git *add_packed_git(const char *, int, int); - extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t); - extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t); - extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *); + + /* + * Return the SHA-1 of the nth object within the specified packfile. + * Open the index if it is not already open. The return value points + * at the SHA-1 within the mmapped index. Return NULL if there is an + * error. + */ + extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t n); + + /* + * Return the offset of the nth object within the specified packfile. + * The index must already be opened. + */ + extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t n); + + /* + * If the object named sha1 is present in the specified packfile, + * return its offset within the packfile; otherwise, return 0. + */ + extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *); + extern int is_pack_valid(struct packed_git *); extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *); extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep); @@@ -1149,12 -1206,6 +1209,12 @@@ extern int update_server_info(int) #define CONFIG_INVALID_PATTERN 6 #define CONFIG_GENERIC_ERROR 7 +struct git_config_source { + unsigned int use_stdin:1; + const char *file; + const char *blob; +}; + typedef int (*config_fn_t)(const char *, const char *, void *); extern int git_default_config(const char *, const char *, void *); extern int git_config_from_file(config_fn_t fn, const char *, void *); @@@ -1164,7 -1215,8 +1224,7 @@@ extern void git_config_push_parameter(c extern int git_config_from_parameters(config_fn_t fn, void *data); extern int git_config(config_fn_t fn, void *); extern int git_config_with_options(config_fn_t fn, void *, - const char *filename, - const char *blob_ref, + struct git_config_source *config_source, int respect_includes); extern int git_config_early(config_fn_t fn, void *, const char *repo_config); extern int git_parse_ulong(const char *, unsigned long *); diff --combined http.c index 1212c587af,faa9dc8f82..94e1afdee7 --- a/http.c +++ b/http.c @@@ -880,20 -880,6 +880,20 @@@ int handle_curl_result(struct slot_resu } } +int run_one_slot(struct active_request_slot *slot, + struct slot_results *results) +{ + slot->results = results; + if (!start_active_slot(slot)) { + snprintf(curl_errorstr, sizeof(curl_errorstr), + "failed to start HTTP request"); + return HTTP_START_FAILED; + } + + run_active_slot(slot); + return handle_curl_result(results); +} + static CURLcode curlinfo_strbuf(CURL *curl, CURLINFO info, struct strbuf *buf) { char *ptr; @@@ -921,6 -907,7 +921,6 @@@ static int http_request(const char *url int ret; slot = get_active_slot(); - slot->results = &results; curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); if (result == NULL) { @@@ -955,7 -942,14 +955,7 @@@ curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip"); - if (start_active_slot(slot)) { - run_active_slot(slot); - ret = handle_curl_result(&results); - } else { - snprintf(curl_errorstr, sizeof(curl_errorstr), - "failed to start HTTP request"); - ret = HTTP_START_FAILED; - } + ret = run_one_slot(slot, &results); if (options && options->content_type) curlinfo_strbuf(slot->curl, CURLINFO_CONTENT_TYPE, @@@ -1390,7 -1384,7 +1390,7 @@@ struct http_object_request *new_http_ob unsigned char *sha1) { char *hex = sha1_to_hex(sha1); - char *filename; + const char *filename; char prevfile[PATH_MAX]; int prevlocal; char prev_buf[PREV_BUF_SIZE]; diff --combined sha1_file.c index 019628add5,bb9f09764a..b37c6f67e4 --- a/sha1_file.c +++ b/sha1_file.c @@@ -60,6 -60,12 +60,12 @@@ static struct cached_object empty_tree 0 }; + /* + * A pointer to the last packed_git in which an object was found. + * When an object is sought, we look in this packfile first, because + * objects that are looked up at similar times are often in the same + * packfile as one another. + */ static struct packed_git *last_found_pack; static struct cached_object *find_cached_object(const unsigned char *sha1) @@@ -178,17 -184,7 +184,7 @@@ static void fill_sha1_path(char *pathbu } } - /* - * NOTE! This returns a statically allocated buffer, so you have to be - * careful about using it. Do an "xstrdup()" if you need to save the - * filename. - * - * Also note that this returns the location for creating. Reading - * SHA1 file can happen from any alternate directory listed in the - * DB_ENVIRONMENT environment variable if it is not found in - * the primary object database. - */ - char *sha1_file_name(const unsigned char *sha1) + const char *sha1_file_name(const unsigned char *sha1) { static char buf[PATH_MAX]; const char *objdir; @@@ -208,6 -204,11 +204,11 @@@ return buf; } + /* + * Return the name of the pack or index file with the specified sha1 + * in its filename. *base and *name are scratch space that must be + * provided by the caller. which should be "pack" or "idx". + */ static char *sha1_get_pack_name(const unsigned char *sha1, char **name, char **base, const char *which) { @@@ -252,6 -253,8 +253,6 @@@ char *sha1_pack_index_name(const unsign struct alternate_object_database *alt_odb_list; static struct alternate_object_database **alt_odb_tail; -static int git_open_noatime(const char *name); - /* * Prepare alternate object database registry. * @@@ -436,8 -439,7 +437,7 @@@ void prepare_alt_odb(void static int has_loose_object_local(const unsigned char *sha1) { - char *name = sha1_file_name(sha1); - return !access(name, F_OK); + return !access(sha1_file_name(sha1), F_OK); } int has_loose_object_nonlocal(const unsigned char *sha1) @@@ -489,7 -491,12 +489,12 @@@ void pack_report(void sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped)); } - static int check_packed_git_idx(const char *path, struct packed_git *p) + /* + * Open and mmap the index file at path, perform a couple of + * consistency checks, then record its information to p. Return 0 on + * success. + */ + static int check_packed_git_idx(const char *path, struct packed_git *p) { void *idx_map; struct pack_idx_header *hdr; @@@ -1230,7 -1237,6 +1235,7 @@@ static void prepare_packed_git_one(cha if (has_extension(de->d_name, ".idx") || has_extension(de->d_name, ".pack") || + has_extension(de->d_name, ".bitmap") || has_extension(de->d_name, ".keep")) string_list_append(&garbage, path); else @@@ -1315,6 -1321,7 +1320,6 @@@ void prepare_packed_git(void void reprepare_packed_git(void) { - discard_revindex(); prepare_packed_git_run_once = 0; prepare_packed_git(); } @@@ -1391,7 -1398,7 +1396,7 @@@ int check_sha1_signature(const unsigne return hashcmp(sha1, real_sha1) ? -1 : 0; } -static int git_open_noatime(const char *name) +int git_open_noatime(const char *name) { static int sha1_file_open_flag = O_NOATIME; @@@ -1412,17 -1419,15 +1417,15 @@@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st) { - char *name = sha1_file_name(sha1); struct alternate_object_database *alt; - if (!lstat(name, st)) + if (!lstat(sha1_file_name(sha1), st)) return 0; prepare_alt_odb(); errno = ENOENT; for (alt = alt_odb_list; alt; alt = alt->next) { - name = alt->name; - fill_sha1_path(name, sha1); + fill_sha1_path(alt->name, sha1); if (!lstat(alt->base, st)) return 0; } @@@ -1433,18 -1438,16 +1436,16 @@@ static int open_sha1_file(const unsigned char *sha1) { int fd; - char *name = sha1_file_name(sha1); struct alternate_object_database *alt; - fd = git_open_noatime(name); + fd = git_open_noatime(sha1_file_name(sha1)); if (fd >= 0) return fd; prepare_alt_odb(); errno = ENOENT; for (alt = alt_odb_list; alt; alt = alt->next) { - name = alt->name; - fill_sha1_path(name, sha1); + fill_sha1_path(alt->name, sha1); fd = git_open_noatime(alt->base); if (fd >= 0) return fd; @@@ -2446,6 -2449,10 +2447,10 @@@ static int fill_pack_entry(const unsign return 1; } + /* + * Iff a pack file contains the object named by sha1, return true and + * store its location to e. + */ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e) { struct packed_git *p; @@@ -2458,11 -2465,13 +2463,13 @@@ return 1; for (p = packed_git; p; p = p->next) { - if (p == last_found_pack || !fill_pack_entry(sha1, e, p)) - continue; + if (p == last_found_pack) + continue; /* we already checked this one */ - last_found_pack = p; - return 1; + if (fill_pack_entry(sha1, e, p)) { + last_found_pack = p; + return 1; + } } return 0; } @@@ -2677,7 -2686,6 +2684,6 @@@ void *read_sha1_file_extended(const uns unsigned flag) { void *data; - char *path; const struct packed_git *p; const unsigned char *repl = lookup_replace_object_extended(sha1, flag); @@@ -2695,7 -2703,8 +2701,8 @@@ sha1_to_hex(repl), sha1_to_hex(sha1)); if (has_loose_object(repl)) { - path = sha1_file_name(sha1); + const char *path = sha1_file_name(sha1); + die("loose object %s (stored in %s) is corrupt", sha1_to_hex(repl), path); } @@@ -2893,10 -2902,9 +2900,9 @@@ static int write_loose_object(const uns git_zstream stream; git_SHA_CTX c; unsigned char parano_sha1[20]; - char *filename; static char tmp_file[PATH_MAX]; + const char *filename = sha1_file_name(sha1); - filename = sha1_file_name(sha1); fd = create_tmpfile(tmp_file, sizeof(tmp_file), filename); if (fd < 0) { if (errno == EACCES)