From: Junio C Hamano Date: Wed, 14 May 2008 20:45:20 +0000 (-0700) Subject: Merge branch 'sb/committer' X-Git-Tag: v1.5.6-rc0~56 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/b66ae7955ca10cf4f59130c9a63b327e4d9df104?ds=inline;hp=-c Merge branch 'sb/committer' * sb/committer: commit: Show committer if automatic commit: Show author if different from committer Preparation to call determine_author_info from prepare_to_commit --- b66ae7955ca10cf4f59130c9a63b327e4d9df104 diff --combined builtin-commit.c index a65c2b8c37,a113eb0272..0baec6db6a --- a/builtin-commit.c +++ b/builtin-commit.c @@@ -47,6 -47,7 +47,7 @@@ static enum static char *logfile, *force_author, *template_file; static char *edit_message, *use_message; + static char *author_name, *author_email, *author_date; static int all, edit_flag, also, interactive, only, amend, signoff; static int quiet, verbose, untracked_files, no_verify, allow_empty; /* @@@ -101,7 -102,7 +102,7 @@@ static struct option builtin_commit_opt OPT_BOOLEAN('o', "only", &only, "commit only specified files"), OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"), OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), - OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"), + OPT_BOOLEAN('u', "untracked-files", &untracked_files, "show all untracked files"), OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"), OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"), @@@ -175,11 -176,9 +176,11 @@@ static void add_remove_files(struct pat { int i; for (i = 0; i < list->nr; i++) { + struct stat st; struct path_list_item *p = &(list->items[i]); - if (file_exists(p->path)) - add_file_to_cache(p->path, 0); + + if (!lstat(p->path, &st)) + add_to_cache(p->path, &st, 0); else remove_file_from_cache(p->path); } @@@ -397,6 -396,47 +398,47 @@@ static int is_a_merge(const unsigned ch static const char sign_off_header[] = "Signed-off-by: "; + static void determine_author_info(void) + { + char *name, *email, *date; + + name = getenv("GIT_AUTHOR_NAME"); + email = getenv("GIT_AUTHOR_EMAIL"); + date = getenv("GIT_AUTHOR_DATE"); + + if (use_message) { + const char *a, *lb, *rb, *eol; + + a = strstr(use_message_buffer, "\nauthor "); + if (!a) + die("invalid commit: %s", use_message); + + lb = strstr(a + 8, " <"); + rb = strstr(a + 8, "> "); + eol = strchr(a + 8, '\n'); + if (!lb || !rb || !eol) + die("invalid commit: %s", use_message); + + name = xstrndup(a + 8, lb - (a + 8)); + email = xstrndup(lb + 2, rb - (lb + 2)); + date = xstrndup(rb + 2, eol - (rb + 2)); + } + + if (force_author) { + const char *lb = strstr(force_author, " <"); + const char *rb = strchr(force_author, '>'); + + if (!lb || !rb) + die("malformed --author parameter"); + name = xstrndup(force_author, lb - force_author); + email = xstrndup(lb + 2, rb - (lb + 2)); + } + + author_name = name; + author_email = email; + author_date = date; + } + static int prepare_to_commit(const char *index_file, const char *prefix) { struct stat statbuf; @@@ -406,6 -446,7 +448,7 @@@ FILE *fp; const char *hook_arg1 = NULL; const char *hook_arg2 = NULL; + int ident_shown = 0; if (!no_verify && run_hook(index_file, "pre-commit", NULL)) return 0; @@@ -485,7 -526,14 +528,14 @@@ strbuf_release(&sb); + determine_author_info(); + + /* This checks if committer ident is explicitly given */ + git_committer_info(0); if (use_editor) { + char *author_ident; + const char *committer_ident; + if (in_merge) fprintf(fp, "#\n" @@@ -508,6 -556,27 +558,27 @@@ if (only_include_assumed) fprintf(fp, "# %s\n", only_include_assumed); + author_ident = xstrdup(fmt_name(author_name, author_email)); + committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"), + getenv("GIT_COMMITTER_EMAIL")); + if (strcmp(author_ident, committer_ident)) + fprintf(fp, + "%s" + "# Author: %s\n", + ident_shown++ ? "" : "#\n", + author_ident); + free(author_ident); + + if (!user_ident_explicitly_given) + fprintf(fp, + "%s" + "# Committer: %s\n", + ident_shown++ ? "" : "#\n", + committer_ident); + + if (ident_shown) + fprintf(fp, "#\n"); + saved_color_setting = wt_status_use_color; wt_status_use_color = 0; commitable = run_status(fp, index_file, prefix, 1); @@@ -624,45 -693,6 +695,6 @@@ static int message_is_empty(struct strb return 1; } - static void determine_author_info(struct strbuf *sb) - { - char *name, *email, *date; - - name = getenv("GIT_AUTHOR_NAME"); - email = getenv("GIT_AUTHOR_EMAIL"); - date = getenv("GIT_AUTHOR_DATE"); - - if (use_message) { - const char *a, *lb, *rb, *eol; - - a = strstr(use_message_buffer, "\nauthor "); - if (!a) - die("invalid commit: %s", use_message); - - lb = strstr(a + 8, " <"); - rb = strstr(a + 8, "> "); - eol = strchr(a + 8, '\n'); - if (!lb || !rb || !eol) - die("invalid commit: %s", use_message); - - name = xstrndup(a + 8, lb - (a + 8)); - email = xstrndup(lb + 2, rb - (lb + 2)); - date = xstrndup(rb + 2, eol - (rb + 2)); - } - - if (force_author) { - const char *lb = strstr(force_author, " <"); - const char *rb = strchr(force_author, '>'); - - if (!lb || !rb) - die("malformed --author parameter"); - name = xstrndup(force_author, lb - force_author); - email = xstrndup(lb + 2, rb - (lb + 2)); - } - - strbuf_addf(sb, "author %s\n", fmt_ident(name, email, date, IDENT_ERROR_ON_NO_NAME)); - } - static int parse_and_validate_options(int argc, const char *argv[], const char * const usage[]) { @@@ -922,7 -952,8 +954,8 @@@ int cmd_commit(int argc, const char **a strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1)); } - determine_author_info(&sb); + strbuf_addf(&sb, "author %s\n", + fmt_ident(author_name, author_email, author_date, IDENT_ERROR_ON_NO_NAME)); strbuf_addf(&sb, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); if (!is_encoding_utf8(git_commit_encoding)) strbuf_addf(&sb, "encoding %s\n", git_commit_encoding); diff --combined cache.h index 9cee9a5f3f,327e5eacd3..093f04cec0 --- a/cache.h +++ b/cache.h @@@ -133,7 -133,6 +133,7 @@@ struct cache_entry #define CE_UPDATE (0x10000) #define CE_REMOVE (0x20000) #define CE_UPTODATE (0x40000) +#define CE_ADDED (0x80000) #define CE_HASHED (0x100000) #define CE_UNHASHED (0x200000) @@@ -154,6 -153,20 +154,6 @@@ static inline void copy_cache_entry(str dst->ce_flags = (dst->ce_flags & ~CE_STATE_MASK) | state; } -/* - * We don't actually *remove* it, we can just mark it invalid so that - * we won't find it in lookups. - * - * Not only would we have to search the lists (simple enough), but - * we'd also have to rehash other hash buckets in case this makes the - * hash bucket empty (common). So it's much better to just mark - * it. - */ -static inline void remove_index_entry(struct cache_entry *ce) -{ - ce->ce_flags |= CE_UNHASHED; -} - static inline unsigned create_ce_flags(size_t len, unsigned stage) { if (len >= CE_NAMEMASK) @@@ -228,23 -241,6 +228,23 @@@ struct index_state extern struct index_state the_index; +/* Name hashing */ +extern void add_name_hash(struct index_state *istate, struct cache_entry *ce); +/* + * We don't actually *remove* it, we can just mark it invalid so that + * we won't find it in lookups. + * + * Not only would we have to search the lists (simple enough), but + * we'd also have to rehash other hash buckets in case this makes the + * hash bucket empty (common). So it's much better to just mark + * it. + */ +static inline void remove_name_hash(struct cache_entry *ce) +{ + ce->ce_flags |= CE_UNHASHED; +} + + #ifndef NO_THE_INDEX_COMPATIBILITY_MACROS #define active_cache (the_index.cache) #define active_nr (the_index.cache_nr) @@@ -261,12 -257,11 +261,12 @@@ #define add_cache_entry(ce, option) add_index_entry(&the_index, (ce), (option)) #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, verbose) add_to_index(&the_index, (path), (st), (verbose)) #define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose)) #define refresh_cache(flags) refresh_index(&the_index, (flags), 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)) -#define cache_name_exists(name, namelen) index_name_exists(&the_index, (name), (namelen)) +#define cache_name_exists(name, namelen, igncase) index_name_exists(&the_index, (name), (namelen), (igncase)) #endif enum object_type { @@@ -356,7 -351,7 +356,7 @@@ extern int write_index(const struct ind extern int discard_index(struct index_state *); extern int unmerged_index(const struct index_state *); extern int verify_path(const char *path); -extern int index_name_exists(struct index_state *istate, const char *name, int namelen); +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 */ @@@ -366,7 -361,6 +366,7 @@@ extern int add_index_entry(struct index extern struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really); extern int remove_index_entry_at(struct index_state *, int pos); extern int remove_file_from_index(struct index_state *, const char *path); +extern int add_to_index(struct index_state *, const char *path, struct stat *, int verbose); extern int add_file_to_index(struct index_state *, const char *path, int verbose); extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); @@@ -411,7 -405,6 +411,7 @@@ extern int delete_ref(const char *, con extern int trust_executable_bit; extern int quote_path_fully; extern int has_symlinks; +extern int ignore_case; extern int assume_unchanged; extern int prefer_symlink_refs; extern int log_all_ref_updates; @@@ -441,15 -434,7 +441,15 @@@ enum branch_track BRANCH_TRACK_EXPLICIT, }; +enum rebase_setup_type { + AUTOREBASE_NEVER = 0, + AUTOREBASE_LOCAL, + AUTOREBASE_REMOTE, + AUTOREBASE_ALWAYS, +}; + extern enum branch_track git_branch_track; +extern enum rebase_setup_type autorebase; #define GIT_REPO_VERSION 0 extern int repository_format_version; @@@ -606,7 -591,7 +606,7 @@@ struct checkout }; extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); -extern int has_symlink_leading_path(const char *name, char *last_symlink); +extern int has_symlink_leading_path(int len, const char *name); extern struct alternate_object_database { struct alternate_object_database *next; @@@ -650,7 -635,6 +650,7 @@@ struct ref struct ref *next; unsigned char old_sha1[20]; unsigned char new_sha1[20]; + char *symref; unsigned int force:1, merge:1, nonfastforward:1, @@@ -735,6 -719,7 +735,7 @@@ extern int config_error_nonbool(const c #define MAX_GITNAME (1000) extern char git_default_email[MAX_GITNAME]; extern char git_default_name[MAX_GITNAME]; + extern int user_ident_explicitly_given; extern const char *git_commit_encoding; extern const char *git_log_output_encoding; diff --combined config.c index e42ada78f8,3bc4c7ed59..5195de10c9 --- a/config.c +++ b/config.c @@@ -350,11 -350,6 +350,11 @@@ int git_default_config(const char *var return 0; } + if (!strcmp(var, "core.ignorecase")) { + ignore_case = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.bare")) { is_bare_repository_cfg = git_config_bool(var, value); return 0; @@@ -448,6 -443,8 +448,8 @@@ if (!value) return config_error_nonbool(var); strlcpy(git_default_name, value, sizeof(git_default_name)); + if (git_default_email[0]) + user_ident_explicitly_given = 1; return 0; } @@@ -455,6 -452,8 +457,8 @@@ if (!value) return config_error_nonbool(var); strlcpy(git_default_email, value, sizeof(git_default_email)); + if (git_default_name[0]) + user_ident_explicitly_given = 1; return 0; } @@@ -492,21 -491,6 +496,21 @@@ git_branch_track = git_config_bool(var, value); return 0; } + if (!strcmp(var, "branch.autosetuprebase")) { + if (!value) + return config_error_nonbool(var); + else if (!strcmp(value, "never")) + autorebase = AUTOREBASE_NEVER; + else if (!strcmp(value, "local")) + autorebase = AUTOREBASE_LOCAL; + else if (!strcmp(value, "remote")) + autorebase = AUTOREBASE_REMOTE; + else if (!strcmp(value, "always")) + autorebase = AUTOREBASE_ALWAYS; + else + return error("Malformed value for %s", var); + return 0; + } /* Add other config variables here and to Documentation/config.txt. */ return 0; @@@ -627,9 -611,11 +631,9 @@@ static int store_aux(const char* key, c case KEY_SEEN: if (matches(key, value)) { if (store.seen == 1 && store.multi_replace == 0) { - fprintf(stderr, - "Warning: %s has multiple values\n", - key); + warning("%s has multiple values", key); } else if (store.seen >= MAX_MATCHES) { - fprintf(stderr, "Too many matches\n"); + error("too many matches for %s", key); return 1; } @@@ -679,9 -665,9 +683,9 @@@ return 0; } -static int write_error(void) +static int write_error(const char *filename) { - fprintf(stderr, "Failed to write new configuration file\n"); + error("failed to write new configuration file %s", filename); /* Same error code as "failed to rename". */ return 4; @@@ -698,7 -684,7 +702,7 @@@ static int store_write_section(int fd, if (dot) { strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key); for (i = dot - key + 1; i < store.baselen; i++) { - if (key[i] == '"') + if (key[i] == '"' || key[i] == '\\') strbuf_addch(&sb, '\\'); strbuf_addch(&sb, key[i]); } @@@ -840,7 -826,7 +844,7 @@@ int git_config_set_multivar(const char */ if (last_dot == NULL) { - fprintf(stderr, "key does not contain a section: %s\n", key); + error("key does not contain a section: %s", key); ret = 2; goto out_free; } @@@ -860,14 -846,14 +864,14 @@@ /* Leave the extended basename untouched.. */ if (!dot || i > store.baselen) { if (!iskeychar(c) || (i == store.baselen+1 && !isalpha(c))) { - fprintf(stderr, "invalid key: %s\n", key); + error("invalid key: %s", key); free(store.key); ret = 1; goto out_free; } c = tolower(c); } else if (c == '\n') { - fprintf(stderr, "invalid key (newline): %s\n", key); + error("invalid key (newline): %s", key); free(store.key); ret = 1; goto out_free; @@@ -883,7 -869,7 +887,7 @@@ lock = xcalloc(sizeof(struct lock_file), 1); fd = hold_lock_file_for_update(lock, config_filename, 0); if (fd < 0) { - fprintf(stderr, "could not lock config file\n"); + error("could not lock config file %s", config_filename); free(store.key); ret = -1; goto out_free; @@@ -930,7 -916,8 +934,7 @@@ store.value_regex = (regex_t*)xmalloc(sizeof(regex_t)); if (regcomp(store.value_regex, value_regex, REG_EXTENDED)) { - fprintf(stderr, "Invalid pattern: %s\n", - value_regex); + error("invalid pattern: %s", value_regex); free(store.value_regex); ret = 6; goto out_free; @@@ -948,7 -935,7 +952,7 @@@ * existing config file. */ if (git_config_from_file(store_aux, config_filename)) { - fprintf(stderr, "invalid config file\n"); + error("invalid config file %s", config_filename); free(store.key); if (store.value_regex != NULL) { regfree(store.value_regex); @@@ -1027,7 -1014,7 +1031,7 @@@ } if (commit_lock_file(lock) < 0) { - fprintf(stderr, "Cannot commit config file!\n"); + error("could not commit config file %s", config_filename); ret = 4; goto out_free; } @@@ -1048,7 -1035,7 +1052,7 @@@ out_free return ret; write_err_out: - ret = write_error(); + ret = write_error(lock->filename); goto out_free; } @@@ -1098,7 -1085,7 +1102,7 @@@ int git_config_rename_section(const cha config_filename = xstrdup(config_filename); out_fd = hold_lock_file_for_update(lock, config_filename, 0); if (out_fd < 0) { - ret = error("Could not lock config file!"); + ret = error("could not lock config file %s", config_filename); goto out; } @@@ -1122,7 -1109,7 +1126,7 @@@ } store.baselen = strlen(new_name); if (!store_write_section(out_fd, new_name)) { - ret = write_error(); + ret = write_error(lock->filename); goto out; } continue; @@@ -1133,14 -1120,14 +1137,14 @@@ continue; length = strlen(buf); if (write_in_full(out_fd, buf, length) != length) { - ret = write_error(); + ret = write_error(lock->filename); goto out; } } fclose(config_file); unlock_and_out: if (commit_lock_file(lock) < 0) - ret = error("Cannot commit config file!"); + ret = error("could not commit config file %s", config_filename); out: free(config_filename); return ret; diff --combined environment.c index 55c2527063,1b80036ca5..4fcb471248 --- a/environment.c +++ b/environment.c @@@ -11,10 -11,10 +11,11 @@@ char git_default_email[MAX_GITNAME]; char git_default_name[MAX_GITNAME]; + int user_ident_explicitly_given; int trust_executable_bit = 1; int quote_path_fully = 1; int has_symlinks = 1; +int ignore_case; int assume_unchanged; int prefer_symlink_refs; int is_bare_repository_cfg = -1; /* unspecified */ @@@ -39,7 -39,6 +40,7 @@@ int auto_crlf = 0; /* 1: both ways, -1 enum safe_crlf safe_crlf = SAFE_CRLF_WARN; unsigned whitespace_rule_cfg = WS_DEFAULT_RULE; enum branch_track git_branch_track = BRANCH_TRACK_REMOTE; +enum rebase_setup_type autorebase = AUTOREBASE_NEVER; /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg;