From: Junio C Hamano Date: Tue, 3 Oct 2017 06:42:48 +0000 (+0900) Subject: Merge branch 'jk/no-optional-locks' X-Git-Tag: v2.15.0-rc0~20 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d4e93836a6a072e392b20d7daf604fd41e15ecf9?ds=inline;hp=-c Merge branch 'jk/no-optional-locks' Some commands (most notably "git status") makes an opportunistic update when performing a read-only operation to help optimize later operations in the same repository. The new "--no-optional-locks" option can be passed to Git to disable them. * jk/no-optional-locks: git: add --no-optional-locks option --- d4e93836a6a072e392b20d7daf604fd41e15ecf9 diff --combined builtin/commit.c index 0f8ddb6866,a8ef73d9ca..d75b3805ea --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -195,6 -195,7 +195,6 @@@ static void determine_whence(struct wt_ static void status_init_config(struct wt_status *s, config_fn_t fn) { wt_status_prepare(s); - gitmodules_config(); git_config(fn, s); determine_whence(s); init_diff_ui_defaults(); @@@ -335,7 -336,7 +335,7 @@@ static void refresh_cache_or_die(int re static const char *prepare_index(int argc, const char **argv, const char *prefix, const struct commit *current_head, int is_status) { - struct string_list partial; + struct string_list partial = STRING_LIST_INIT_DUP; struct pathspec pathspec; int refresh_flags = REFRESH_QUIET; const char *ret; @@@ -380,8 -381,7 +380,8 @@@ warning(_("Failed to update main cache tree")); commit_style = COMMIT_NORMAL; - return get_lock_file_path(&index_lock); + ret = get_lock_file_path(&index_lock); + goto out; } /* @@@ -404,8 -404,7 +404,8 @@@ if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) die(_("unable to write new_index file")); commit_style = COMMIT_NORMAL; - return get_lock_file_path(&index_lock); + ret = get_lock_file_path(&index_lock); + goto out; } /* @@@ -431,8 -430,7 +431,8 @@@ rollback_lock_file(&index_lock); } commit_style = COMMIT_AS_IS; - return get_index_file(); + ret = get_index_file(); + goto out; } /* @@@ -463,6 -461,7 +463,6 @@@ die(_("cannot do a partial commit during a cherry-pick.")); } - string_list_init(&partial, 1); if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, &pathspec)) exit(1); @@@ -492,9 -491,6 +492,9 @@@ discard_cache(); ret = get_lock_file_path(&false_lock); read_cache_from(ret); +out: + string_list_clear(&partial, 0); + clear_pathspec(&pathspec); return ret; } @@@ -514,7 -510,7 +514,7 @@@ static int run_status(FILE *fp, const c s->index_file = index_file; s->fp = fp; s->nowarn = nowarn; - s->is_initial = get_sha1(s->reference, oid.hash) ? 1 : 0; + s->is_initial = get_oid(s->reference, &oid) ? 1 : 0; if (!s->is_initial) hashcpy(s->sha1_commit, oid.hash); s->status_format = status_format; @@@ -895,7 -891,7 +895,7 @@@ static int prepare_to_commit(const cha if (amend) parent = "HEAD^1"; - if (get_sha1(parent, oid.hash)) { + if (get_oid(parent, &oid)) { int i, ita_nr = 0; for (i = 0; i < active_nr; i++) @@@ -944,16 -940,13 +944,16 @@@ return 0; } - /* - * Re-read the index as pre-commit hook could have updated it, - * and write it out as a tree. We must do this before we invoke - * the editor and after we invoke run_status above. - */ - discard_cache(); + if (!no_verify && find_hook("pre-commit")) { + /* + * Re-read the index as pre-commit hook could have updated it, + * and write it out as a tree. We must do this before we invoke + * the editor and after we invoke run_status above. + */ + discard_cache(); + } read_cache_from(index_file); + if (update_main_cache_tree(0)) { error(_("Error building trees")); return 0; @@@ -1392,9 -1385,12 +1392,12 @@@ int cmd_status(int argc, const char **a read_cache_preload(&s.pathspec); refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL); - fd = hold_locked_index(&index_lock, 0); + if (use_optional_locks()) + fd = hold_locked_index(&index_lock, 0); + else + fd = -1; - s.is_initial = get_sha1(s.reference, oid.hash) ? 1 : 0; + s.is_initial = get_oid(s.reference, &oid) ? 1 : 0; if (!s.is_initial) hashcpy(s.sha1_commit, oid.hash); @@@ -1436,6 -1432,7 +1439,6 @@@ static void print_summary(const char *p struct rev_info rev; struct commit *commit; struct strbuf format = STRBUF_INIT; - struct object_id junk_oid; const char *head; struct pretty_print_context pctx = {0}; struct strbuf author_ident = STRBUF_INIT; @@@ -1488,7 -1485,7 +1491,7 @@@ rev.diffopt.break_opt = 0; diff_setup_done(&rev.diffopt); - head = resolve_ref_unsafe("HEAD", 0, junk_oid.hash, NULL); + head = resolve_ref_unsafe("HEAD", 0, NULL, NULL); if (!strcmp(head, "HEAD")) head = _("detached HEAD"); else @@@ -1663,7 -1660,7 +1666,7 @@@ int cmd_commit(int argc, const char **a status_format = STATUS_FORMAT_NONE; /* Ignore status.short */ s.colopts = 0; - if (get_sha1("HEAD", oid.hash)) + if (get_oid("HEAD", &oid)) current_head = NULL; else { current_head = lookup_commit_or_die(&oid, "HEAD"); @@@ -1822,7 -1819,6 +1825,7 @@@ if (!quiet) print_summary(prefix, &oid, !current_head); - strbuf_release(&err); + UNLEAK(err); + UNLEAK(sb); return 0; } diff --combined cache.h index ea6c236e0f,56053cf39b..6440e2bf21 --- a/cache.h +++ b/cache.h @@@ -4,7 -4,6 +4,7 @@@ #include "git-compat-util.h" #include "strbuf.h" #include "hashmap.h" +#include "mru.h" #include "advice.h" #include "gettext.h" #include "convert.h" @@@ -418,6 -417,7 +418,6 @@@ static inline enum object_type object_t #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE" #define GIT_PREFIX_ENVIRONMENT "GIT_PREFIX" #define GIT_SUPER_PREFIX_ENVIRONMENT "GIT_INTERNAL_SUPER_PREFIX" -#define GIT_TOPLEVEL_PREFIX_ENVIRONMENT "GIT_INTERNAL_TOPLEVEL_PREFIX" #define DEFAULT_GIT_DIR_ENVIRONMENT ".git" #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY" #define INDEX_ENVIRONMENT "GIT_INDEX_FILE" @@@ -433,7 -433,6 +433,7 @@@ #define GITATTRIBUTES_FILE ".gitattributes" #define INFOATTRIBUTES_FILE "info/attributes" #define ATTRIBUTE_MACRO_PREFIX "[attr]" +#define GITMODULES_FILE ".gitmodules" #define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF" #define GIT_NOTES_DEFAULT_REF "refs/notes/commits" #define GIT_NOTES_DISPLAY_REF_ENVIRONMENT "GIT_NOTES_DISPLAY_REF" @@@ -444,6 -443,7 +444,7 @@@ #define GIT_NOGLOB_PATHSPECS_ENVIRONMENT "GIT_NOGLOB_PATHSPECS" #define GIT_ICASE_PATHSPECS_ENVIRONMENT "GIT_ICASE_PATHSPECS" #define GIT_QUARANTINE_ENVIRONMENT "GIT_QUARANTINE_PATH" + #define GIT_OPTIONAL_LOCKS_ENVIRONMENT "GIT_OPTIONAL_LOCKS" /* * This environment variable is expected to contain a boolean indicating @@@ -685,8 -685,8 +686,8 @@@ extern int ie_modified(const struct ind #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); -extern int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned flags); +extern int index_fd(struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); +extern int index_path(struct object_id *oid, const char *path, struct stat *st, unsigned flags); /* * Record to sd the data from st that we use to check whether a file @@@ -783,6 -783,11 +784,11 @@@ extern int protect_ntfs */ extern int ref_paranoia; + /* + * Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). + */ + int use_optional_locks(void); + /* * The character that begins a commented line in user-editable file * that is subject to stripspace. @@@ -903,6 -908,20 +909,6 @@@ extern void check_repository_format(voi */ 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); - /* * Return an abbreviated sha1 unique within this repository's object database. * The result will be at least `len` characters long, and will be NUL @@@ -1179,7 -1198,7 +1185,7 @@@ static inline const unsigned char *look extern int sha1_object_info(const unsigned char *, unsigned long *); extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1); extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1); -extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags); +extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, struct object_id *oid, unsigned flags); 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_cloexec(const char *name, int flags); @@@ -1188,10 -1207,15 +1194,10 @@@ extern void *map_sha1_file(const unsign 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); -/* global flag to enable extra checks when accessing packed objects */ -extern int do_check_packed_object_crc; - extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); extern int finalize_object_file(const char *tmpfile, const char *filename); -extern int has_sha1_pack(const unsigned char *sha1); - /* * Open the loose object at path, check its sha1, and return the contents, * type, and size. If the object is a blob, then "contents" may return NULL, @@@ -1227,6 -1251,8 +1233,6 @@@ extern int has_object_file_with_flags(c */ extern int has_loose_object_nonlocal(const unsigned char *sha1); -extern int has_pack_index(const unsigned char *sha1); - extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect); /* Helper to check and "touch" a file */ @@@ -1244,8 -1270,8 +1250,8 @@@ static inline unsigned int hexval(unsig */ static inline int hex2chr(const char *s) { - int val = hexval(s[0]); - return (val < 0) ? val : (val << 4) | hexval(s[1]); + unsigned int val = hexval(s[0]); + return (val & ~0xf) ? val : (val << 4) | hexval(s[1]); } /* Convert to/from hex/sha1 representation */ @@@ -1264,37 -1290,38 +1270,37 @@@ struct object_context */ struct strbuf symlink_path; /* - * If GET_SHA1_RECORD_PATH is set, this will record path (if any) + * If GET_OID_RECORD_PATH is set, this will record path (if any) * found when resolving the name. The caller is responsible for * releasing the memory. */ char *path; }; -#define GET_SHA1_QUIETLY 01 -#define GET_SHA1_COMMIT 02 -#define GET_SHA1_COMMITTISH 04 -#define GET_SHA1_TREE 010 -#define GET_SHA1_TREEISH 020 -#define GET_SHA1_BLOB 040 -#define GET_SHA1_FOLLOW_SYMLINKS 0100 -#define GET_SHA1_RECORD_PATH 0200 -#define GET_SHA1_ONLY_TO_DIE 04000 - -#define GET_SHA1_DISAMBIGUATORS \ - (GET_SHA1_COMMIT | GET_SHA1_COMMITTISH | \ - GET_SHA1_TREE | GET_SHA1_TREEISH | \ - GET_SHA1_BLOB) - -extern int get_sha1(const char *str, unsigned char *sha1); -extern int get_sha1_commit(const char *str, unsigned char *sha1); -extern int get_sha1_committish(const char *str, unsigned char *sha1); -extern int get_sha1_tree(const char *str, unsigned char *sha1); -extern int get_sha1_treeish(const char *str, unsigned char *sha1); -extern int get_sha1_blob(const char *str, unsigned char *sha1); -extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix); -extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *oc); +#define GET_OID_QUIETLY 01 +#define GET_OID_COMMIT 02 +#define GET_OID_COMMITTISH 04 +#define GET_OID_TREE 010 +#define GET_OID_TREEISH 020 +#define GET_OID_BLOB 040 +#define GET_OID_FOLLOW_SYMLINKS 0100 +#define GET_OID_RECORD_PATH 0200 +#define GET_OID_ONLY_TO_DIE 04000 + +#define GET_OID_DISAMBIGUATORS \ + (GET_OID_COMMIT | GET_OID_COMMITTISH | \ + GET_OID_TREE | GET_OID_TREEISH | \ + GET_OID_BLOB) extern int get_oid(const char *str, struct object_id *oid); +extern int get_oid_commit(const char *str, struct object_id *oid); +extern int get_oid_committish(const char *str, struct object_id *oid); +extern int get_oid_tree(const char *str, struct object_id *oid); +extern int get_oid_treeish(const char *str, struct object_id *oid); +extern int get_oid_blob(const char *str, struct object_id *oid); +extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix); +extern int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc); + typedef int each_abbrev_fn(const struct object_id *oid, void *); extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *); @@@ -1590,7 -1617,8 +1596,7 @@@ extern struct packed_git * A most-recently-used ordered version of the packed_git list, which can * be iterated instead of packed_git (and marked via mru_mark). */ -struct mru; -extern struct mru *packed_git_mru; +extern struct mru packed_git_mru; struct pack_entry { off_t offset; @@@ -1598,6 -1626,29 +1604,6 @@@ struct packed_git *p; }; -extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); - -/* A hook to report invalid files in pack directory */ -#define PACKDIR_FILE_PACK 1 -#define PACKDIR_FILE_IDX 2 -#define PACKDIR_FILE_GARBAGE 4 -extern void (*report_garbage)(unsigned seen_bits, const char *path); - -extern void prepare_packed_git(void); -extern void reprepare_packed_git(void); -extern void install_packed_git(struct packed_git *pack); - -/* - * Give a rough count of objects in the repository. This sacrifices accuracy - * for speed. - */ -unsigned long approximate_object_count(void); - -extern struct packed_git *find_sha1_pack(const unsigned char *sha1, - struct packed_git *packs); - -extern void pack_report(void); - /* * Create a temporary file rooted in the object database directory, or * die on failure. The filename is taken from "pattern", which should have the @@@ -1606,6 -1657,15 +1612,6 @@@ */ extern int odb_mkstemp(struct strbuf *template, const char *pattern); -/* - * Generate the filename to be used for a pack file with checksum "sha1" and - * extension "ext". The result is written into the strbuf "buf", overwriting - * any existing contents. A pointer to buf->buf is returned as a convenience. - * - * Example: odb_pack_name(out, sha1, "idx") => ".git/objects/pack/pack-1234..idx" - */ -extern char *odb_pack_name(struct strbuf *buf, const unsigned char *sha1, const char *ext); - /* * Create a pack .keep file named "name" (which should generally be the output * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on @@@ -1613,6 -1673,67 +1619,6 @@@ */ extern int odb_pack_keep(const char *name); -/* - * 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 close_all_packs(void); -extern void unuse_pack(struct pack_window **); -extern void clear_delta_base_cache(void); -extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local); - -/* - * Make sure that a pointer access into an mmap'd index file is within bounds, - * and can provide at least 8 bytes of data. - * - * Note that this is only necessary for variable-length segments of the file - * (like the 64-bit extended offset table), as we compare the size to the - * fixed-length parts when we open the file. - */ -extern void check_pack_index_ptr(const struct packed_git *p, const void *ptr); - -/* - * 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); -/* - * Like nth_packed_object_sha1, but write the data into the object specified by - * the the first argument. Returns the first argument on success, and NULL on - * error. - */ -extern const struct object_id *nth_packed_object_oid(struct object_id *, 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); -extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t); -extern int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *); - /* * Iterate over the files in the loose-object parts of the object * directory "path", triggering the following callbacks: @@@ -1662,12 -1783,17 +1668,12 @@@ int for_each_loose_file_in_objdir_buf(s void *data); /* - * Iterate over loose and packed objects in both the local + * Iterate over loose objects in both the local * repository and any alternates repositories (unless the * LOCAL_ONLY flag is set). */ #define FOR_EACH_OBJECT_LOCAL_ONLY 0x1 -typedef int each_packed_object_fn(const struct object_id *oid, - struct packed_git *pack, - uint32_t pos, - void *data); extern int for_each_loose_object(each_loose_object_fn, void *, unsigned flags); -extern int for_each_packed_object(each_packed_object_fn, void *, unsigned flags); struct object_info { /* Request */ @@@ -1717,6 -1843,7 +1723,6 @@@ /* Do not retry packed storage after checking packed and loose storage */ #define OBJECT_INFO_QUICK 8 extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags); -extern int packed_object_info(struct packed_git *pack, off_t offset, struct object_info *); /* Dumb servers support */ extern int update_server_info(int); @@@ -1835,8 -1962,6 +1841,8 @@@ void shift_tree_by(const struct object_ #define WS_TRAILING_SPACE (WS_BLANK_AT_EOL|WS_BLANK_AT_EOF) #define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB|8) #define WS_TAB_WIDTH_MASK 077 +/* All WS_* -- when extended, adapt diff.c emit_symbol */ +#define WS_RULE_MASK 07777 extern unsigned whitespace_rule_cfg; extern unsigned whitespace_rule(const char *); extern unsigned parse_whitespace_rule(const char *); diff --combined environment.c index f1f934b6fd,68823598d3..8289c25b44 --- a/environment.c +++ b/environment.c @@@ -97,7 -97,7 +97,7 @@@ int ignore_untracked_cache_config /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; -static const char *namespace; +static char *namespace; static const char *super_prefix; @@@ -152,10 -152,8 +152,10 @@@ void setup_git_env(void if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) check_replace_refs = 0; replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); + free(git_replace_ref_base); git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base : "refs/replace/"); + free(namespace); namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT)); shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); if (shallow_file) @@@ -338,3 -336,8 +338,8 @@@ void reset_shared_repository(void { need_shared_repository_from_config = 1; } + + int use_optional_locks(void) + { + return git_env_bool(GIT_OPTIONAL_LOCKS_ENVIRONMENT, 1); + } diff --combined git.c index f31dca6962,21a3c9872c..9e96dd4090 --- a/git.c +++ b/git.c @@@ -182,6 -182,10 +182,10 @@@ static int handle_options(const char ** setenv(GIT_ICASE_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) *envchanged = 1; + } else if (!strcmp(cmd, "--no-optional-locks")) { + setenv(GIT_OPTIONAL_LOCKS_ENVIRONMENT, "0", 1); + if (envchanged) + *envchanged = 1; } else if (!strcmp(cmd, "--shallow-file")) { (*argv)++; (*argc)--; @@@ -404,7 -408,7 +408,7 @@@ static struct cmd_struct commands[] = { "fsck-objects", cmd_fsck, RUN_SETUP }, { "gc", cmd_gc, RUN_SETUP }, { "get-tar-commit-id", cmd_get_tar_commit_id }, - { "grep", cmd_grep, RUN_SETUP_GENTLY | SUPPORT_SUPER_PREFIX }, + { "grep", cmd_grep, RUN_SETUP_GENTLY }, { "hash-object", cmd_hash_object }, { "help", cmd_help }, { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },