aboutsummaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/blame.c4
-rw-r--r--builtin/checkout.c31
-rw-r--r--builtin/clone.c3
-rw-r--r--builtin/commit.c28
-rw-r--r--builtin/fmt-merge-msg.c76
-rw-r--r--builtin/for-each-ref.c4
-rw-r--r--builtin/grep.c8
-rw-r--r--builtin/ls-files.c75
-rw-r--r--builtin/ls-remote.c10
-rw-r--r--builtin/merge-file.c2
-rw-r--r--builtin/merge-tree.c2
-rw-r--r--builtin/merge.c20
-rw-r--r--builtin/notes.c15
-rw-r--r--builtin/pack-objects.c6
-rw-r--r--builtin/remote.c102
-rw-r--r--builtin/rerere.c2
16 files changed, 277 insertions, 111 deletions
diff --git a/builtin/blame.c b/builtin/blame.c
index fc1586350..8506286dd 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -39,7 +39,7 @@ static int show_root;
static int reverse;
static int blank_boundary;
static int incremental;
-static int xdl_opts = XDF_NEED_MINIMAL;
+static int xdl_opts;
static enum date_mode blame_date_mode = DATE_ISO8601;
static size_t blame_date_width;
@@ -1589,7 +1589,7 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent)
strcpy(hex, sha1_to_hex(suspect->commit->object.sha1));
printf("%s%c%d %d %d\n",
hex,
- ent->guilty ? ' ' : '*', // purely for debugging
+ ent->guilty ? ' ' : '*', /* purely for debugging */
ent->s_lno + 1,
ent->lno + 1,
ent->num_lines);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index c3825219c..72e4fbc72 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -493,7 +493,24 @@ static void update_refs_for_switch(struct checkout_opts *opts,
struct strbuf msg = STRBUF_INIT;
const char *old_desc;
if (opts->new_branch) {
- if (!opts->new_orphan_branch)
+ if (opts->new_orphan_branch) {
+ if (opts->new_branch_log && !log_all_ref_updates) {
+ int temp;
+ char log_file[PATH_MAX];
+ char *ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch);
+
+ temp = log_all_ref_updates;
+ log_all_ref_updates = 1;
+ if (log_ref_setup(ref_name, log_file, sizeof(log_file))) {
+ fprintf(stderr, "Can not do reflog for '%s'\n",
+ opts->new_orphan_branch);
+ log_all_ref_updates = temp;
+ return;
+ }
+ log_all_ref_updates = temp;
+ }
+ }
+ else
create_branch(old->name, opts->new_branch, new->name, 0,
opts->new_branch_log, opts->track);
new->name = opts->new_branch;
@@ -517,6 +534,14 @@ static void update_refs_for_switch(struct checkout_opts *opts,
opts->new_branch ? " a new" : "",
new->name);
}
+ if (old->path && old->name) {
+ char log_file[PATH_MAX], ref_file[PATH_MAX];
+
+ git_snpath(log_file, sizeof(log_file), "logs/%s", old->path);
+ git_snpath(ref_file, sizeof(ref_file), "%s", old->path);
+ if (!file_exists(ref_file) && file_exists(log_file))
+ remove_path(log_file);
+ }
} else if (strcmp(new->name, "HEAD")) {
update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
REF_NODEREF, DIE_ON_ERR);
@@ -684,8 +709,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
if (opts.new_orphan_branch) {
if (opts.new_branch)
die("--orphan and -b are mutually exclusive");
- if (opts.track > 0 || opts.new_branch_log)
- die("--orphan cannot be used with -t or -l");
+ if (opts.track > 0)
+ die("--orphan cannot be used with -t");
opts.new_branch = opts.new_orphan_branch;
}
diff --git a/builtin/clone.c b/builtin/clone.c
index 445792242..efb1e6faa 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -464,7 +464,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
set_git_dir(make_absolute_path(git_dir));
if (0 <= option_verbosity)
- printf("Cloning into %s...\n", get_git_dir());
+ printf("Cloning into %s%s...\n",
+ option_bare ? "bare repository " : "", dir);
init_db(option_template, INIT_DB_QUIET);
/*
diff --git a/builtin/commit.c b/builtin/commit.c
index ddf77e48e..a86168664 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -93,6 +93,7 @@ static enum {
STATUS_FORMAT_SHORT,
STATUS_FORMAT_PORCELAIN,
} status_format = STATUS_FORMAT_LONG;
+static int status_show_branch;
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
{
@@ -134,6 +135,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
OPT_SET_INT(0, "short", &status_format, "show status concisely",
STATUS_FORMAT_SHORT),
+ OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"),
OPT_SET_INT(0, "porcelain", &status_format,
"show porcelain output format", STATUS_FORMAT_PORCELAIN),
OPT_BOOLEAN('z', "null", &null_termination,
@@ -424,7 +426,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
switch (status_format) {
case STATUS_FORMAT_SHORT:
- wt_shortstatus_print(s, null_termination);
+ wt_shortstatus_print(s, null_termination, status_show_branch);
break;
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s, null_termination);
@@ -462,15 +464,21 @@ static void determine_author_info(void)
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)
+ lb = strchrnul(a + strlen("\nauthor "), '<');
+ rb = strchrnul(lb, '>');
+ eol = strchrnul(rb, '\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 (lb == a + strlen("\nauthor "))
+ /* \nauthor <foo@example.com> */
+ name = xcalloc(1, 1);
+ else
+ name = xmemdupz(a + strlen("\nauthor "),
+ (lb - strlen(" ") -
+ (a + strlen("\nauthor "))));
+ email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
+ date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
}
if (force_author) {
@@ -1030,6 +1038,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
OPT__VERBOSE(&verbose),
OPT_SET_INT('s', "short", &status_format,
"show status concisely", STATUS_FORMAT_SHORT),
+ OPT_BOOLEAN('b', "branch", &status_show_branch,
+ "show branch information"),
OPT_SET_INT(0, "porcelain", &status_format,
"show porcelain output format",
STATUS_FORMAT_PORCELAIN),
@@ -1082,7 +1092,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
switch (status_format) {
case STATUS_FORMAT_SHORT:
- wt_shortstatus_print(&s, null_termination);
+ wt_shortstatus_print(&s, null_termination, status_show_branch);
break;
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(&s, null_termination);
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 379a03131..44204257c 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -202,35 +202,10 @@ static void shortlog(const char *name, unsigned char *sha1,
string_list_clear(&subjects, 0);
}
-int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
- int limit = 20, i = 0, pos = 0;
+static void do_fmt_merge_msg_title(struct strbuf *out,
+ const char *current_branch) {
+ int i = 0;
char *sep = "";
- unsigned char head_sha1[20];
- const char *current_branch;
-
- /* get current branch */
- current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
- if (!current_branch)
- die("No current branch");
- if (!prefixcmp(current_branch, "refs/heads/"))
- current_branch += 11;
-
- /* get a line */
- while (pos < in->len) {
- int len;
- char *newline, *p = in->buf + pos;
-
- newline = strchr(p, '\n');
- len = newline ? newline - p : strlen(p);
- pos += len + !!newline;
- i++;
- p[len] = 0;
- if (handle_line(p))
- die ("Error in line %d: %.*s", i, len, p);
- }
-
- if (!srcs.nr)
- return 0;
strbuf_addstr(out, "Merge ");
for (i = 0; i < srcs.nr; i++) {
@@ -278,6 +253,40 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
strbuf_addch(out, '\n');
else
strbuf_addf(out, " into %s\n", current_branch);
+}
+
+static int do_fmt_merge_msg(int merge_title, int merge_summary,
+ struct strbuf *in, struct strbuf *out) {
+ int limit = 20, i = 0, pos = 0;
+ unsigned char head_sha1[20];
+ const char *current_branch;
+
+ /* get current branch */
+ current_branch = resolve_ref("HEAD", head_sha1, 1, NULL);
+ if (!current_branch)
+ die("No current branch");
+ if (!prefixcmp(current_branch, "refs/heads/"))
+ current_branch += 11;
+
+ /* get a line */
+ while (pos < in->len) {
+ int len;
+ char *newline, *p = in->buf + pos;
+
+ newline = strchr(p, '\n');
+ len = newline ? newline - p : strlen(p);
+ pos += len + !!newline;
+ i++;
+ p[len] = 0;
+ if (handle_line(p))
+ die ("Error in line %d: %.*s", i, len, p);
+ }
+
+ if (!srcs.nr)
+ return 0;
+
+ if (merge_title)
+ do_fmt_merge_msg_title(out, current_branch);
if (merge_summary) {
struct commit *head;
@@ -289,6 +298,9 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
rev.ignore_merges = 1;
rev.limited = 1;
+ if (suffixcmp(out->buf, "\n"))
+ strbuf_addch(out, '\n');
+
for (i = 0; i < origins.nr; i++)
shortlog(origins.items[i].string, origins.items[i].util,
head, &rev, limit, out);
@@ -296,6 +308,14 @@ int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
return 0;
}
+int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out) {
+ return do_fmt_merge_msg(1, merge_summary, in, out);
+}
+
+int fmt_merge_msg_shortlog(struct strbuf *in, struct strbuf *out) {
+ return do_fmt_merge_msg(0, 1, in, out);
+}
+
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
{
const char *inpath = NULL;
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 3a9795317..a2b28c696 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -552,10 +552,10 @@ static void grab_values(struct atom_value *val, int deref, struct object *obj, v
grab_person("committer", val, deref, obj, buf, sz);
break;
case OBJ_TREE:
- // grab_tree_values(val, deref, obj, buf, sz);
+ /* grab_tree_values(val, deref, obj, buf, sz); */
break;
case OBJ_BLOB:
- // grab_blob_values(val, deref, obj, buf, sz);
+ /* grab_blob_values(val, deref, obj, buf, sz); */
break;
default:
die("Eh? Object of type %d?", obj->type);
diff --git a/builtin/grep.c b/builtin/grep.c
index b194ea3ce..d0a73da07 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -724,11 +724,15 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
if (!patterns)
die_errno("cannot open '%s'", arg);
while (strbuf_getline(&sb, patterns, '\n') == 0) {
+ char *s;
+ size_t len;
+
/* ignore empty line like grep does */
if (sb.len == 0)
continue;
- append_grep_pattern(grep_opt, strbuf_detach(&sb, NULL), arg,
- ++lno, GREP_PATTERN);
+
+ s = strbuf_detach(&sb, &len);
+ append_grep_pat(grep_opt, s, len, arg, ++lno, GREP_PATTERN);
}
fclose(patterns);
strbuf_release(&sb);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c0fbcdcf4..080404769 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -26,8 +26,9 @@ static int show_killed;
static int show_valid_bit;
static int line_terminator = '\n';
+static const char *prefix;
+static int max_prefix_len;
static int prefix_len;
-static int prefix_offset;
static const char **pathspec;
static int error_unmatch;
static char *ps_matched;
@@ -43,10 +44,15 @@ static const char *tag_modified = "";
static const char *tag_skip_worktree = "";
static const char *tag_resolve_undo = "";
+static void write_name(const char* name, size_t len)
+{
+ write_name_quoted_relative(name, len, prefix, prefix_len, stdout,
+ line_terminator);
+}
+
static void show_dir_entry(const char *tag, struct dir_entry *ent)
{
- int len = prefix_len;
- int offset = prefix_offset;
+ int len = max_prefix_len;
if (len >= ent->len)
die("git ls-files: internal error - directory entry not superset of prefix");
@@ -55,7 +61,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
return;
fputs(tag, stdout);
- write_name_quoted(ent->name + offset, stdout, line_terminator);
+ write_name(ent->name, ent->len);
}
static void show_other_files(struct dir_struct *dir)
@@ -121,8 +127,7 @@ static void show_killed_files(struct dir_struct *dir)
static void show_ce_entry(const char *tag, struct cache_entry *ce)
{
- int len = prefix_len;
- int offset = prefix_offset;
+ int len = max_prefix_len;
if (len >= ce_namelen(ce))
die("git ls-files: internal error - cache entry not superset of prefix");
@@ -156,20 +161,19 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
find_unique_abbrev(ce->sha1,abbrev),
ce_stage(ce));
}
- write_name_quoted(ce->name + offset, stdout, line_terminator);
+ write_name(ce->name, ce_namelen(ce));
}
static int show_one_ru(struct string_list_item *item, void *cbdata)
{
- int offset = prefix_offset;
const char *path = item->string;
struct resolve_undo_info *ui = item->util;
int i, len;
len = strlen(path);
- if (len < prefix_len)
+ if (len < max_prefix_len)
return 0; /* outside of the prefix */
- if (!match_pathspec(pathspec, path, len, prefix_len, ps_matched))
+ if (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched))
return 0; /* uninterested */
for (i = 0; i < 3; i++) {
if (!ui->mode[i])
@@ -177,19 +181,19 @@ static int show_one_ru(struct string_list_item *item, void *cbdata)
printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
find_unique_abbrev(ui->sha1[i], abbrev),
i + 1);
- write_name_quoted(path + offset, stdout, line_terminator);
+ write_name(path, len);
}
return 0;
}
-static void show_ru_info(const char *prefix)
+static void show_ru_info(void)
{
if (!the_index.resolve_undo)
return;
for_each_string_list(show_one_ru, the_index.resolve_undo, NULL);
}
-static void show_files(struct dir_struct *dir, const char *prefix)
+static void show_files(struct dir_struct *dir)
{
int i;
@@ -243,7 +247,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
*/
static void prune_cache(const char *prefix)
{
- int pos = cache_name_pos(prefix, prefix_len);
+ int pos = cache_name_pos(prefix, max_prefix_len);
unsigned int first, last;
if (pos < 0)
@@ -256,7 +260,7 @@ static void prune_cache(const char *prefix)
while (last > first) {
int next = (last + first) >> 1;
struct cache_entry *ce = active_cache[next];
- if (!strncmp(ce->name, prefix, prefix_len)) {
+ if (!strncmp(ce->name, prefix, max_prefix_len)) {
first = next+1;
continue;
}
@@ -265,11 +269,16 @@ static void prune_cache(const char *prefix)
active_nr = last;
}
-static const char *verify_pathspec(const char *prefix)
+static const char *pathspec_prefix(const char *prefix)
{
const char **p, *n, *prev;
unsigned long max;
+ if (!pathspec) {
+ max_prefix_len = prefix ? strlen(prefix) : 0;
+ return prefix;
+ }
+
prev = NULL;
max = PATH_MAX;
for (p = pathspec; (n = *p) != NULL; p++) {
@@ -291,10 +300,7 @@ static const char *verify_pathspec(const char *prefix)
}
}
- if (prefix_offset > max || memcmp(prev, prefix, prefix_offset))
- die("git ls-files: cannot generate relative filenames containing '..'");
-
- prefix_len = max;
+ max_prefix_len = max;
return max ? xmemdupz(prev, max) : NULL;
}
@@ -374,7 +380,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
}
}
-int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset)
+int report_path_error(const char *ps_matched, const char **pathspec, int prefix_len)
{
/*
* Make sure all pathspec matched; otherwise it is an error.
@@ -404,7 +410,7 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
continue;
error("pathspec '%s' did not match any file(s) known to git.",
- pathspec[num] + prefix_offset);
+ pathspec[num] + prefix_len);
errors++;
}
return errors;
@@ -456,9 +462,10 @@ static int option_parse_exclude_standard(const struct option *opt,
return 0;
}
-int cmd_ls_files(int argc, const char **argv, const char *prefix)
+int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
{
int require_work_tree = 0, show_tag = 0;
+ const char *max_prefix;
struct dir_struct dir;
struct option builtin_ls_files_options[] = {
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
@@ -504,7 +511,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
{ OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
"add the standard git exclusions",
PARSE_OPT_NOARG, option_parse_exclude_standard },
- { OPTION_SET_INT, 0, "full-name", &prefix_offset, NULL,
+ { OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
"make the output relative to the project top directory",
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
OPT_BOOLEAN(0, "error-unmatch", &error_unmatch,
@@ -516,8 +523,9 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
};
memset(&dir, 0, sizeof(dir));
+ prefix = cmd_prefix;
if (prefix)
- prefix_offset = strlen(prefix);
+ prefix_len = strlen(prefix);
git_config(git_default_config, NULL);
if (read_cache() < 0)
@@ -555,9 +563,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
if (pathspec)
strip_trailing_slash_from_submodules();
- /* Verify that the pathspec matches the prefix */
- if (pathspec)
- prefix = verify_pathspec(prefix);
+ /* Find common prefix for all pathspec's */
+ max_prefix = pathspec_prefix(prefix);
/* Treat unmatching pathspec elements as errors */
if (pathspec && error_unmatch) {
@@ -575,8 +582,8 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
show_killed | show_modified | show_resolve_undo))
show_cached = 1;
- if (prefix)
- prune_cache(prefix);
+ if (max_prefix)
+ prune_cache(max_prefix);
if (with_tree) {
/*
* Basic sanity check; show-stages and show-unmerged
@@ -584,15 +591,15 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
*/
if (show_stage || show_unmerged)
die("ls-files --with-tree is incompatible with -s or -u");
- overlay_tree_on_cache(with_tree, prefix);
+ overlay_tree_on_cache(with_tree, max_prefix);
}
- show_files(&dir, prefix);
+ show_files(&dir);
if (show_resolve_undo)
- show_ru_info(prefix);
+ show_ru_info();
if (ps_matched) {
int bad;
- bad = report_path_error(ps_matched, pathspec, prefix_offset);
+ bad = report_path_error(ps_matched, pathspec, prefix_len);
if (bad)
fprintf(stderr, "Did you forget to 'git add'?\n");
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 8ee91eb54..34480cfad 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -5,7 +5,7 @@
static const char ls_remote_usage[] =
"git ls-remote [--heads] [--tags] [-u <exec> | --upload-pack <exec>]\n"
-" [<repository> [<refs>...]]";
+" [-q|--quiet] [<repository> [<refs>...]]";
/*
* Is there one among the list of patterns that match the tail part
@@ -34,6 +34,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
const char *dest = NULL;
int nongit;
unsigned flags = 0;
+ int quiet = 0;
const char *uploadpack = NULL;
const char **pattern = NULL;
@@ -67,6 +68,10 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
flags |= REF_NORMAL;
continue;
}
+ if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) {
+ quiet = 1;
+ continue;
+ }
usage(ls_remote_usage);
}
dest = arg;
@@ -99,6 +104,9 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
ref = transport_get_remote_refs(transport);
if (transport_disconnect(transport))
return 1;
+
+ if (!dest && !quiet)
+ fprintf(stderr, "From %s\n", *remote->url);
for ( ; ref; ref = ref->next) {
if (!check_ref_type(ref, flags))
continue;
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index 610849a65..b8e9e5ba0 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -25,7 +25,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
const char *names[3] = { NULL, NULL, NULL };
mmfile_t mmfs[3];
mmbuffer_t result = {NULL, 0};
- xmparam_t xmp = {{XDF_NEED_MINIMAL}};
+ xmparam_t xmp = {{0}};
int ret = 0, i = 0, to_stdout = 0;
int quiet = 0;
int nongit;
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index a4a4f2ce4..fc00d794d 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -106,7 +106,7 @@ static void show_diff(struct merge_list *entry)
xdemitconf_t xecfg;
xdemitcb_t ecb;
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = 0;
memset(&xecfg, 0, sizeof(xecfg));
xecfg.ctxlen = 3;
ecb.outf = show_outf;
diff --git a/builtin/merge.c b/builtin/merge.c
index 37d414b3b..37ce4f589 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -982,7 +982,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
reset_hard(remote_head->sha1, 0);
return 0;
} else {
- struct strbuf msg = STRBUF_INIT;
+ struct strbuf merge_names = STRBUF_INIT;
/* We are invoked directly as the first-class UI. */
head_arg = "HEAD";
@@ -995,13 +995,17 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* codepath so we discard the error in this
* loop.
*/
- if (!have_message) {
- for (i = 0; i < argc; i++)
- merge_name(argv[i], &msg);
- fmt_merge_msg(option_log, &msg, &merge_msg);
- if (merge_msg.len)
- strbuf_setlen(&merge_msg, merge_msg.len-1);
- }
+ for (i = 0; i < argc; i++)
+ merge_name(argv[i], &merge_names);
+
+ if (have_message && option_log)
+ fmt_merge_msg_shortlog(&merge_names, &merge_msg);
+ else if (!have_message)
+ fmt_merge_msg(option_log, &merge_names, &merge_msg);
+
+
+ if (!(have_message && !option_log) && merge_msg.len)
+ strbuf_setlen(&merge_msg, merge_msg.len-1);
}
if (head_invalid || !argc)
diff --git a/builtin/notes.c b/builtin/notes.c
index 52b72fca6..648033c27 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -26,7 +26,7 @@ static const char * const git_notes_usage[] = {
"git notes [--ref <notes_ref>] edit [<object>]",
"git notes [--ref <notes_ref>] show [<object>]",
"git notes [--ref <notes_ref>] remove [<object>]",
- "git notes [--ref <notes_ref>] prune",
+ "git notes [--ref <notes_ref>] prune [-n | -v]",
NULL
};
@@ -67,7 +67,7 @@ static const char * const git_notes_remove_usage[] = {
};
static const char * const git_notes_prune_usage[] = {
- "git notes prune",
+ "git notes prune [<options>]",
NULL
};
@@ -416,7 +416,7 @@ int notes_copy_from_stdin(int force, const char *rewrite_cmd)
{
struct strbuf buf = STRBUF_INIT;
struct notes_rewrite_cfg *c = NULL;
- struct notes_tree *t;
+ struct notes_tree *t = NULL;
int ret = 0;
if (rewrite_cmd) {
@@ -792,7 +792,10 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
static int prune(int argc, const char **argv, const char *prefix)
{
struct notes_tree *t;
+ int show_only = 0, verbose = 0;
struct option options[] = {
+ OPT_BOOLEAN('n', NULL, &show_only, "do not remove, show only"),
+ OPT_BOOLEAN('v', NULL, &verbose, "report pruned notes"),
OPT_END()
};
@@ -806,8 +809,10 @@ static int prune(int argc, const char **argv, const char *prefix)
t = init_notes_check("prune");
- prune_notes(t);
- commit_notes(t, "Notes removed by 'git notes prune'");
+ prune_notes(t, (verbose ? NOTES_PRUNE_VERBOSE : 0) |
+ (show_only ? NOTES_PRUNE_VERBOSE|NOTES_PRUNE_DRYRUN : 0) );
+ if (!show_only)
+ commit_notes(t, "Notes removed by 'git notes prune'");
free_notes(t);
return 0;
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 214d7ef2b..0e8167311 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1529,6 +1529,8 @@ static void try_to_free_from_threads(size_t size)
read_unlock();
}
+try_to_free_t old_try_to_free_routine;
+
/*
* The main thread waits on the condition that (at least) one of the workers
* has stopped working (which is indicated in the .working member of
@@ -1563,12 +1565,12 @@ static void init_threaded_search(void)
pthread_mutex_init(&cache_mutex, NULL);
pthread_mutex_init(&progress_mutex, NULL);
pthread_cond_init(&progress_cond, NULL);
- set_try_to_free_routine(try_to_free_from_threads);
+ old_try_to_free_routine = set_try_to_free_routine(try_to_free_from_threads);
}
static void cleanup_threaded_search(void)
{
- set_try_to_free_routine(NULL);
+ set_try_to_free_routine(old_try_to_free_routine);
pthread_cond_destroy(&progress_cond);
pthread_mutex_destroy(&read_mutex);
pthread_mutex_destroy(&cache_mutex);
diff --git a/builtin/remote.c b/builtin/remote.c
index 0e99a9957..4745957b9 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -16,6 +16,7 @@ static const char * const builtin_remote_usage[] = {
"git remote [-v | --verbose] show [-n] <name>",
"git remote prune [-n | --dry-run] <name>",
"git remote [-v | --verbose] update [-p | --prune] [group | remote]",
+ "git remote set-branches <name> [--add] <branch>...",
"git remote set-url <name> <newurl> [<oldurl>]",
"git remote set-url --add <name> <newurl>",
"git remote set-url --delete <name> <url>",
@@ -42,6 +43,12 @@ static const char * const builtin_remote_sethead_usage[] = {
NULL
};
+static const char * const builtin_remote_setbranches_usage[] = {
+ "git remote set-branches <name> <branch>...",
+ "git remote set-branches --add <name> <branch>...",
+ NULL
+};
+
static const char * const builtin_remote_show_usage[] = {
"git remote show [<options>] <name>",
NULL
@@ -110,6 +117,20 @@ enum {
TAGS_SET = 2
};
+static int add_branch(const char *key, const char *branchname,
+ const char *remotename, int mirror, struct strbuf *tmp)
+{
+ strbuf_reset(tmp);
+ strbuf_addch(tmp, '+');
+ if (mirror)
+ strbuf_addf(tmp, "refs/%s:refs/%s",
+ branchname, branchname);
+ else
+ strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s",
+ branchname, remotename, branchname);
+ return git_config_set_multivar(key, tmp->buf, "^$", 0);
+}
+
static int add(int argc, const char **argv)
{
int fetch = 0, mirror = 0, fetch_tags = TAGS_DEFAULT;
@@ -162,17 +183,8 @@ static int add(int argc, const char **argv)
if (track.nr == 0)
string_list_append("*", &track);
for (i = 0; i < track.nr; i++) {
- struct string_list_item *item = track.items + i;
-
- strbuf_reset(&buf2);
- strbuf_addch(&buf2, '+');
- if (mirror)
- strbuf_addf(&buf2, "refs/%s:refs/%s",
- item->string, item->string);
- else
- strbuf_addf(&buf2, "refs/heads/%s:refs/remotes/%s/%s",
- item->string, name, item->string);
- if (git_config_set_multivar(buf.buf, buf2.buf, "^$", 0))
+ if (add_branch(buf.buf, track.items[i].string,
+ name, mirror, &buf2))
return 1;
}
@@ -1284,6 +1296,72 @@ static int update(int argc, const char **argv)
return run_command_v_opt(fetch_argv, RUN_GIT_CMD);
}
+static int remove_all_fetch_refspecs(const char *remote, const char *key)
+{
+ return git_config_set_multivar(key, NULL, NULL, 1);
+}
+
+static int add_branches(struct remote *remote, const char **branches,
+ const char *key)
+{
+ const char *remotename = remote->name;
+ int mirror = remote->mirror;
+ struct strbuf refspec = STRBUF_INIT;
+
+ for (; *branches; branches++)
+ if (add_branch(key, *branches, remotename, mirror, &refspec)) {
+ strbuf_release(&refspec);
+ return 1;
+ }
+
+ strbuf_release(&refspec);
+ return 0;
+}
+
+static int set_remote_branches(const char *remotename, const char **branches,
+ int add_mode)
+{
+ struct strbuf key = STRBUF_INIT;
+ struct remote *remote;
+
+ strbuf_addf(&key, "remote.%s.fetch", remotename);
+
+ if (!remote_is_configured(remotename))
+ die("No such remote '%s'", remotename);
+ remote = remote_get(remotename);
+
+ if (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) {
+ strbuf_release(&key);
+ return 1;
+ }
+ if (add_branches(remote, branches, key.buf)) {
+ strbuf_release(&key);
+ return 1;
+ }
+
+ strbuf_release(&key);
+ return 0;
+}
+
+static int set_branches(int argc, const char **argv)
+{
+ int add_mode = 0;
+ struct option options[] = {
+ OPT_BOOLEAN('\0', "add", &add_mode, "add branch"),
+ OPT_END()
+ };
+
+ argc = parse_options(argc, argv, NULL, options,
+ builtin_remote_setbranches_usage, 0);
+ if (argc == 0) {
+ error("no remote specified");
+ usage_with_options(builtin_remote_seturl_usage, options);
+ }
+ argv[argc] = NULL;
+
+ return set_remote_branches(argv[0], argv + 1, add_mode);
+}
+
static int set_url(int argc, const char **argv)
{
int i, push_mode = 0, add_mode = 0, delete_mode = 0;
@@ -1449,6 +1527,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
result = rm(argc, argv);
else if (!strcmp(argv[0], "set-head"))
result = set_head(argc, argv);
+ else if (!strcmp(argv[0], "set-branches"))
+ result = set_branches(argc, argv);
else if (!strcmp(argv[0], "set-url"))
result = set_url(argc, argv);
else if (!strcmp(argv[0], "show"))
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 34f9acee9..0048f9ef7 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -89,7 +89,7 @@ static int diff_two(const char *file1, const char *label1,
printf("--- a/%s\n+++ b/%s\n", label1, label2);
fflush(stdout);
memset(&xpp, 0, sizeof(xpp));
- xpp.flags = XDF_NEED_MINIMAL;
+ xpp.flags = 0;
memset(&xecfg, 0, sizeof(xecfg));
xecfg.ctxlen = 3;
ecb.outf = outf;