summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c49
-rw-r--r--builtin/apply.c9
-rw-r--r--builtin/blame.c2
-rw-r--r--builtin/checkout.c29
-rw-r--r--builtin/clone.c2
-rw-r--r--builtin/commit.c4
-rw-r--r--builtin/diff-tree.c12
-rw-r--r--builtin/diff.c4
-rw-r--r--builtin/grep.c12
-rw-r--r--builtin/init-db.c10
-rw-r--r--builtin/log.c87
-rw-r--r--builtin/ls-files.c9
-rw-r--r--builtin/ls-tree.c13
-rw-r--r--builtin/merge-base.c3
-rw-r--r--builtin/merge.c66
-rw-r--r--builtin/notes.c30
-rw-r--r--builtin/rerere.c77
-rw-r--r--builtin/rev-list.c10
-rw-r--r--builtin/send-pack.c5
19 files changed, 227 insertions, 206 deletions
diff --git a/builtin/add.c b/builtin/add.c
index d39a6ab930..e57abddf52 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -26,6 +26,27 @@ struct update_callback_data {
int add_errors;
};
+static int fix_unmerged_status(struct diff_filepair *p,
+ struct update_callback_data *data)
+{
+ if (p->status != DIFF_STATUS_UNMERGED)
+ return p->status;
+ if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL) && !p->two->mode)
+ /*
+ * This is not an explicit add request, and the
+ * path is missing from the working tree (deleted)
+ */
+ return DIFF_STATUS_DELETED;
+ else
+ /*
+ * Either an explicit add request, or path exists
+ * in the working tree. An attempt to explicitly
+ * add a path that does not exist in the working tree
+ * will be caught as an error by the caller immediately.
+ */
+ return DIFF_STATUS_MODIFIED;
+}
+
static void update_callback(struct diff_queue_struct *q,
struct diff_options *opt, void *cbdata)
{
@@ -35,30 +56,9 @@ static void update_callback(struct diff_queue_struct *q,
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
const char *path = p->one->path;
- switch (p->status) {
+ switch (fix_unmerged_status(p, data)) {
default:
die(_("unexpected diff status %c"), p->status);
- case DIFF_STATUS_UNMERGED:
- /*
- * ADD_CACHE_IGNORE_REMOVAL is unset if "git
- * add -u" is calling us, In such a case, a
- * missing work tree file needs to be removed
- * if there is an unmerged entry at stage #2,
- * but such a diff record is followed by
- * another with DIFF_STATUS_DELETED (and if
- * there is no stage #2, we won't see DELETED
- * nor MODIFIED). We can simply continue
- * either way.
- */
- if (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))
- continue;
- /*
- * Otherwise, it is "git add path" is asking
- * to explicitly add it; we fall through. A
- * missing work tree file is an error and is
- * caught by add_file_to_index() in such a
- * case.
- */
case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_TYPE_CHANGED:
if (add_file_to_index(&the_index, path, data->flags)) {
@@ -91,6 +91,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
data.flags = flags;
data.add_errors = 0;
rev.diffopt.format_callback_data = &data;
+ rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
return !!data.add_errors;
}
@@ -330,8 +331,8 @@ static struct option builtin_add_options[] = {
static int add_config(const char *var, const char *value, void *cb)
{
- if (!strcasecmp(var, "add.ignoreerrors") ||
- !strcasecmp(var, "add.ignore-errors")) {
+ if (!strcmp(var, "add.ignoreerrors") ||
+ !strcmp(var, "add.ignore-errors")) {
ignore_add_errors = git_config_bool(var, value);
return 0;
}
diff --git a/builtin/apply.c b/builtin/apply.c
index 36e150768b..530d4bb7e7 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -43,6 +43,7 @@ static int apply = 1;
static int apply_in_reverse;
static int apply_with_reject;
static int apply_verbosely;
+static int allow_overlap;
static int no_add;
static const char *fake_ancestor;
static int line_termination = '\n';
@@ -2430,9 +2431,9 @@ static void update_image(struct image *img,
memcpy(img->line + applied_pos,
postimage->line,
postimage->nr * sizeof(*img->line));
- for (i = 0; i < postimage->nr; i++)
- img->line[applied_pos + i].flag |= LINE_PATCHED;
-
+ if (!allow_overlap)
+ for (i = 0; i < postimage->nr; i++)
+ img->line[applied_pos + i].flag |= LINE_PATCHED;
img->nr = nr;
}
@@ -3889,6 +3890,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
"don't expect at least one line of context"),
OPT_BOOLEAN(0, "reject", &apply_with_reject,
"leave the rejected hunks in corresponding *.rej files"),
+ OPT_BOOLEAN(0, "allow-overlap", &allow_overlap,
+ "allow overlapping hunks"),
OPT__VERBOSE(&apply_verbosely, "be verbose"),
OPT_BIT(0, "inaccurate-eof", &options,
"tolerate incorrectly detected missing new-line at the end of file",
diff --git a/builtin/blame.c b/builtin/blame.c
index 4639788178..4242e4b513 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1378,7 +1378,7 @@ static void get_ac_line(const char *inbuf, const char *what,
timepos = tmp;
*tmp = 0;
- while (person < tmp && *tmp != ' ')
+ while (person < tmp && !(*tmp == ' ' && tmp[1] == '<'))
tmp--;
if (tmp <= person)
return;
diff --git a/builtin/checkout.c b/builtin/checkout.c
index eece5d6ac0..4761769512 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -79,7 +79,10 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
static int read_tree_some(struct tree *tree, const char **pathspec)
{
- read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
+ struct pathspec ps;
+ init_pathspec(&ps, pathspec);
+ read_tree_recursive(tree, "", 0, 0, &ps, update_some, NULL);
+ free_pathspec(&ps);
/* update the index with the given tree's info
* for all args, expanding wildcards, and exit
@@ -648,18 +651,30 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
if (more == 1)
describe_one_orphan(&sb, last);
else
- strbuf_addf(&sb, " ... and %d more.\n", more);
+ strbuf_addf(&sb, _(" ... and %d more.\n"), more);
}
fprintf(stderr,
- "Warning: you are leaving %d commit%s behind, "
+ Q_(
+ /* The singular version */
+ "Warning: you are leaving %d commit behind, "
+ "not connected to\n"
+ "any of your branches:\n\n"
+ "%s\n"
+ "If you want to keep it by creating a new branch, "
+ "this may be a good time\nto do so with:\n\n"
+ " git branch new_branch_name %s\n\n",
+ /* The plural version */
+ "Warning: you are leaving %d commits behind, "
"not connected to\n"
"any of your branches:\n\n"
"%s\n"
"If you want to keep them by creating a new branch, "
"this may be a good time\nto do so with:\n\n"
" git branch new_branch_name %s\n\n",
- lost, ((1 < lost) ? "s" : ""),
+ /* Give ngettext() the count */
+ lost),
+ lost,
sb.buf,
sha1_to_hex(commit->object.sha1));
strbuf_release(&sb);
@@ -961,9 +976,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
die (_("--patch is incompatible with all other options"));
if (opts.force_detach && (opts.new_branch || opts.new_orphan_branch))
- die("--detach cannot be used with -b/-B/--orphan");
+ die(_("--detach cannot be used with -b/-B/--orphan"));
if (opts.force_detach && 0 < opts.track)
- die("--detach cannot be used with -t");
+ die(_("--detach cannot be used with -t"));
/* --track without -b should DWIM */
if (0 < opts.track && !opts.new_branch) {
@@ -1043,7 +1058,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
}
if (opts.force_detach)
- die("git checkout: --detach does not take a path argument");
+ die(_("git checkout: --detach does not take a path argument"));
if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));
diff --git a/builtin/clone.c b/builtin/clone.c
index 4144bcf5ca..49c838fd3f 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -417,7 +417,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (path)
repo = xstrdup(absolute_path(repo_name));
else if (!strchr(repo_name, ':'))
- die("repository '%s' does not exist", repo_name);
+ die(_("repository '%s' does not exist"), repo_name);
else
repo = repo_name;
is_local = path && !is_bundle;
diff --git a/builtin/commit.c b/builtin/commit.c
index 67757e999f..411d5e4153 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -615,6 +615,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
const char *hook_arg1 = NULL;
const char *hook_arg2 = NULL;
int ident_shown = 0;
+ int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
return 0;
@@ -681,6 +682,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (strbuf_read_file(&sb, template_file, 0) < 0)
die_errno(_("could not read '%s'"), template_file);
hook_arg1 = "template";
+ clean_message_contents = 0;
}
/*
@@ -708,7 +710,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (s->fp == NULL)
die_errno(_("could not open '%s'"), git_path(commit_editmsg));
- if (cleanup_mode != CLEANUP_NONE)
+ if (clean_message_contents)
stripspace(&sb, 0);
if (signoff) {
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 0d2a3e9fa2..be6417d166 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -163,6 +163,9 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
}
if (read_stdin) {
+ int saved_nrl = 0;
+ int saved_dcctc = 0;
+
if (opt->diffopt.detect_rename)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
DIFF_SETUP_USE_CACHE);
@@ -173,9 +176,16 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
fputs(line, stdout);
fflush(stdout);
}
- else
+ else {
diff_tree_stdin(line);
+ if (saved_nrl < opt->diffopt.needed_rename_limit)
+ saved_nrl = opt->diffopt.needed_rename_limit;
+ if (opt->diffopt.degraded_cc_to_c)
+ saved_dcctc = 1;
+ }
}
+ opt->diffopt.degraded_cc_to_c = saved_dcctc;
+ opt->diffopt.needed_rename_limit = saved_nrl;
}
return diff_result_code(&opt->diffopt, 0);
diff --git a/builtin/diff.c b/builtin/diff.c
index 717fa1a341..14bd14fce0 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -202,7 +202,6 @@ static void refresh_index_quietly(void)
static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv)
{
- int result;
unsigned int options = 0;
while (1 < argc && argv[1][0] == '-') {
@@ -236,8 +235,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
perror("read_cache_preload");
return -1;
}
- result = run_diff_files(revs, options);
- return diff_result_code(&revs->diffopt, result);
+ return run_diff_files(revs, options);
}
int cmd_diff(int argc, const char **argv, const char *prefix)
diff --git a/builtin/grep.c b/builtin/grep.c
index 10a1f65310..3ee2ec51de 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -533,18 +533,18 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len)
{
- int hit = 0, matched = 0;
+ int hit = 0, match = 0;
struct name_entry entry;
int old_baselen = base->len;
while (tree_entry(tree, &entry)) {
int te_len = tree_entry_len(entry.path, entry.sha1);
- if (matched != 2) {
- matched = tree_entry_interesting(&entry, base, tn_len, pathspec);
- if (matched == -1)
- break; /* no more matches */
- if (!matched)
+ if (match != 2) {
+ match = tree_entry_interesting(&entry, base, tn_len, pathspec);
+ if (match < 0)
+ break;
+ if (match == 0)
continue;
}
diff --git a/builtin/init-db.c b/builtin/init-db.c
index b7370d9bb8..ba13a54793 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -319,10 +319,10 @@ int set_git_dir_init(const char *git_dir, const char *real_git_dir,
struct stat st;
if (!exist_ok && !stat(git_dir, &st))
- die("%s already exists", git_dir);
+ die(_("%s already exists"), git_dir);
if (!exist_ok && !stat(real_git_dir, &st))
- die("%s already exists", real_git_dir);
+ die(_("%s already exists"), real_git_dir);
/*
* make sure symlinks are resolved because we'll be
@@ -351,15 +351,15 @@ static void separate_git_dir(const char *git_dir)
else if (S_ISDIR(st.st_mode))
src = git_link;
else
- die("unable to handle file type %d", st.st_mode);
+ die(_("unable to handle file type %d"), st.st_mode);
if (rename(src, git_dir))
- die_errno("unable to move %s to %s", src, git_dir);
+ die_errno(_("unable to move %s to %s"), src, git_dir);
}
fp = fopen(git_link, "w");
if (!fp)
- die("Could not create git link %s", git_link);
+ die(_("Could not create git link %s"), git_link);
fprintf(fp, "gitdir: %s\n", git_dir);
fclose(fp);
}
diff --git a/builtin/log.c b/builtin/log.c
index c6dce9b895..f6219909a7 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -25,12 +25,15 @@ static const char *default_date_mode = NULL;
static int default_show_root = 1;
static int decoration_style;
+static int decoration_given;
static const char *fmt_patch_subject_prefix = "PATCH";
static const char *fmt_pretty;
-static const char * const builtin_log_usage =
+static const char * const builtin_log_usage[] = {
"git log [<options>] [<since>..<until>] [[--] <path>...]\n"
- " or: git show [options] <object>...";
+ " or: git show [options] <object>...",
+ NULL
+};
static int parse_decoration_style(const char *var, const char *value)
{
@@ -49,6 +52,23 @@ static int parse_decoration_style(const char *var, const char *value)
return -1;
}
+static int decorate_callback(const struct option *opt, const char *arg, int unset)
+{
+ if (unset)
+ decoration_style = 0;
+ else if (arg)
+ decoration_style = parse_decoration_style("command line", arg);
+ else
+ decoration_style = DECORATE_SHORT_REFS;
+
+ if (decoration_style < 0)
+ die("invalid --decorate option: %s", arg);
+
+ decoration_given = 1;
+
+ return 0;
+}
+
static void cmd_log_init_defaults(struct rev_info *rev)
{
rev->abbrev = DEFAULT_ABBREV;
@@ -68,17 +88,28 @@ static void cmd_log_init_defaults(struct rev_info *rev)
static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
struct rev_info *rev, struct setup_revision_opt *opt)
{
- int i;
- int decoration_given = 0;
struct userformat_want w;
- /*
- * Check for -h before setup_revisions(), or "git log -h" will
- * fail when run without a git directory.
- */
- if (argc == 2 && !strcmp(argv[1], "-h"))
- usage(builtin_log_usage);
+ int quiet = 0, source = 0;
+
+ const struct option builtin_log_options[] = {
+ OPT_BOOLEAN(0, "quiet", &quiet, "supress diff output"),
+ OPT_BOOLEAN(0, "source", &source, "show source"),
+ { OPTION_CALLBACK, 0, "decorate", NULL, NULL, "decorate options",
+ PARSE_OPT_OPTARG, decorate_callback},
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, prefix,
+ builtin_log_options, builtin_log_usage,
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
+ PARSE_OPT_KEEP_DASHDASH);
+
argc = setup_revisions(argc, argv, rev, opt);
+ /* Any arguments at this point are not recognized */
+ if (argc > 1)
+ die("unrecognized argument: %s", argv[1]);
+
memset(&w, 0, sizeof(w));
userformat_find_requirements(NULL, &w);
@@ -94,26 +125,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
if (rev->diffopt.pathspec.nr != 1)
usage("git logs can only follow renames on one pathname at a time");
}
- for (i = 1; i < argc; i++) {
- const char *arg = argv[i];
- if (!strcmp(arg, "--decorate")) {
- decoration_style = DECORATE_SHORT_REFS;
- decoration_given = 1;
- } else if (!prefixcmp(arg, "--decorate=")) {
- const char *v = skip_prefix(arg, "--decorate=");
- decoration_style = parse_decoration_style(arg, v);
- if (decoration_style < 0)
- die(_("invalid --decorate option: %s"), arg);
- decoration_given = 1;
- } else if (!strcmp(arg, "--no-decorate")) {
- decoration_style = 0;
- } else if (!strcmp(arg, "--source")) {
- rev->show_source = 1;
- } else if (!strcmp(arg, "-h")) {
- usage(builtin_log_usage);
- } else
- die(_("unrecognized argument: %s"), arg);
- }
+
+ if (source)
+ rev->show_source = 1;
/*
* defeat log.decorate configuration interacting with --pretty=raw
@@ -256,6 +270,8 @@ static void finish_early_output(struct rev_info *rev)
static int cmd_log_walk(struct rev_info *rev)
{
struct commit *commit;
+ int saved_nrl = 0;
+ int saved_dcctc = 0;
if (rev->early_output)
setup_early_output(rev);
@@ -286,7 +302,14 @@ static int cmd_log_walk(struct rev_info *rev)
}
free_commit_list(commit->parents);
commit->parents = NULL;
+ if (saved_nrl < rev->diffopt.needed_rename_limit)
+ saved_nrl = rev->diffopt.needed_rename_limit;
+ if (rev->diffopt.degraded_cc_to_c)
+ saved_dcctc = 1;
}
+ rev->diffopt.degraded_cc_to_c = saved_dcctc;
+ rev->diffopt.needed_rename_limit = saved_nrl;
+
if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
return 02;
@@ -405,6 +428,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
struct rev_info rev;
struct object_array_entry *objects;
struct setup_revision_opt opt;
+ struct pathspec match_all;
int i, count, ret = 0;
git_config(git_log_config, NULL);
@@ -412,6 +436,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;
+ init_pathspec(&match_all, NULL);
init_revisions(&rev, prefix);
rev.diff = 1;
rev.always_show_header = 1;
@@ -458,7 +483,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
name,
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
- read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
+ read_tree_recursive((struct tree *)o, "", 0, 0, &match_all,
show_tree_object, NULL);
rev.shown_one = 1;
break;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index fb2d5f4b1f..15701233e2 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -338,7 +338,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
{
struct tree *tree;
unsigned char sha1[20];
- const char **match;
+ struct pathspec pathspec;
struct cache_entry *last_stage0 = NULL;
int i;
@@ -360,10 +360,11 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
static const char *(matchbuf[2]);
matchbuf[0] = prefix;
matchbuf[1] = NULL;
- match = matchbuf;
+ init_pathspec(&pathspec, matchbuf);
+ pathspec.items[0].use_wildcard = 0;
} else
- match = NULL;
- if (read_tree(tree, 1, match))
+ init_pathspec(&pathspec, NULL);
+ if (read_tree(tree, 1, &pathspec))
die("unable to read tree entries %s", tree_name);
for (i = 0; i < active_nr; i++) {
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index f73e6bd962..f08c5b0c94 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -19,7 +19,7 @@ static int line_termination = '\n';
#define LS_SHOW_SIZE 16
static int abbrev;
static int ls_options;
-static const char **pathspec;
+static struct pathspec pathspec;
static int chomp_prefix;
static const char *ls_tree_prefix;
@@ -35,7 +35,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
if (ls_options & LS_RECURSIVE)
return 1;
- s = pathspec;
+ s = pathspec.raw;
if (!s)
return 0;
@@ -120,7 +120,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
{
unsigned char sha1[20];
struct tree *tree;
- int full_tree = 0;
+ int i, full_tree = 0;
const struct option ls_tree_options[] = {
OPT_BIT('d', NULL, &ls_options, "only show trees",
LS_TREE_ONLY),
@@ -166,11 +166,14 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
if (get_sha1(argv[0], sha1))
die("Not a valid object name %s", argv[0]);
- pathspec = get_pathspec(prefix, argv + 1);
+ init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
+ for (i = 0; i < pathspec.nr; i++)
+ pathspec.items[i].use_wildcard = 0;
+ pathspec.has_wildcard = 0;
tree = parse_tree_indirect(sha1);
if (!tree)
die("not a tree object");
- read_tree_recursive(tree, "", 0, 0, pathspec, show_tree, NULL);
+ read_tree_recursive(tree, "", 0, 0, &pathspec, show_tree, NULL);
return 0;
}
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index 96dd160731..4f30f1b0c8 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -23,7 +23,8 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
}
static const char * const merge_base_usage[] = {
- "git merge-base [-a|--all] [--octopus] <commit> <commit>...",
+ "git merge-base [-a|--all] <commit> <commit>...",
+ "git merge-base [-a|--all] --octopus <commit>...",
"git merge-base --independent <commit>...",
NULL
};
diff --git a/builtin/merge.c b/builtin/merge.c
index 0bdd19a137..7eebb71491 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -56,6 +56,7 @@ static size_t use_strategies_nr, use_strategies_alloc;
static const char **xopts;
static size_t xopts_nr, xopts_alloc;
static const char *branch;
+static char *branch_mergeoptions;
static int option_renormalize;
static int verbosity;
static int allow_rerere_auto;
@@ -503,26 +504,34 @@ cleanup:
strbuf_release(&bname);
}
+static void parse_branch_merge_options(char *bmo)
+{
+ const char **argv;
+ int argc;
+
+ if (!bmo)
+ return;
+ argc = split_cmdline(bmo, &argv);
+ if (argc < 0)
+ die(_("Bad branch.%s.mergeoptions string: %s"), branch,
+ split_cmdline_strerror(argc));
+ argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
+ memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
+ argc++;
+ argv[0] = "branch.*.mergeoptions";
+ parse_options(argc, argv, NULL, builtin_merge_options,
+ builtin_merge_usage, 0);
+ free(argv);
+}
+
static int git_merge_config(const char *k, const char *v, void *cb)
{
if (branch && !prefixcmp(k, "branch.") &&
!prefixcmp(k + 7, branch) &&
!strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
- const char **argv;
- int argc;
- char *buf;
-
- buf = xstrdup(v);
- argc = split_cmdline(buf, &argv);
- if (argc < 0)
- die(_("Bad branch.%s.mergeoptions string: %s"), branch,
- split_cmdline_strerror(argc));
- argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
- memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
- argc++;
- parse_options(argc, argv, NULL, builtin_merge_options,
- builtin_merge_usage, 0);
- free(buf);
+ free(branch_mergeoptions);
+ branch_mergeoptions = xstrdup(v);
+ return 0;
}
if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat"))
@@ -541,6 +550,15 @@ static int git_merge_config(const char *k, const char *v, void *cb)
if (is_bool && shortlog_len)
shortlog_len = DEFAULT_MERGE_LOG_LEN;
return 0;
+ } else if (!strcmp(k, "merge.ff")) {
+ int boolval = git_config_maybe_bool(k, v);
+ if (0 <= boolval) {
+ allow_fast_forward = boolval;
+ } else if (v && !strcmp(v, "only")) {
+ allow_fast_forward = 1;
+ fast_forward_only = 1;
+ } /* do not barf on values from future versions of git */
+ return 0;
} else if (!strcmp(k, "merge.defaulttoupstream")) {
default_to_upstream = git_config_bool(k, v);
return 0;
@@ -822,7 +840,7 @@ static void read_merge_msg(void)
{
strbuf_reset(&merge_msg);
if (strbuf_read_file(&merge_msg, git_path("MERGE_MSG"), 0) < 0)
- die_errno("Could not read from '%s'", git_path("MERGE_MSG"));
+ die_errno(_("Could not read from '%s'"), git_path("MERGE_MSG"));
}
static void run_prepare_commit_msg(void)
@@ -962,16 +980,16 @@ static int setup_with_upstream(const char ***argv)
const char **args;
if (!branch)
- die("No current branch.");
+ die(_("No current branch."));
if (!branch->remote)
- die("No remote for the current branch.");
+ die(_("No remote for the current branch."));
if (!branch->merge_nr)
- die("No default upstream defined for the current branch.");
+ die(_("No default upstream defined for the current branch."));
args = xcalloc(branch->merge_nr + 1, sizeof(char *));
for (i = 0; i < branch->merge_nr; i++) {
if (!branch->merge[i]->dst)
- die("No remote tracking branch for %s from %s",
+ die(_("No remote tracking branch for %s from %s"),
branch->merge[i]->src, branch->remote_name);
args[i] = branch->merge[i]->dst;
}
@@ -1010,6 +1028,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;
+ if (branch_mergeoptions)
+ parse_branch_merge_options(branch_mergeoptions);
argc = parse_options(argc, argv, prefix, builtin_merge_options,
builtin_merge_usage, 0);
@@ -1043,10 +1063,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
}
if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
if (advice_resolve_conflict)
- die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
- "Please, commit your changes before you can merge.");
+ die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
+ "Please, commit your changes before you can merge."));
else
- die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).");
+ die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."));
}
resolve_undo_clear();
diff --git a/builtin/notes.c b/builtin/notes.c
index d6dcfcb014..1fb1f73439 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -100,16 +100,6 @@ struct msg_arg {
struct strbuf buf;
};
-static void expand_notes_ref(struct strbuf *sb)
-{
- if (!prefixcmp(sb->buf, "refs/notes/"))
- return; /* we're happy */
- else if (!prefixcmp(sb->buf, "notes/"))
- strbuf_insert(sb, 0, "refs/", 5);
- else
- strbuf_insert(sb, 0, "refs/notes/", 11);
-}
-
static int list_each_note(const unsigned char *object_sha1,
const unsigned char *note_sha1, char *note_path,
void *cb_data)
@@ -529,6 +519,8 @@ static int list(int argc, const char **argv, const char *prefix)
return retval;
}
+static int append_edit(int argc, const char **argv, const char *prefix);
+
static int add(int argc, const char **argv, const char *prefix)
{
int retval = 0, force = 0;
@@ -556,14 +548,14 @@ static int add(int argc, const char **argv, const char *prefix)
};
argc = parse_options(argc, argv, prefix, options, git_notes_add_usage,
- 0);
+ PARSE_OPT_KEEP_ARGV0);
- if (1 < argc) {
+ if (2 < argc) {
error(_("too many parameters"));
usage_with_options(git_notes_add_usage, options);
}
- object_ref = argc ? argv[0] : "HEAD";
+ object_ref = argc > 1 ? argv[1] : "HEAD";
if (get_sha1(object_ref, object))
die(_("Failed to resolve '%s' as a valid ref."), object_ref);
@@ -573,6 +565,18 @@ static int add(int argc, const char **argv, const char *prefix)
if (note) {
if (!force) {
+ if (!msg.given) {
+ /*
+ * Redirect to "edit" subcommand.
+ *
+ * We only end up here if none of -m/-F/-c/-C
+ * or -f are given. The original args are
+ * therefore still in argv[0-1].
+ */
+ argv[0] = "edit";
+ free_notes(t);
+ return append_edit(argc, argv, prefix);
+ }
retval = error(_("Cannot add notes. Found existing notes "
"for object %s. Use '-f' to overwrite "
"existing notes"), sha1_to_hex(object));
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 82358855d1..08213c7c0b 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -12,74 +12,6 @@ static const char * const rerere_usage[] = {
NULL,
};
-/* these values are days */
-static int cutoff_noresolve = 15;
-static int cutoff_resolve = 60;
-
-static time_t rerere_created_at(const char *name)
-{
- struct stat st;
- return stat(rerere_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime;
-}
-
-static time_t rerere_last_used_at(const char *name)
-{
- struct stat st;
- return stat(rerere_path(name, "postimage"), &st) ? (time_t) 0 : st.st_mtime;
-}
-
-static void unlink_rr_item(const char *name)
-{
- unlink(rerere_path(name, "thisimage"));
- unlink(rerere_path(name, "preimage"));
- unlink(rerere_path(name, "postimage"));
- rmdir(git_path("rr-cache/%s", name));
-}
-
-static int git_rerere_gc_config(const char *var, const char *value, void *cb)
-{
- if (!strcmp(var, "gc.rerereresolved"))
- cutoff_resolve = git_config_int(var, value);
- else if (!strcmp(var, "gc.rerereunresolved"))
- cutoff_noresolve = git_config_int(var, value);
- else
- return git_default_config(var, value, cb);
- return 0;
-}
-
-static void garbage_collect(struct string_list *rr)
-{
- struct string_list to_remove = STRING_LIST_INIT_DUP;
- DIR *dir;
- struct dirent *e;
- int i, cutoff;
- time_t now = time(NULL), then;
-
- git_config(git_rerere_gc_config, NULL);
- dir = opendir(git_path("rr-cache"));
- if (!dir)
- die_errno("unable to open rr-cache directory");
- while ((e = readdir(dir))) {
- if (is_dot_or_dotdot(e->d_name))
- continue;
-
- then = rerere_last_used_at(e->d_name);
- if (then) {
- cutoff = cutoff_resolve;
- } else {
- then = rerere_created_at(e->d_name);
- if (!then)
- continue;
- cutoff = cutoff_noresolve;
- }
- if (then < now - cutoff * 86400)
- string_list_append(&to_remove, e->d_name);
- }
- for (i = 0; i < to_remove.nr; i++)
- unlink_rr_item(to_remove.items[i].string);
- string_list_clear(&to_remove, 0);
-}
-
static int outf(void *dummy, mmbuffer_t *ptr, int nbuf)
{
int i;
@@ -148,14 +80,9 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
return 0;
if (!strcmp(argv[0], "clear")) {
- for (i = 0; i < merge_rr.nr; i++) {
- const char *name = (const char *)merge_rr.items[i].util;
- if (!has_rerere_resolution(name))
- unlink_rr_item(name);
- }
- unlink_or_warn(git_path("MERGE_RR"));
+ rerere_clear(&merge_rr);
} else if (!strcmp(argv[0], "gc"))
- garbage_collect(&merge_rr);
+ rerere_gc(&merge_rr);
else if (!strcmp(argv[0], "status"))
for (i = 0; i < merge_rr.nr; i++)
printf("%s\n", merge_rr.items[i].string);
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 9bfb94201f..4be66998f6 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -55,7 +55,9 @@ static void show_commit(struct commit *commit, void *data)
graph_show_commit(revs->graph);
if (revs->count) {
- if (commit->object.flags & SYMMETRIC_LEFT)
+ if (commit->object.flags & PATCHSAME)
+ revs->count_same++;
+ else if (commit->object.flags & SYMMETRIC_LEFT)
revs->count_left++;
else
revs->count_right++;
@@ -406,8 +408,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
&info);
if (revs.count) {
- if (revs.left_right)
+ if (revs.left_right && revs.cherry_mark)
+ printf("%d\t%d\t%d\n", revs.count_left, revs.count_right, revs.count_same);
+ else if (revs.left_right)
printf("%d\t%d\n", revs.count_left, revs.count_right);
+ else if (revs.cherry_mark)
+ printf("%d\t%d\n", revs.count_left + revs.count_right, revs.count_same);
else
printf("%d\n", revs.count_left + revs.count_right);
}
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 8b0911c0d2..4ac2ca984f 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -229,6 +229,9 @@ static void print_helper_status(struct ref *ref)
static int sideband_demux(int in, int out, void *data)
{
int *fd = data;
+#ifdef NO_PTHREADS
+ close(fd[1]);
+#endif
int ret = recv_sideband("send-pack", fd[0], out);
close(out);
return ret;
@@ -339,6 +342,8 @@ int send_pack(struct send_pack_args *args,
if (pack_objects(out, remote_refs, extra_have, args) < 0) {
for (ref = remote_refs; ref; ref = ref->next)
ref->status = REF_STATUS_NONE;
+ if (args->stateless_rpc)
+ close(out);
if (use_sideband)
finish_async(&demux);
return -1;