From: Junio C Hamano Date: Tue, 2 Sep 2014 20:23:19 +0000 (-0700) Subject: Merge branch 'mm/config-edit-global' X-Git-Tag: v2.2.0-rc0~180 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/1d8a6f6929054919baf4032e22935523c2843f2c?hp=-c Merge branch 'mm/config-edit-global' Start "git config --edit --global" from a skeletal per-user configuration file contents, instead of a total blank, when the user does not already have any. This immediately reduces the need for a later "Have you forgotten setting core.user?" and we can add more to the template as we gain more experience. * mm/config-edit-global: commit: advertise config --global --edit on guessed identity home_config_paths(): let the caller ignore xdg path config --global --edit: create a template file if needed --- 1d8a6f6929054919baf4032e22935523c2843f2c diff --combined builtin/commit.c index 5ed60364ce,cddebc031b..a3eaf4b5ea --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -42,7 -42,20 +42,20 @@@ static const char * const builtin_statu NULL }; - static const char implicit_ident_advice[] = + static const char implicit_ident_advice_noconfig[] = + N_("Your name and email address were configured automatically based\n" + "on your username and hostname. Please check that they are accurate.\n" + "You can suppress this message by setting them explicitly. Run the\n" + "following command and follow the instructions in your editor to edit\n" + "your configuration file:\n" + "\n" + " git config --global --edit\n" + "\n" + "After doing this, you may fix the identity used for this commit with:\n" + "\n" + " git commit --amend --reset-author\n"); + + static const char implicit_ident_advice_config[] = N_("Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" "You can suppress this message by setting them explicitly:\n" @@@ -305,6 -318,7 +318,6 @@@ static void refresh_cache_or_die(int re static char *prepare_index(int argc, const char **argv, const char *prefix, const struct commit *current_head, int is_status) { - int fd; struct string_list partial; struct pathspec pathspec; int refresh_flags = REFRESH_QUIET; @@@ -320,11 -334,12 +333,11 @@@ if (interactive) { char *old_index_env = NULL; - fd = hold_locked_index(&index_lock, 1); + hold_locked_index(&index_lock, 1); refresh_cache_or_die(refresh_flags); - if (write_cache(fd, active_cache, active_nr) || - close_lock_file(&index_lock)) + if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) die(_("unable to create temporary index")); old_index_env = getenv(INDEX_ENVIRONMENT); @@@ -358,11 -373,12 +371,11 @@@ * (B) on failure, rollback the real index. */ if (all || (also && pathspec.nr)) { - fd = hold_locked_index(&index_lock, 1); + hold_locked_index(&index_lock, 1); add_files_to_cache(also ? prefix : NULL, &pathspec, 0); refresh_cache_or_die(refresh_flags); update_main_cache_tree(WRITE_TREE_SILENT); - if (write_cache(fd, active_cache, active_nr) || - close_lock_file(&index_lock)) + if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) die(_("unable to write new_index file")); commit_style = COMMIT_NORMAL; return index_lock.filename; @@@ -378,12 -394,12 +391,12 @@@ * We still need to refresh the index here. */ if (!only && !pathspec.nr) { - fd = hold_locked_index(&index_lock, 1); + hold_locked_index(&index_lock, 1); refresh_cache_or_die(refresh_flags); if (active_cache_changed) { update_main_cache_tree(WRITE_TREE_SILENT); - if (write_cache(fd, active_cache, active_nr) || - commit_locked_index(&index_lock)) + if (write_locked_index(&the_index, &index_lock, + COMMIT_LOCK)) die(_("unable to write new_index file")); } else { rollback_lock_file(&index_lock); @@@ -420,7 -436,8 +433,7 @@@ die(_("cannot do a partial commit during a cherry-pick.")); } - memset(&partial, 0, sizeof(partial)); - partial.strdup_strings = 1; + string_list_init(&partial, 1); if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, &pathspec)) exit(1); @@@ -428,22 -445,24 +441,22 @@@ if (read_cache() < 0) die(_("cannot read the index")); - fd = hold_locked_index(&index_lock, 1); + hold_locked_index(&index_lock, 1); add_remove_files(&partial); refresh_cache(REFRESH_QUIET); - if (write_cache(fd, active_cache, active_nr) || - close_lock_file(&index_lock)) + if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) die(_("unable to write new_index file")); - fd = hold_lock_file_for_update(&false_lock, - git_path("next-index-%"PRIuMAX, - (uintmax_t) getpid()), - LOCK_DIE_ON_ERROR); + hold_lock_file_for_update(&false_lock, + git_path("next-index-%"PRIuMAX, + (uintmax_t) getpid()), + LOCK_DIE_ON_ERROR); create_base_index(current_head); add_remove_files(&partial); refresh_cache(REFRESH_QUIET); - if (write_cache(fd, active_cache, active_nr) || - close_lock_file(&false_lock)) + if (write_locked_index(&the_index, &false_lock, CLOSE_LOCK)) die(_("unable to write temporary index file")); discard_cache(); @@@ -520,29 -539,10 +533,29 @@@ static int sane_ident_split(struct iden return 1; } +static int parse_force_date(const char *in, char *out, int len) +{ + if (len < 1) + return -1; + *out++ = '@'; + len--; + + if (parse_date(in, out, len) < 0) { + int errors = 0; + unsigned long t = approxidate_careful(in, &errors); + if (errors) + return -1; + snprintf(out, len, "%lu", t); + } + + return 0; +} + static void determine_author_info(struct strbuf *author_ident) { char *name, *email, *date; struct ident_split author; + char date_buf[64]; name = getenv("GIT_AUTHOR_NAME"); email = getenv("GIT_AUTHOR_EMAIL"); @@@ -587,12 -587,8 +600,12 @@@ email = xstrndup(lb + 2, rb - (lb + 2)); } - if (force_date) - date = force_date; + if (force_date) { + if (parse_force_date(force_date, date_buf, sizeof(date_buf))) + die(_("invalid date format: %s"), force_date); + date = date_buf; + } + strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT)); if (!split_ident_line(&author, author_ident->buf, author_ident->len) && sane_ident_split(&author)) { @@@ -602,46 -598,13 +615,46 @@@ } } -static char *cut_ident_timestamp_part(char *string) +static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf) { - char *ket = strrchr(string, '>'); - if (!ket || ket[1] != ' ') - die(_("Malformed ident string: '%s'"), string); - *++ket = '\0'; - return ket; + if (split_ident_line(id, buf->buf, buf->len) || + !sane_ident_split(id)) + die(_("Malformed ident string: '%s'"), buf->buf); +} + +static int author_date_is_interesting(void) +{ + return author_message || force_date; +} + +static void adjust_comment_line_char(const struct strbuf *sb) +{ + char candidates[] = "#;@!$%^&|:"; + char *candidate; + const char *p; + + comment_line_char = candidates[0]; + if (!memchr(sb->buf, comment_line_char, sb->len)) + return; + + p = sb->buf; + candidate = strchr(candidates, *p); + if (candidate) + *candidate = ' '; + for (p = sb->buf; *p; p++) { + if ((p[0] == '\n' || p[0] == '\r') && p[1]) { + candidate = strchr(candidates, p[1]); + if (candidate) + *candidate = ' '; + } + } + + for (p = candidates; *p == ' '; p++) + ; + if (!*p) + die(_("unable to select a comment character that is not used\n" + "in the current commit message")); + comment_line_char = *p; } static int prepare_to_commit(const char *index_file, const char *prefix, @@@ -701,7 -664,7 +714,7 @@@ char *buffer; buffer = strstr(use_message_buffer, "\n\n"); if (buffer) - strbuf_add(&sb, buffer + 2, strlen(buffer + 2)); + strbuf_addstr(&sb, buffer + 2); hook_arg1 = "commit"; hook_arg2 = use_message; } else if (fixup_message) { @@@ -797,8 -760,6 +810,8 @@@ if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) die_errno(_("could not write commit template")); + if (auto_comment_line_char) + adjust_comment_line_char(&sb); strbuf_release(&sb); /* This checks if committer ident is explicitly given */ @@@ -806,8 -767,7 +819,8 @@@ if (use_editor && include_status) { int ident_shown = 0; int saved_color_setting; - char *ai_tmp, *ci_tmp; + struct ident_split ci, ai; + if (whence != FROM_COMMIT) { if (cleanup_mode == CLEANUP_SCISSORS) wt_status_add_cut_line(s->fp); @@@ -847,39 -807,32 +860,39 @@@ status_printf_ln(s, GIT_COLOR_NORMAL, "%s", only_include_assumed); - ai_tmp = cut_ident_timestamp_part(author_ident->buf); - ci_tmp = cut_ident_timestamp_part(committer_ident.buf); - if (strcmp(author_ident->buf, committer_ident.buf)) + split_ident_or_die(&ai, author_ident); + split_ident_or_die(&ci, &committer_ident); + + if (ident_cmp(&ai, &ci)) status_printf_ln(s, GIT_COLOR_NORMAL, _("%s" - "Author: %s"), + "Author: %.*s <%.*s>"), ident_shown++ ? "" : "\n", - author_ident->buf); + (int)(ai.name_end - ai.name_begin), ai.name_begin, + (int)(ai.mail_end - ai.mail_begin), ai.mail_begin); + + if (author_date_is_interesting()) + status_printf_ln(s, GIT_COLOR_NORMAL, + _("%s" + "Date: %s"), + ident_shown++ ? "" : "\n", + show_ident_date(&ai, DATE_NORMAL)); if (!committer_ident_sufficiently_given()) status_printf_ln(s, GIT_COLOR_NORMAL, _("%s" - "Committer: %s"), + "Committer: %.*s <%.*s>"), ident_shown++ ? "" : "\n", - committer_ident.buf); + (int)(ci.name_end - ci.name_begin), ci.name_begin, + (int)(ci.mail_end - ci.mail_begin), ci.mail_begin); if (ident_shown) - status_printf_ln(s, GIT_COLOR_NORMAL, ""); + status_printf_ln(s, GIT_COLOR_NORMAL, "%s", ""); saved_color_setting = s->use_color; s->use_color = 0; commitable = run_status(s->fp, index_file, prefix, 1, s); s->use_color = saved_color_setting; - - *ai_tmp = ' '; - *ci_tmp = ' '; } else { unsigned char sha1[20]; const char *parent = "HEAD"; @@@ -1014,7 -967,7 +1027,7 @@@ static int message_is_empty(struct strb static int template_untouched(struct strbuf *sb) { struct strbuf tmpl = STRBUF_INIT; - char *start; + const char *start; if (cleanup_mode == CLEANUP_NONE && sb->len) return 0; @@@ -1023,7 -976,8 +1036,7 @@@ return 0; stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); - start = (char *)skip_prefix(sb->buf, tmpl.buf); - if (!start) + if (!skip_prefix(sb->buf, tmpl.buf, &start)) start = sb->buf; strbuf_release(&tmpl); return rest_is_empty(sb, start - sb->buf); @@@ -1402,6 -1356,24 +1415,24 @@@ int cmd_status(int argc, const char **a return 0; } + static const char *implicit_ident_advice(void) + { + char *user_config = NULL; + char *xdg_config = NULL; + int config_exists; + + home_config_paths(&user_config, &xdg_config, "config"); + config_exists = file_exists(user_config) || file_exists(xdg_config); + free(user_config); + free(xdg_config); + + if (config_exists) + return _(implicit_ident_advice_config); + else + return _(implicit_ident_advice_noconfig); + + } + static void print_summary(const char *prefix, const unsigned char *sha1, int initial_commit) { @@@ -1428,19 -1400,12 +1459,19 @@@ strbuf_addstr(&format, "\n Author: "); strbuf_addbuf_percentquote(&format, &author_ident); } + if (author_date_is_interesting()) { + struct strbuf date = STRBUF_INIT; + format_commit_message(commit, "%ad", &date, &pctx); + strbuf_addstr(&format, "\n Date: "); + strbuf_addbuf_percentquote(&format, &date); + strbuf_release(&date); + } if (!committer_ident_sufficiently_given()) { strbuf_addstr(&format, "\n Committer: "); strbuf_addbuf_percentquote(&format, &committer_ident); if (advice_implicit_identity) { strbuf_addch(&format, '\n'); - strbuf_addstr(&format, _(implicit_ident_advice)); + strbuf_addstr(&format, implicit_ident_advice()); } } strbuf_release(&author_ident); @@@ -1751,10 -1716,6 +1782,10 @@@ int cmd_commit(int argc, const char **a ? NULL : current_head->object.sha1, 0, NULL); + if (!ref_lock) { + rollback_index_files(); + die(_("cannot lock HEAD ref")); + } nl = strchr(sb.buf, '\n'); if (nl) @@@ -1764,6 -1725,10 +1795,6 @@@ strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg)); strbuf_insert(&sb, strlen(reflog_msg), ": ", 2); - if (!ref_lock) { - rollback_index_files(); - die(_("cannot lock HEAD ref")); - } if (write_ref_sha1(ref_lock, sha1, sb.buf) < 0) { rollback_index_files(); die(_("cannot update HEAD ref")); diff --combined builtin/config.c index fcd8474701,9346894240..aba71355f8 --- a/builtin/config.c +++ b/builtin/config.c @@@ -395,6 -395,19 +395,6 @@@ static int urlmatch_collect_fn(const ch return 0; } -static char *dup_downcase(const char *string) -{ - char *result; - size_t len, i; - - len = strlen(string); - result = xmalloc(len + 1); - for (i = 0; i < len; i++) - result[i] = tolower(string[i]); - result[i] = '\0'; - return result; -} - static int get_urlmatch(const char *var, const char *url) { char *section_tail; @@@ -409,7 -422,7 +409,7 @@@ if (!url_normalize(url, &config.url)) die("%s", config.url.err); - config.section = dup_downcase(var); + config.section = xstrdup_tolower(var); section_tail = strchr(config.section, '.'); if (section_tail) { *section_tail = '\0'; @@@ -445,6 -458,20 +445,20 @@@ return 0; } + static char *default_user_config(void) + { + struct strbuf buf = STRBUF_INIT; + strbuf_addf(&buf, + _("# This is Git's per-user configuration file.\n" + "[core]\n" + "# Please adapt and uncomment the following lines:\n" + "# user = %s\n" + "# email = %s\n"), + ident_default_name(), + ident_default_email()); + return strbuf_detach(&buf, NULL); + } + int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = !startup_info->have_repository; @@@ -551,6 -578,8 +565,8 @@@ } } else if (actions == ACTION_EDIT) { + const char *config_file = given_config_source.file ? + given_config_source.file : git_path("config"); check_argc(argc, 0, 0); if (!given_config_source.file && nongit) die("not in a git directory"); @@@ -559,9 -588,18 +575,18 @@@ if (given_config_source.blob) die("editing blobs is not supported"); git_config(git_default_config, NULL); - launch_editor(given_config_source.file ? - given_config_source.file : git_path("config"), - NULL, NULL); + if (use_global_config) { + int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (fd) { + char *content = default_user_config(); + write_str_in_full(fd, content); + free(content); + close(fd); + } + else if (errno != EEXIST) + die_errno(_("cannot create configuration file %s"), config_file); + } + launch_editor(config_file, NULL, NULL); } else if (actions == ACTION_SET) { int ret; diff --combined cache.h index 30268b6eed,beb00a659c..76be785087 --- a/cache.h +++ b/cache.h @@@ -7,7 -7,6 +7,7 @@@ #include "advice.h" #include "gettext.h" #include "convert.h" +#include "trace.h" #include SHA1_HEADER #ifndef git_SHA_CTX @@@ -75,21 -74,6 +75,21 @@@ unsigned long git_deflate_bound(git_zst #define S_IFGITLINK 0160000 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK) +/* + * Some mode bits are also used internally for computations. + * + * They *must* not overlap with any valid modes, and they *must* not be emitted + * to outside world - i.e. appear on disk or network. In other words, it's just + * temporary fields, which we internally use, but they have to stay in-house. + * + * ( such approach is valid, as standard S_IF* fits into 16 bits, and in Git + * codebase mode is `unsigned int` which is assumed to be at least 32 bits ) + */ + +/* used internally in tree-diff */ +#define S_DIFFTREE_IFXMIN_NEQ 0x80000000 + + /* * Intensive research over the course of many years has shown that * port 9418 is totally unused by anything else. Or @@@ -151,7 -135,6 +151,7 @@@ struct cache_entry unsigned int ce_mode; unsigned int ce_flags; unsigned int ce_namelen; + unsigned int index; /* for link extension */ unsigned char sha1[20]; char name[FLEX_ARRAY]; /* more */ }; @@@ -162,7 -145,7 +162,7 @@@ #define CE_STAGESHIFT 12 /* - * Range 0xFFFF0000 in ce_flags is divided into + * Range 0xFFFF0FFF in ce_flags is divided into * two parts: in-memory flags and on-disk ones. * Flags in CE_EXTENDED_FLAGS will get saved on-disk * if you want to save a new flag, add it in @@@ -185,9 -168,6 +185,9 @@@ /* used to temporarily mark paths matched by pathspecs */ #define CE_MATCHED (1 << 26) +#define CE_UPDATE_IN_BASE (1 << 27) +#define CE_STRIP_NAME (1 << 28) + /* * Extended on-disk flags */ @@@ -288,22 -268,12 +288,22 @@@ static inline unsigned int canon_mode(u #define cache_entry_size(len) (offsetof(struct cache_entry,name) + (len) + 1) +#define SOMETHING_CHANGED (1 << 0) /* unclassified changes go here */ +#define CE_ENTRY_CHANGED (1 << 1) +#define CE_ENTRY_REMOVED (1 << 2) +#define CE_ENTRY_ADDED (1 << 3) +#define RESOLVE_UNDO_CHANGED (1 << 4) +#define CACHE_TREE_CHANGED (1 << 5) +#define SPLIT_INDEX_ORDERED (1 << 6) + +struct split_index; struct index_state { struct cache_entry **cache; unsigned int version; unsigned int cache_nr, cache_alloc, cache_changed; struct string_list *resolve_undo; struct cache_tree *cache_tree; + struct split_index *split_index; struct cache_time timestamp; unsigned name_hash_initialized : 1, initialized : 1; @@@ -332,6 -302,7 +332,6 @@@ extern void free_name_hash(struct index #define read_cache_preload(pathspec) read_index_preload(&the_index, (pathspec)) #define is_cache_unborn() is_index_unborn(&the_index) #define read_cache_unmerged() read_index_unmerged(&the_index) -#define write_cache(newfd, cache, entries) write_index(&the_index, (newfd)) #define discard_cache() discard_index(&the_index) #define unmerged_cache() unmerged_index(&the_index) #define cache_name_pos(name, namelen) index_name_pos(&the_index,(name),(namelen)) @@@ -486,17 -457,12 +486,17 @@@ extern int daemonize(void) } while (0) /* Initialize and use the cache information */ +struct lock_file; extern int read_index(struct index_state *); extern int read_index_preload(struct index_state *, const struct pathspec *pathspec); +extern int do_read_index(struct index_state *istate, const char *path, + int must_exist); /* for testting only! */ extern int read_index_from(struct index_state *, const char *path); extern int is_index_unborn(struct index_state *); extern int read_index_unmerged(struct index_state *); -extern int write_index(struct index_state *, int newfd); +#define COMMIT_LOCK (1 << 0) +#define CLOSE_LOCK (1 << 1) +extern int write_locked_index(struct index_state *, struct lock_file *lock, unsigned flags); extern int discard_index(struct index_state *); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); @@@ -508,7 -474,6 +508,7 @@@ extern int index_name_pos(const struct #define ADD_CACHE_SKIP_DFCHECK 4 /* Ok to skip DF conflict checks */ #define ADD_CACHE_JUST_APPEND 8 /* Append only; tree.c::read_tree() */ #define ADD_CACHE_NEW_ONLY 16 /* Do not replace existing ones */ +#define ADD_CACHE_KEEP_CACHE_TREE 32 /* Do not invalidate cache-tree */ extern int add_index_entry(struct index_state *, struct cache_entry *ce, int option); extern void rename_index_entry_at(struct index_state *, int pos, const char *new_name); extern int remove_index_entry_at(struct index_state *, int pos); @@@ -579,16 -544,14 +579,16 @@@ struct lock_file #define LOCK_DIE_ON_ERROR 1 #define LOCK_NODEREF 2 extern int unable_to_lock_error(const char *path, int err); +extern void unable_to_lock_message(const char *path, int err, + struct strbuf *buf); extern NORETURN void unable_to_lock_index_die(const char *path, int err); extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int hold_lock_file_for_append(struct lock_file *, const char *path, int); extern int commit_lock_file(struct lock_file *); +extern int reopen_lock_file(struct lock_file *); extern void update_index_if_able(struct index_state *, struct lock_file *); extern int hold_locked_index(struct lock_file *, int); -extern int commit_locked_index(struct lock_file *); extern void set_alternate_index_output(const char *); extern int close_lock_file(struct lock_file *); extern void rollback_lock_file(struct lock_file *); @@@ -640,7 -603,6 +640,7 @@@ extern int precomposed_unicode * that is subject to stripspace. */ extern char comment_line_char; +extern int auto_comment_line_char; enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, @@@ -848,6 -810,7 +848,6 @@@ int normalize_path_copy(char *dst, cons int longest_ancestor_length(const char *path, struct string_list *prefixes); char *strip_path_suffix(const char *path, const char *suffix); int daemon_avoid_alias(const char *path); -int offset_1st_component(const char *path); /* object replacement */ #define LOOKUP_REPLACE_OBJECT 1 @@@ -999,7 -962,7 +999,7 @@@ extern int read_ref(const char *refname * NULL. If more than MAXDEPTH recursive symbolic lookups are needed, * give up and return NULL. * - * errno is sometimes set on errors, but not always. + * errno is set to something meaningful on error. */ extern const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1, int reading, int *flag); extern char *resolve_refdup(const char *ref, unsigned char *sha1, int reading, int *flag); @@@ -1021,7 -984,7 +1021,7 @@@ extern int validate_headref(const char extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2); extern int df_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2); -extern int cache_name_compare(const char *name1, int len1, const char *name2, int len2); +extern int name_compare(const char *name1, size_t len1, const char *name2, size_t len2); extern int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2); extern void *read_object_with_reference(const unsigned char *sha1, @@@ -1062,6 -1025,7 +1062,7 @@@ extern const char *git_author_info(int) extern const char *git_committer_info(int); extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int); extern const char *fmt_name(const char *name, const char *email); + extern const char *ident_default_name(void); extern const char *ident_default_email(void); extern const char *git_editor(void); extern const char *git_pager(int stdout_is_tty); @@@ -1083,13 -1047,6 +1084,13 @@@ struct ident_split */ extern int split_ident_line(struct ident_split *, const char *, int); +/* + * Like show_date, but pull the timestamp and tz parameters from + * the ident_split. It will also sanity-check the values and produce + * a well-known sentinel date if they appear bogus. + */ +const char *show_ident_date(const struct ident_split *id, enum date_mode mode); + /* * Compare split idents for equality or strict ordering. Note that we * compare only the ident part of the line, ignoring any timestamp. @@@ -1100,7 -1057,6 +1101,7 @@@ extern int ident_cmp(const struct ident_split *, const struct ident_split *); struct checkout { + struct index_state *istate; const char *base_dir; int base_dir_len; unsigned force:1, @@@ -1113,16 -1069,12 +1114,16 @@@ extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); struct cache_def { - char path[PATH_MAX + 1]; - int len; + struct strbuf path; int flags; int track_flags; int prefix_len_stat_func; }; +#define CACHE_DEF_INIT { STRBUF_INIT, 0, 0, 0 } +static inline void cache_def_clear(struct cache_def *cache) +{ + strbuf_release(&cache->path); +} extern int has_symlink_leading_path(const char *name, int len); extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int); @@@ -1321,8 -1273,8 +1322,8 @@@ extern int check_repository_format_vers extern int git_env_bool(const char *, int); extern int git_config_system(void); extern int config_error_nonbool(const char *); -#if defined(__GNUC__) && ! defined(__clang__) -#define config_error_nonbool(s) (config_error_nonbool(s), -1) +#if defined(__GNUC__) +#define config_error_nonbool(s) (config_error_nonbool(s), const_error()) #endif extern const char *get_log_output_encoding(void); extern const char *get_commit_output_encoding(void); @@@ -1403,9 -1355,18 +1404,9 @@@ extern void *alloc_commit_node(void) extern void *alloc_tag_node(void); extern void *alloc_object_node(void); extern void alloc_report(void); +extern unsigned int alloc_commit_index(void); -/* trace.c */ -__attribute__((format (printf, 1, 2))) -extern void trace_printf(const char *format, ...); -__attribute__((format (printf, 2, 3))) -extern void trace_argv_printf(const char **argv, const char *format, ...); -extern void trace_repo_setup(const char *prefix); -extern int trace_want(const char *key); -__attribute__((format (printf, 2, 3))) -extern void trace_printf_key(const char *key, const char *fmt, ...); -extern void trace_strbuf(const char *key, const struct strbuf *buf); - +/* pkt-line.c */ void packet_trace_identity(const char *prog); /* add */ diff --combined path.c index 3afcdb432a,1b6cdc407f..f68df0cf88 --- a/path.c +++ b/path.c @@@ -148,10 -148,12 +148,12 @@@ void home_config_paths(char **global, c *global = mkpathdup("%s/.gitconfig", home); } - if (!xdg_home) - *xdg = NULL; - else - *xdg = mkpathdup("%s/git/%s", xdg_home, file); + if (xdg) { + if (!xdg_home) + *xdg = NULL; + else + *xdg = mkpathdup("%s/git/%s", xdg_home, file); + } free(to_free); } @@@ -275,16 -277,16 +277,16 @@@ char *expand_user_path(const char *path const char *home = getenv("HOME"); if (!home) goto return_null; - strbuf_add(&user_path, home, strlen(home)); + strbuf_addstr(&user_path, home); } else { struct passwd *pw = getpw_str(username, username_len); if (!pw) goto return_null; - strbuf_add(&user_path, pw->pw_dir, strlen(pw->pw_dir)); + strbuf_addstr(&user_path, pw->pw_dir); } to_copy = first_slash; } - strbuf_add(&user_path, to_copy, strlen(to_copy)); + strbuf_addstr(&user_path, to_copy); return strbuf_detach(&user_path, NULL); return_null: strbuf_release(&user_path); @@@ -821,3 -823,10 +823,3 @@@ int daemon_avoid_alias(const char *p } } } - -int offset_1st_component(const char *path) -{ - if (has_dos_drive_prefix(path)) - return 2 + is_dir_sep(path[2]); - return is_dir_sep(path[0]); -}