From: Junio C Hamano Date: Sun, 30 Jul 2017 21:57:33 +0000 (-0700) Subject: Merge tag 'v2.9.5' into maint-2.10 X-Git-Tag: v2.10.4~1 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d78f06a1b70f3743899b5494f55a456596e51a63?ds=inline;hp=-c Merge tag 'v2.9.5' into maint-2.10 Git 2.9.5 --- d78f06a1b70f3743899b5494f55a456596e51a63 diff --combined cache.h index 1ec9021a70,84148cf9ea..2125eb50d0 --- a/cache.h +++ b/cache.h @@@ -367,9 -367,8 +367,9 @@@ extern void free_name_hash(struct index #define rename_cache_entry_at(pos, new_name) rename_index_entry_at(&the_index, (pos), (new_name)) #define remove_cache_entry_at(pos) remove_index_entry_at(&the_index, (pos)) #define remove_file_from_cache(path) remove_file_from_index(&the_index, (path)) -#define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags), 0) -#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags), 0) +#define add_to_cache(path, st, flags) add_to_index(&the_index, (path), (st), (flags)) +#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags)) +#define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip)) #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL) #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options)) #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) @@@ -582,10 -581,9 +582,10 @@@ extern int remove_file_from_index(struc #define ADD_CACHE_IGNORE_ERRORS 4 #define ADD_CACHE_IGNORE_REMOVAL 8 #define ADD_CACHE_INTENT 16 -extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags, int force_mode); -extern int add_file_to_index(struct index_state *, const char *path, int flags, int force_mode); +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, unsigned int refresh_options); +extern int chmod_index_entry(struct index_state *, struct cache_entry *ce, char flip); 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); @@@ -1006,11 -1004,6 +1006,11 @@@ int adjust_shared_perm(const char *path * directory while we were working. To be robust against this kind of * race, callers might want to try invoking the function again when it * returns SCLD_VANISHED. + * + * safe_create_leading_directories() temporarily changes path while it + * is working but restores it before returning. + * safe_create_leading_directories_const() doesn't modify path, even + * temporarily. */ enum scld_error { SCLD_OK = 0, @@@ -1042,6 -1035,14 +1042,14 @@@ char *strip_path_suffix(const char *pat int daemon_avoid_alias(const char *path); extern int is_ntfs_dotgit(const char *name); + /* + * Returns true iff "str" could be confused as a command-line option when + * passed to a sub-program like "ssh". Note that this has nothing to do with + * shell-quoting, which should be handled separately; we're assuming here that + * the string makes it verbatim to the sub-program. + */ + int looks_like_command_line_option(const char *str); + /** * Return a newly allocated string with the evaluation of * "$XDG_CONFIG_HOME/git/$filename" if $XDG_CONFIG_HOME is non-empty, otherwise @@@ -1123,7 -1124,6 +1131,7 @@@ static inline int has_sha1_file(const u /* Same as the above, except for struct object_id. */ extern int has_object_file(const struct object_id *oid); +extern int has_object_file_with_flags(const struct object_id *oid, int flags); /* * Return true iff an alternate object database has a loose object @@@ -1142,16 -1142,6 +1150,16 @@@ static inline unsigned int hexval(unsig return hexval_table[c]; } +/* + * Convert two consecutive hexadecimal digits into a char. Return a + * negative value on error. Don't run over the end of short strings. + */ +static inline int hex2chr(const char *s) +{ + int val = hexval(s[0]); + return (val < 0) ? val : (val << 4) | hexval(s[1]); +} + /* Convert to/from hex/sha1 representation */ #define MINIMUM_ABBREV minimum_abbrev #define DEFAULT_ABBREV default_abbrev @@@ -1212,7 -1202,6 +1220,7 @@@ extern int get_oid_hex(const char *hex * printf("%s -> %s", sha1_to_hex(one), sha1_to_hex(two)); */ extern char *sha1_to_hex_r(char *out, const unsigned char *sha1); +extern char *oid_to_hex_r(char *out, const struct object_id *oid); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as sha1_to_hex */ @@@ -1392,13 -1381,6 +1400,13 @@@ extern struct packed_git char pack_name[FLEX_ARRAY]; /* more */ } *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; + struct pack_entry { off_t offset; unsigned char sha1[20]; @@@ -1438,6 -1420,7 +1446,6 @@@ extern unsigned char *use_pack(struct p extern void close_pack_windows(struct packed_git *); extern void close_all_packs(void); 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 *path, size_t path_len, int local); @@@ -1587,18 -1570,10 +1595,18 @@@ struct git_config_source const char *blob; }; +enum config_origin_type { + CONFIG_ORIGIN_BLOB, + CONFIG_ORIGIN_FILE, + CONFIG_ORIGIN_STDIN, + CONFIG_ORIGIN_SUBMODULE_BLOB, + CONFIG_ORIGIN_CMDLINE +}; + 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 *); -extern int git_config_from_mem(config_fn_t fn, const char *origin_type, +extern int git_config_from_mem(config_fn_t fn, const enum config_origin_type, const char *name, const char *buf, size_t len, void *data); extern void git_config_push_parameter(const char *text); extern int git_config_from_parameters(config_fn_t fn, void *data); @@@ -1640,16 -1615,6 +1648,16 @@@ extern const char *get_log_output_encod extern const char *get_commit_output_encoding(void); extern int git_config_parse_parameter(const char *, config_fn_t fn, void *data); + +enum config_scope { + CONFIG_SCOPE_UNKNOWN = 0, + CONFIG_SCOPE_SYSTEM, + CONFIG_SCOPE_GLOBAL, + CONFIG_SCOPE_REPO, + CONFIG_SCOPE_CMDLINE, +}; + +extern enum config_scope current_config_scope(void); extern const char *current_config_origin_type(void); extern const char *current_config_name(void); @@@ -1742,8 -1707,6 +1750,8 @@@ extern int ignore_untracked_cache_confi struct key_value_info { const char *filename; int linenr; + enum config_origin_type origin_type; + enum config_scope scope; }; extern NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3))); @@@ -1769,6 -1732,7 +1777,6 @@@ extern int copy_file(const char *dst, c extern int copy_file_with_time(const char *dst, const char *src, int mode); extern void write_or_die(int fd, const void *buf, size_t count); -extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg); extern void fsync_or_die(int fd, const char *); extern ssize_t read_in_full(int fd, void *buf, size_t count); @@@ -1780,21 -1744,8 +1788,21 @@@ static inline ssize_t write_str_in_full return write_in_full(fd, str, strlen(str)); } -extern int write_file(const char *path, const char *fmt, ...); -extern int write_file_gently(const char *path, const char *fmt, ...); +/** + * Open (and truncate) the file at path, write the contents of buf to it, + * and close it. Dies if any errors are encountered. + */ +extern void write_file_buf(const char *path, const char *buf, size_t len); + +/** + * Like write_file_buf(), but format the contents into a buffer first. + * Additionally, write_file() will append a newline if one is not already + * present, making it convenient to write text files: + * + * write_file(path, "counter: %d", ctr); + */ +__attribute__((format (printf, 2, 3))) +extern void write_file(const char *path, const char *fmt, ...); /* pager.c */ extern void setup_pager(void); @@@ -1831,7 -1782,7 +1839,7 @@@ void packet_trace_identity(const char * * return 0 if success, 1 - if addition of a file failed and * ADD_FILES_IGNORE_ERRORS was specified in flags */ -int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags, int force_mode); +int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int flags); /* diff.c */ extern int diff_auto_refresh_index; diff --combined connect.c index 722dc3fc54,c75bf52ee2..048fa04917 --- a/connect.c +++ b/connect.c @@@ -557,6 -557,11 +557,11 @@@ static struct child_process *git_proxy_ get_host_and_port(&host, &port); + if (looks_like_command_line_option(host)) + die("strange hostname '%s' blocked", host); + if (looks_like_command_line_option(port)) + die("strange port '%s' blocked", port); + proxy = xmalloc(sizeof(*proxy)); child_process_init(proxy); argv_array_push(&proxy->args, git_proxy_command); @@@ -658,19 -663,6 +663,19 @@@ static enum protocol parse_connect_url( static struct child_process no_fork = CHILD_PROCESS_INIT; +static const char *get_ssh_command(void) +{ + const char *ssh; + + if ((ssh = getenv("GIT_SSH_COMMAND"))) + return ssh; + + if (!git_config_get_string_const("core.sshcommand", &ssh)) + return ssh; + + return NULL; +} + /* * This returns a dummy child_process if the transport protocol does not * need fork(2), or a struct child_process object if it does. Once done, @@@ -739,6 -731,9 +744,9 @@@ struct child_process *git_connect(int f conn = xmalloc(sizeof(*conn)); child_process_init(conn); + if (looks_like_command_line_option(path)) + die("strange pathname '%s' blocked", path); + strbuf_addstr(&cmd, prog); strbuf_addch(&cmd, ' '); sq_quote_buf(&cmd, path); @@@ -771,7 -766,10 +779,10 @@@ return NULL; } + if (looks_like_command_line_option(ssh_host)) + die("strange hostname '%s' blocked", ssh_host); + - ssh = getenv("GIT_SSH_COMMAND"); + ssh = get_ssh_command(); if (!ssh) { const char *base; char *ssh_dup; diff --combined path.c index 9bfaeda207,0778ff03f9..6d4b007f4a --- a/path.c +++ b/path.c @@@ -24,8 -24,7 +24,8 @@@ static struct strbuf *get_pathname(void STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; static int index; - struct strbuf *sb = &pathname_array[3 & ++index]; + struct strbuf *sb = &pathname_array[index]; + index = (index + 1) % ARRAY_SIZE(pathname_array); strbuf_reset(sb); return sb; } @@@ -381,8 -380,6 +381,8 @@@ static void adjust_git_path(struct strb get_index_file(), strlen(get_index_file())); else if (git_db_env && dir_prefix(base, "objects")) replace_dir(buf, git_dir_len + 7, get_object_directory()); + else if (git_hooks_path && dir_prefix(base, "hooks")) + replace_dir(buf, git_dir_len + 5, git_hooks_path); else if (git_common_dir_env) update_common_dir(buf, git_dir_len, NULL); } @@@ -1225,6 -1222,11 +1225,11 @@@ int is_ntfs_dotgit(const char *name } } + int looks_like_command_line_option(const char *str) + { + return str && str[0] == '-'; + } + char *xdg_config_home(const char *filename) { const char *home, *config_home;