aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/am.c41
-rw-r--r--builtin/apply.c6
-rw-r--r--builtin/blame.c23
-rw-r--r--builtin/branch.c30
-rw-r--r--builtin/cat-file.c4
-rw-r--r--builtin/checkout.c6
-rw-r--r--builtin/clone.c12
-rw-r--r--builtin/commit.c4
-rw-r--r--builtin/config.c2
-rw-r--r--builtin/fast-export.c10
-rw-r--r--builtin/fetch.c205
-rw-r--r--builtin/fsck.c84
-rw-r--r--builtin/gc.c2
-rw-r--r--builtin/grep.c4
-rw-r--r--builtin/index-pack.c33
-rw-r--r--builtin/init-db.c17
-rw-r--r--builtin/log.c93
-rw-r--r--builtin/merge-recursive.c20
-rw-r--r--builtin/merge.c72
-rw-r--r--builtin/notes.c24
-rw-r--r--builtin/pack-objects.c17
-rw-r--r--builtin/pull.c2
-rw-r--r--builtin/push.c21
-rw-r--r--builtin/receive-pack.c177
-rw-r--r--builtin/remote.c27
-rw-r--r--builtin/repack.c2
-rw-r--r--builtin/reset.c6
-rw-r--r--builtin/rev-list.c17
-rw-r--r--builtin/revert.c13
-rw-r--r--builtin/rm.c5
-rw-r--r--builtin/shortlog.c15
-rw-r--r--builtin/unpack-objects.c4
-rw-r--r--builtin/worktree.c68
33 files changed, 728 insertions, 338 deletions
diff --git a/builtin/am.c b/builtin/am.c
index d5da5fe090..b77bf11ace 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -184,22 +184,22 @@ static inline const char *am_path(const struct am_state *state, const char *path
/**
* For convenience to call write_file()
*/
-static int write_state_text(const struct am_state *state,
- const char *name, const char *string)
+static void write_state_text(const struct am_state *state,
+ const char *name, const char *string)
{
- return write_file(am_path(state, name), "%s", string);
+ write_file(am_path(state, name), "%s", string);
}
-static int write_state_count(const struct am_state *state,
- const char *name, int value)
+static void write_state_count(const struct am_state *state,
+ const char *name, int value)
{
- return write_file(am_path(state, name), "%d", value);
+ write_file(am_path(state, name), "%d", value);
}
-static int write_state_bool(const struct am_state *state,
- const char *name, int value)
+static void write_state_bool(const struct am_state *state,
+ const char *name, int value)
{
- return write_state_text(state, name, value ? "t" : "f");
+ write_state_text(state, name, value ? "t" : "f");
}
/**
@@ -403,13 +403,8 @@ static int read_commit_msg(struct am_state *state)
*/
static void write_commit_msg(const struct am_state *state)
{
- int fd;
const char *filename = am_path(state, "final-commit");
-
- fd = xopen(filename, O_WRONLY | O_CREAT, 0666);
- if (write_in_full(fd, state->msg, state->msg_len) < 0)
- die_errno(_("could not write to %s"), filename);
- close(fd);
+ write_file_buf(filename, state->msg, state->msg_len);
}
/**
@@ -1584,14 +1579,14 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
}
/**
- * Do the three-way merge using fake ancestor, his tree constructed
+ * Do the three-way merge using fake ancestor, their tree constructed
* from the fake ancestor and the postimage of the patch, and our
* state.
*/
static int run_fallback_merge_recursive(const struct am_state *state,
unsigned char *orig_tree,
unsigned char *our_tree,
- unsigned char *his_tree)
+ unsigned char *their_tree)
{
struct child_process cp = CHILD_PROCESS_INIT;
int status;
@@ -1599,7 +1594,7 @@ static int run_fallback_merge_recursive(const struct am_state *state,
cp.git_cmd = 1;
argv_array_pushf(&cp.env_array, "GITHEAD_%s=%.*s",
- sha1_to_hex(his_tree), linelen(state->msg), state->msg);
+ sha1_to_hex(their_tree), linelen(state->msg), state->msg);
if (state->quiet)
argv_array_push(&cp.env_array, "GIT_MERGE_VERBOSITY=0");
@@ -1607,7 +1602,7 @@ static int run_fallback_merge_recursive(const struct am_state *state,
argv_array_push(&cp.args, sha1_to_hex(orig_tree));
argv_array_push(&cp.args, "--");
argv_array_push(&cp.args, sha1_to_hex(our_tree));
- argv_array_push(&cp.args, sha1_to_hex(his_tree));
+ argv_array_push(&cp.args, sha1_to_hex(their_tree));
status = run_command(&cp) ? (-1) : 0;
discard_cache();
@@ -1620,7 +1615,7 @@ static int run_fallback_merge_recursive(const struct am_state *state,
*/
static int fall_back_threeway(const struct am_state *state, const char *index_path)
{
- unsigned char orig_tree[GIT_SHA1_RAWSZ], his_tree[GIT_SHA1_RAWSZ],
+ unsigned char orig_tree[GIT_SHA1_RAWSZ], their_tree[GIT_SHA1_RAWSZ],
our_tree[GIT_SHA1_RAWSZ];
if (get_sha1("HEAD", our_tree) < 0)
@@ -1657,7 +1652,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
return error(_("Did you hand edit your patch?\n"
"It does not apply to blobs recorded in its index."));
- if (write_index_as_tree(his_tree, &the_index, index_path, 0, NULL))
+ if (write_index_as_tree(their_tree, &the_index, index_path, 0, NULL))
return error("could not write tree");
say(state, stdout, _("Falling back to patching base and 3-way merge..."));
@@ -1667,13 +1662,13 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
/*
* This is not so wrong. Depending on which base we picked, orig_tree
- * may be wildly different from ours, but his_tree has the same set of
+ * may be wildly different from ours, but their_tree has the same set of
* wildly different changes in parts the patch did not touch, so
* recursive ends up canceling them, saying that we reverted all those
* changes.
*/
- if (run_fallback_merge_recursive(state, orig_tree, our_tree, his_tree)) {
+ if (run_fallback_merge_recursive(state, orig_tree, our_tree, their_tree)) {
rerere(state->allow_rerere_autoupdate);
return error(_("Failed to merge in the changes."));
}
diff --git a/builtin/apply.c b/builtin/apply.c
index 7fc5c3e307..1a488f9e88 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3359,7 +3359,7 @@ static int load_patch_target(struct apply_state *state,
{
if (state->cached || state->check_index) {
if (read_file_or_gitlink(ce, buf))
- return error(_("read of %s failed"), name);
+ return error(_("failed to read %s"), name);
} else if (name) {
if (S_ISGITLINK(expected_mode)) {
if (ce)
@@ -3370,7 +3370,7 @@ static int load_patch_target(struct apply_state *state,
return error(_("reading from '%s' beyond a symbolic link"), name);
} else {
if (read_old_data(st, name, buf))
- return error(_("read of %s failed"), name);
+ return error(_("failed to read %s"), name);
}
}
return 0;
@@ -3416,7 +3416,7 @@ static int load_preimage(struct apply_state *state,
free_fragment_list(patch->fragments);
patch->fragments = NULL;
} else if (status) {
- return error(_("read of %s failed"), patch->old_name);
+ return error(_("failed to read %s"), patch->old_name);
}
}
diff --git a/builtin/blame.c b/builtin/blame.c
index 1e214bd4ec..ab66cde2c2 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -134,7 +134,7 @@ struct progress_info {
int blamed_lines;
};
-static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen,
+static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
xdl_emit_hunk_consume_func_t hunk_func, void *cb_data)
{
xpparam_t xpp = {0};
@@ -142,7 +142,6 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen,
xdemitcb_t ecb = {NULL};
xpp.flags = xdl_opts;
- xecfg.ctxlen = ctxlen;
xecfg.hunk_func = hunk_func;
ecb.priv = cb_data;
return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
@@ -599,7 +598,7 @@ static struct origin *find_origin(struct scoreboard *sb,
p->status);
case 'M':
porigin = get_origin(sb, parent, origin->path);
- hashcpy(porigin->blob_sha1, p->one->sha1);
+ hashcpy(porigin->blob_sha1, p->one->oid.hash);
porigin->mode = p->one->mode;
break;
case 'A':
@@ -645,7 +644,7 @@ static struct origin *find_rename(struct scoreboard *sb,
if ((p->status == 'R' || p->status == 'C') &&
!strcmp(p->two->path, origin->path)) {
porigin = get_origin(sb, parent, p->one->path);
- hashcpy(porigin->blob_sha1, p->one->sha1);
+ hashcpy(porigin->blob_sha1, p->one->oid.hash);
porigin->mode = p->one->mode;
break;
}
@@ -980,7 +979,7 @@ static void pass_blame_to_parent(struct scoreboard *sb,
fill_origin_blob(&sb->revs->diffopt, target, &file_o);
num_get_patch++;
- if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
+ if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d))
die("unable to generate diff (%s -> %s)",
oid_to_hex(&parent->commit->object.oid),
oid_to_hex(&target->commit->object.oid));
@@ -1129,7 +1128,7 @@ static void find_copy_in_blob(struct scoreboard *sb,
* file_p partially may match that image.
*/
memset(split, 0, sizeof(struct blame_entry [3]));
- if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
+ if (diff_hunks(file_p, &file_o, handle_split_cb, &d))
die("unable to generate diff (%s)",
oid_to_hex(&parent->commit->object.oid));
/* remainder, if any, all match the preimage */
@@ -1309,7 +1308,7 @@ static void find_copy_in_parent(struct scoreboard *sb,
continue;
norigin = get_origin(sb, parent, p->one->path);
- hashcpy(norigin->blob_sha1, p->one->sha1);
+ hashcpy(norigin->blob_sha1, p->one->oid.hash);
norigin->mode = p->one->mode;
fill_origin_blob(&sb->revs->diffopt, norigin, &file_p);
if (!file_p.ptr)
@@ -2230,6 +2229,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)
static void verify_working_tree_path(struct commit *work_tree, const char *path)
{
struct commit_list *parents;
+ int pos;
for (parents = work_tree->parents; parents; parents = parents->next) {
const unsigned char *commit_sha1 = parents->item->object.oid.hash;
@@ -2240,7 +2240,14 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
return;
}
- die("no such path '%s' in HEAD", path);
+
+ pos = cache_name_pos(path, strlen(path));
+ if (pos >= 0)
+ ; /* path is in the index */
+ else if (!strcmp(active_cache[-1 - pos]->name, path))
+ ; /* path is in the index, unmerged */
+ else
+ die("no such path '%s' in HEAD", path);
}
static struct commit_list **append_parent(struct commit_list **tail, const unsigned char *sha1)
diff --git a/builtin/branch.c b/builtin/branch.c
index 2ecde53bf8..7df05437f1 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -212,7 +212,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
die(_("Couldn't look up commit object for HEAD"));
}
for (i = 0; i < argc; i++, strbuf_release(&bname)) {
- const char *target;
+ char *target = NULL;
int flags = 0;
strbuf_branchname(&bname, argv[i]);
@@ -231,11 +231,11 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
}
}
- target = resolve_ref_unsafe(name,
- RESOLVE_REF_READING
- | RESOLVE_REF_NO_RECURSE
- | RESOLVE_REF_ALLOW_BAD_NAME,
- sha1, &flags);
+ target = resolve_refdup(name,
+ RESOLVE_REF_READING
+ | RESOLVE_REF_NO_RECURSE
+ | RESOLVE_REF_ALLOW_BAD_NAME,
+ sha1, &flags);
if (!target) {
error(remote_branch
? _("remote-tracking branch '%s' not found.")
@@ -248,7 +248,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
check_branch_commit(bname.buf, name, sha1, head_rev, kinds,
force)) {
ret = 1;
- continue;
+ goto next;
}
if (delete_ref(name, is_null_sha1(sha1) ? NULL : sha1,
@@ -258,7 +258,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
: _("Error deleting branch '%s'"),
bname.buf);
ret = 1;
- continue;
+ goto next;
}
if (!quiet) {
printf(remote_branch
@@ -270,6 +270,9 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
: find_unique_abbrev(sha1, DEFAULT_ABBREV));
}
delete_branch_config(bname.buf);
+
+ next:
+ free(target);
}
free(name);
@@ -614,14 +617,11 @@ static int edit_branch_description(const char *branch_name)
if (!buf.len || buf.buf[buf.len-1] != '\n')
strbuf_addch(&buf, '\n');
strbuf_commented_addf(&buf,
- "Please edit the description for the branch\n"
- " %s\n"
- "Lines starting with '%c' will be stripped.\n",
+ _("Please edit the description for the branch\n"
+ " %s\n"
+ "Lines starting with '%c' will be stripped.\n"),
branch_name, comment_line_char);
- if (write_file_gently(git_path(edit_description), "%s", buf.buf)) {
- strbuf_release(&buf);
- return error_errno(_("could not write branch description template"));
- }
+ write_file_buf(git_path(edit_description), buf.buf, buf.len);
strbuf_reset(&buf);
if (launch_editor(git_path(edit_description), &buf, NULL)) {
strbuf_release(&buf);
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 618103fdee..2dfe6265f7 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -131,7 +131,7 @@ struct expand_data {
unsigned char sha1[20];
enum object_type type;
unsigned long size;
- unsigned long disk_size;
+ off_t disk_size;
const char *rest;
unsigned char delta_base_sha1[20];
@@ -191,7 +191,7 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
if (data->mark_query)
data->info.disk_sizep = &data->disk_size;
else
- strbuf_addf(sb, "%lu", data->disk_size);
+ strbuf_addf(sb, "%"PRIuMAX, (uintmax_t)data->disk_size);
} else if (is_atom("rest", atom, len)) {
if (data->mark_query)
data->split_on_whitespace = 1;
diff --git a/builtin/checkout.c b/builtin/checkout.c
index c3486bdec3..27c1a05246 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -276,7 +276,7 @@ static int checkout_paths(const struct checkout_opts *opts,
hold_locked_index(lock_file, 1);
if (read_cache_preload(&opts->pathspec) < 0)
- return error(_("corrupt index file"));
+ return error(_("index file corrupt"));
if (opts->source_tree)
read_tree_some(opts->source_tree, &opts->pathspec);
@@ -470,7 +470,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
hold_locked_index(lock_file, 1);
if (read_cache_preload(NULL) < 0)
- return error(_("corrupt index file"));
+ return error(_("index file corrupt"));
resolve_undo_clear();
if (opts->force) {
@@ -1138,7 +1138,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"),
N_("create/reset and checkout a branch")),
OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
- OPT_BOOL(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
+ OPT_BOOL(0, "detach", &opts.force_detach, N_("detach HEAD at named commit")),
OPT_SET_INT('t', "track", &opts.track, N_("set upstream info for new branch"),
BRANCH_TRACK_EXPLICIT),
OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new-branch"), N_("new unparented branch")),
diff --git a/builtin/clone.c b/builtin/clone.c
index 31ea247e3f..f044a8c27f 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -624,13 +624,13 @@ static void update_remote_refs(const struct ref *refs,
const struct ref *rm = mapped_refs;
if (check_connectivity) {
- if (transport->progress)
- fprintf(stderr, _("Checking connectivity... "));
- if (check_everything_connected_with_transport(iterate_ref_map,
- 0, &rm, transport))
+ struct check_connected_options opt = CHECK_CONNECTED_INIT;
+
+ opt.transport = transport;
+ opt.progress = transport->progress;
+
+ if (check_connected(iterate_ref_map, &rm, &opt))
die(_("remote did not send all necessary objects"));
- if (transport->progress)
- fprintf(stderr, _("done.\n"));
}
if (refs) {
diff --git a/builtin/commit.c b/builtin/commit.c
index 3f189428b1..77e3dc8494 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -715,7 +715,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
char *buffer;
buffer = strstr(use_message_buffer, "\n\n");
if (buffer)
- strbuf_addstr(&sb, buffer + 2);
+ strbuf_addstr(&sb, skip_blank_lines(buffer + 2));
hook_arg1 = "commit";
hook_arg2 = use_message;
} else if (fixup_message) {
@@ -1617,7 +1617,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")),
OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")),
OPT_BOOL('o', "only", &only, N_("commit only specified files")),
- OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit hook")),
+ OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit and commit-msg hooks")),
OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")),
OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
STATUS_FORMAT_SHORT),
diff --git a/builtin/config.c b/builtin/config.c
index 1d7c6ef558..a991a53418 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -604,7 +604,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
given_config_source.file : git_path("config"));
if (use_global_config) {
int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666);
- if (fd) {
+ if (fd >= 0) {
char *content = default_user_config();
write_str_in_full(fd, content);
free(content);
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 8164b581a6..c0652a7ed0 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -368,7 +368,7 @@ static void show_filemodify(struct diff_queue_struct *q,
print_path(spec->path);
putchar('\n');
- if (!hashcmp(ospec->sha1, spec->sha1) &&
+ if (!oidcmp(&ospec->oid, &spec->oid) &&
ospec->mode == spec->mode)
break;
/* fallthrough */
@@ -383,10 +383,10 @@ static void show_filemodify(struct diff_queue_struct *q,
if (no_data || S_ISGITLINK(spec->mode))
printf("M %06o %s ", spec->mode,
sha1_to_hex(anonymize ?
- anonymize_sha1(spec->sha1) :
- spec->sha1));
+ anonymize_sha1(spec->oid.hash) :
+ spec->oid.hash));
else {
- struct object *object = lookup_object(spec->sha1);
+ struct object *object = lookup_object(spec->oid.hash);
printf("M %06o :%d ", spec->mode,
get_object_mark(object));
}
@@ -572,7 +572,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
/* Export the referenced blobs, and remember the marks. */
for (i = 0; i < diff_queued_diff.nr; i++)
if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
- export_blob(diff_queued_diff.queue[i]->two->sha1);
+ export_blob(diff_queued_diff.queue[i]->two->oid.hash);
refname = commit->util;
if (anonymize) {
diff --git a/builtin/fetch.c b/builtin/fetch.c
index f896aa1f88..164623bb6f 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -15,6 +15,7 @@
#include "submodule.h"
#include "connected.h"
#include "argv-array.h"
+#include "utf8.h"
static const char * const builtin_fetch_usage[] = {
N_("git fetch [<options>] [<repository> [<refspec>...]]"),
@@ -449,7 +450,132 @@ fail:
: STORE_REF_ERROR_OTHER;
}
-#define REFCOL_WIDTH 10
+static int refcol_width = 10;
+static int compact_format;
+
+static void adjust_refcol_width(const struct ref *ref)
+{
+ int max, rlen, llen, len;
+
+ /* uptodate lines are only shown on high verbosity level */
+ if (!verbosity && !oidcmp(&ref->peer_ref->old_oid, &ref->old_oid))
+ return;
+
+ max = term_columns();
+ rlen = utf8_strwidth(prettify_refname(ref->name));
+
+ llen = utf8_strwidth(prettify_refname(ref->peer_ref->name));
+
+ /*
+ * rough estimation to see if the output line is too long and
+ * should not be counted (we can't do precise calculation
+ * anyway because we don't know if the error explanation part
+ * will be printed in update_local_ref)
+ */
+ if (compact_format) {
+ llen = 0;
+ max = max * 2 / 3;
+ }
+ len = 21 /* flag and summary */ + rlen + 4 /* -> */ + llen;
+ if (len >= max)
+ return;
+
+ /*
+ * Not precise calculation for compact mode because '*' can
+ * appear on the left hand side of '->' and shrink the column
+ * back.
+ */
+ if (refcol_width < rlen)
+ refcol_width = rlen;
+}
+
+static void prepare_format_display(struct ref *ref_map)
+{
+ struct ref *rm;
+ const char *format = "full";
+
+ git_config_get_string_const("fetch.output", &format);
+ if (!strcasecmp(format, "full"))
+ compact_format = 0;
+ else if (!strcasecmp(format, "compact"))
+ compact_format = 1;
+ else
+ die(_("configuration fetch.output contains invalid value %s"),
+ format);
+
+ for (rm = ref_map; rm; rm = rm->next) {
+ if (rm->status == REF_STATUS_REJECT_SHALLOW ||
+ !rm->peer_ref ||
+ !strcmp(rm->name, "HEAD"))
+ continue;
+
+ adjust_refcol_width(rm);
+ }
+}
+
+static void print_remote_to_local(struct strbuf *display,
+ const char *remote, const char *local)
+{
+ strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local);
+}
+
+static int find_and_replace(struct strbuf *haystack,
+ const char *needle,
+ const char *placeholder)
+{
+ const char *p = strstr(haystack->buf, needle);
+ int plen, nlen;
+
+ if (!p)
+ return 0;
+
+ if (p > haystack->buf && p[-1] != '/')
+ return 0;
+
+ plen = strlen(p);
+ nlen = strlen(needle);
+ if (plen > nlen && p[nlen] != '/')
+ return 0;
+
+ strbuf_splice(haystack, p - haystack->buf, nlen,
+ placeholder, strlen(placeholder));
+ return 1;
+}
+
+static void print_compact(struct strbuf *display,
+ const char *remote, const char *local)
+{
+ struct strbuf r = STRBUF_INIT;
+ struct strbuf l = STRBUF_INIT;
+
+ if (!strcmp(remote, local)) {
+ strbuf_addf(display, "%-*s -> *", refcol_width, remote);
+ return;
+ }
+
+ strbuf_addstr(&r, remote);
+ strbuf_addstr(&l, local);
+
+ if (!find_and_replace(&r, local, "*"))
+ find_and_replace(&l, remote, "*");
+ print_remote_to_local(display, r.buf, l.buf);
+
+ strbuf_release(&r);
+ strbuf_release(&l);
+}
+
+static void format_display(struct strbuf *display, char code,
+ const char *summary, const char *error,
+ const char *remote, const char *local)
+{
+ strbuf_addf(display, "%c %-*s ", code, TRANSPORT_SUMMARY(summary));
+ if (!compact_format)
+ print_remote_to_local(display, remote, local);
+ else
+ print_compact(display, remote, local);
+ if (error)
+ strbuf_addf(display, " (%s)", error);
+}
static int update_local_ref(struct ref *ref,
const char *remote,
@@ -467,9 +593,8 @@ static int update_local_ref(struct ref *ref,
if (!oidcmp(&ref->old_oid, &ref->new_oid)) {
if (verbosity > 0)
- strbuf_addf(display, "= %-*s %-*s -> %s",
- TRANSPORT_SUMMARY(_("[up to date]")),
- REFCOL_WIDTH, remote, pretty_ref);
+ format_display(display, '=', _("[up to date]"), NULL,
+ remote, pretty_ref);
return 0;
}
@@ -481,10 +606,9 @@ static int update_local_ref(struct ref *ref,
* If this is the head, and it's not okay to update
* the head, and the old value of the head isn't empty...
*/
- strbuf_addf(display,
- _("! %-*s %-*s -> %s (can't fetch in current branch)"),
- TRANSPORT_SUMMARY(_("[rejected]")),
- REFCOL_WIDTH, remote, pretty_ref);
+ format_display(display, '!', _("[rejected]"),
+ _("can't fetch in current branch"),
+ remote, pretty_ref);
return 1;
}
@@ -492,11 +616,9 @@ static int update_local_ref(struct ref *ref,
starts_with(ref->name, "refs/tags/")) {
int r;
r = s_update_ref("updating tag", ref, 0);
- strbuf_addf(display, "%c %-*s %-*s -> %s%s",
- r ? '!' : '-',
- TRANSPORT_SUMMARY(_("[tag update]")),
- REFCOL_WIDTH, remote, pretty_ref,
- r ? _(" (unable to update local ref)") : "");
+ format_display(display, r ? '!' : 't', _("[tag update]"),
+ r ? _("unable to update local ref") : NULL,
+ remote, pretty_ref);
return r;
}
@@ -527,11 +649,9 @@ static int update_local_ref(struct ref *ref,
(recurse_submodules != RECURSE_SUBMODULES_ON))
check_for_new_submodule_commits(ref->new_oid.hash);
r = s_update_ref(msg, ref, 0);
- strbuf_addf(display, "%c %-*s %-*s -> %s%s",
- r ? '!' : '*',
- TRANSPORT_SUMMARY(what),
- REFCOL_WIDTH, remote, pretty_ref,
- r ? _(" (unable to update local ref)") : "");
+ format_display(display, r ? '!' : '*', what,
+ r ? _("unable to update local ref") : NULL,
+ remote, pretty_ref);
return r;
}
@@ -545,11 +665,9 @@ static int update_local_ref(struct ref *ref,
(recurse_submodules != RECURSE_SUBMODULES_ON))
check_for_new_submodule_commits(ref->new_oid.hash);
r = s_update_ref("fast-forward", ref, 1);
- strbuf_addf(display, "%c %-*s %-*s -> %s%s",
- r ? '!' : ' ',
- TRANSPORT_SUMMARY_WIDTH, quickref.buf,
- REFCOL_WIDTH, remote, pretty_ref,
- r ? _(" (unable to update local ref)") : "");
+ format_display(display, r ? '!' : ' ', quickref.buf,
+ r ? _("unable to update local ref") : NULL,
+ remote, pretty_ref);
strbuf_release(&quickref);
return r;
} else if (force || ref->force) {
@@ -562,18 +680,14 @@ static int update_local_ref(struct ref *ref,
(recurse_submodules != RECURSE_SUBMODULES_ON))
check_for_new_submodule_commits(ref->new_oid.hash);
r = s_update_ref("forced-update", ref, 1);
- strbuf_addf(display, "%c %-*s %-*s -> %s (%s)",
- r ? '!' : '+',
- TRANSPORT_SUMMARY_WIDTH, quickref.buf,
- REFCOL_WIDTH, remote, pretty_ref,
- r ? _("unable to update local ref") : _("forced update"));
+ format_display(display, r ? '!' : '+', quickref.buf,
+ r ? _("unable to update local ref") : _("forced update"),
+ remote, pretty_ref);
strbuf_release(&quickref);
return r;
} else {
- strbuf_addf(display, "! %-*s %-*s -> %s %s",
- TRANSPORT_SUMMARY(_("[rejected]")),
- REFCOL_WIDTH, remote, pretty_ref,
- _("(non-fast-forward)"));
+ format_display(display, '!', _("[rejected]"), _("non-fast-forward"),
+ remote, pretty_ref);
return 1;
}
}
@@ -615,11 +729,13 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
url = xstrdup("foreign");
rm = ref_map;
- if (check_everything_connected(iterate_ref_map, 0, &rm)) {
+ if (check_connected(iterate_ref_map, &rm, NULL)) {
rc = error(_("%s did not send all necessary objects\n"), url);
goto abort;
}
+ prepare_format_display(ref_map);
+
/*
* We do a pass for each fetch_head_status type in their enum order, so
* merged entries are written before not-for-merge. That lets readers
@@ -714,11 +830,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
rc |= update_local_ref(ref, what, rm, &note);
free(ref);
} else
- strbuf_addf(&note, "* %-*s %-*s -> FETCH_HEAD",
- TRANSPORT_SUMMARY_WIDTH,
- *kind ? kind : "branch",
- REFCOL_WIDTH,
- *what ? what : "HEAD");
+ format_display(&note, '*',
+ *kind ? kind : "branch", NULL,
+ *what ? what : "HEAD",
+ "FETCH_HEAD");
if (note.len) {
if (verbosity >= 0 && !shown_url) {
fprintf(stderr, _("From %.*s\n"),
@@ -751,6 +866,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
static int quickfetch(struct ref *ref_map)
{
struct ref *rm = ref_map;
+ struct check_connected_options opt = CHECK_CONNECTED_INIT;
/*
* If we are deepening a shallow clone we already have these
@@ -761,7 +877,8 @@ static int quickfetch(struct ref *ref_map)
*/
if (depth)
return -1;
- return check_everything_connected(iterate_ref_map, 1, &rm);
+ opt.quiet = 1;
+ return check_connected(iterate_ref_map, &rm, &opt);
}
static int fetch_refs(struct transport *transport, struct ref *ref_map)
@@ -806,19 +923,21 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
for (ref = stale_refs; ref; ref = ref->next)
string_list_append(&refnames, ref->name);
- result = delete_refs(&refnames);
+ result = delete_refs(&refnames, 0);
string_list_clear(&refnames, 0);
}
if (verbosity >= 0) {
for (ref = stale_refs; ref; ref = ref->next) {
+ struct strbuf sb = STRBUF_INIT;
if (!shown_url) {
fprintf(stderr, _("From %.*s\n"), url_len, url);
shown_url = 1;
}
- fprintf(stderr, " x %-*s %-*s -> %s\n",
- TRANSPORT_SUMMARY(_("[deleted]")),
- REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
+ format_display(&sb, '-', _("[deleted]"), NULL,
+ _("(none)"), prettify_refname(ref->name));
+ fprintf(stderr, " %s\n",sb.buf);
+ strbuf_release(&sb);
warn_dangling_symref(stderr, dangling_msg, ref->name);
}
}
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 3f27456883..2de272ea36 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -13,6 +13,7 @@
#include "dir.h"
#include "progress.h"
#include "streaming.h"
+#include "decorate.h"
#define REACHABLE 0x0001
#define SEEN 0x0002
@@ -35,11 +36,26 @@ static int write_lost_and_found;
static int verbose;
static int show_progress = -1;
static int show_dangling = 1;
+static int name_objects;
#define ERROR_OBJECT 01
#define ERROR_REACHABLE 02
#define ERROR_PACK 04
#define ERROR_REFS 010
+static const char *describe_object(struct object *obj)
+{
+ static struct strbuf buf = STRBUF_INIT;
+ char *name = name_objects ?
+ lookup_decoration(fsck_walk_options.object_names, obj) : NULL;
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, oid_to_hex(&obj->oid));
+ if (name)
+ strbuf_addf(&buf, " (%s)", name);
+
+ return buf.buf;
+}
+
static int fsck_config(const char *var, const char *value, void *cb)
{
if (strcmp(var, "fsck.skiplist") == 0) {
@@ -67,7 +83,7 @@ static void objreport(struct object *obj, const char *msg_type,
const char *err)
{
fprintf(stderr, "%s in %s %s: %s\n",
- msg_type, typename(obj->type), oid_to_hex(&obj->oid), err);
+ msg_type, typename(obj->type), describe_object(obj), err);
}
static int objerror(struct object *obj, const char *err)
@@ -77,7 +93,8 @@ static int objerror(struct object *obj, const char *err)
return -1;
}
-static int fsck_error_func(struct object *obj, int type, const char *message)
+static int fsck_error_func(struct fsck_options *o,
+ struct object *obj, int type, const char *message)
{
objreport(obj, (type == FSCK_WARN) ? "warning" : "error", message);
return (type == FSCK_WARN) ? 0 : 1;
@@ -97,7 +114,7 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
if (!obj) {
/* ... these references to parent->fld are safe here */
printf("broken link from %7s %s\n",
- typename(parent->type), oid_to_hex(&parent->oid));
+ typename(parent->type), describe_object(parent));
printf("broken link from %7s %s\n",
(type == OBJ_ANY ? "unknown" : typename(type)), "unknown");
errors_found |= ERROR_REACHABLE;
@@ -114,9 +131,9 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
if (!(obj->flags & HAS_OBJ)) {
if (parent && !has_object_file(&obj->oid)) {
printf("broken link from %7s %s\n",
- typename(parent->type), oid_to_hex(&parent->oid));
+ typename(parent->type), describe_object(parent));
printf(" to %7s %s\n",
- typename(obj->type), oid_to_hex(&obj->oid));
+ typename(obj->type), describe_object(obj));
errors_found |= ERROR_REACHABLE;
}
return 1;
@@ -190,7 +207,8 @@ static void check_reachable_object(struct object *obj)
return; /* it is in pack - forget about it */
if (connectivity_only && has_object_file(&obj->oid))
return;
- printf("missing %s %s\n", typename(obj->type), oid_to_hex(&obj->oid));
+ printf("missing %s %s\n", typename(obj->type),
+ describe_object(obj));
errors_found |= ERROR_REACHABLE;
return;
}
@@ -215,7 +233,8 @@ static void check_unreachable_object(struct object *obj)
* since this is something that is prunable.
*/
if (show_unreachable) {
- printf("unreachable %s %s\n", typename(obj->type), oid_to_hex(&obj->oid));
+ printf("unreachable %s %s\n", typename(obj->type),
+ describe_object(obj));
return;
}
@@ -234,11 +253,11 @@ static void check_unreachable_object(struct object *obj)
if (!obj->used) {
if (show_dangling)
printf("dangling %s %s\n", typename(obj->type),
- oid_to_hex(&obj->oid));
+ describe_object(obj));
if (write_lost_and_found) {
char *filename = git_pathdup("lost-found/%s/%s",
obj->type == OBJ_COMMIT ? "commit" : "other",
- oid_to_hex(&obj->oid));
+ describe_object(obj));
FILE *f;
if (safe_create_leading_directories_const(filename)) {
@@ -252,7 +271,7 @@ static void check_unreachable_object(struct object *obj)
if (stream_blob_to_fd(fileno(f), obj->oid.hash, NULL, 1))
die_errno("Could not write '%s'", filename);
} else
- fprintf(f, "%s\n", oid_to_hex(&obj->oid));
+ fprintf(f, "%s\n", describe_object(obj));
if (fclose(f))
die_errno("Could not finish '%s'",
filename);
@@ -271,7 +290,7 @@ static void check_unreachable_object(struct object *obj)
static void check_object(struct object *obj)
{
if (verbose)
- fprintf(stderr, "Checking %s\n", oid_to_hex(&obj->oid));
+ fprintf(stderr, "Checking %s\n", describe_object(obj));
if (obj->flags & REACHABLE)
check_reachable_object(obj);
@@ -307,7 +326,7 @@ static int fsck_obj(struct object *obj)
if (verbose)
fprintf(stderr, "Checking %s %s\n",
- typename(obj->type), oid_to_hex(&obj->oid));
+ typename(obj->type), describe_object(obj));
if (fsck_walk(obj, NULL, &fsck_obj_options))
objerror(obj, "broken links");
@@ -326,15 +345,17 @@ static int fsck_obj(struct object *obj)
free_commit_buffer(commit);
if (!commit->parents && show_root)
- printf("root %s\n", oid_to_hex(&commit->object.oid));
+ printf("root %s\n", describe_object(&commit->object));
}
if (obj->type == OBJ_TAG) {
struct tag *tag = (struct tag *) obj;
if (show_tags && tag->tagged) {
- printf("tagged %s %s", typename(tag->tagged->type), oid_to_hex(&tag->tagged->oid));
- printf(" (%s) in %s\n", tag->tag, oid_to_hex(&tag->object.oid));
+ printf("tagged %s %s", typename(tag->tagged->type),
+ describe_object(tag->tagged));
+ printf(" (%s) in %s\n", tag->tag,
+ describe_object(&tag->object));
}
}
@@ -356,6 +377,10 @@ static int fsck_sha1(const unsigned char *sha1)
static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
unsigned long size, void *buffer, int *eaten)
{
+ /*
+ * Note, buffer may be NULL if type is OBJ_BLOB. See
+ * verify_packfile(), data_valid variable for details.
+ */
struct object *obj;
obj = parse_object_buffer(sha1, type, size, buffer, eaten);
if (!obj) {
@@ -368,13 +393,18 @@ static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
static int default_refs;
-static void fsck_handle_reflog_sha1(const char *refname, unsigned char *sha1)
+static void fsck_handle_reflog_sha1(const char *refname, unsigned char *sha1,
+ unsigned long timestamp)
{
struct object *obj;
if (!is_null_sha1(sha1)) {
obj = lookup_object(sha1);
if (obj) {
+ if (timestamp && name_objects)
+ add_decoration(fsck_walk_options.object_names,
+ obj,
+ xstrfmt("%s@{%ld}", refname, timestamp));
obj->used = 1;
mark_object_reachable(obj);
} else {
@@ -394,8 +424,8 @@ static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
fprintf(stderr, "Checking reflog %s->%s\n",
sha1_to_hex(osha1), sha1_to_hex(nsha1));
- fsck_handle_reflog_sha1(refname, osha1);
- fsck_handle_reflog_sha1(refname, nsha1);
+ fsck_handle_reflog_sha1(refname, osha1, 0);
+ fsck_handle_reflog_sha1(refname, nsha1, timestamp);
return 0;
}
@@ -424,6 +454,9 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
}
default_refs++;
obj->used = 1;
+ if (name_objects)
+ add_decoration(fsck_walk_options.object_names,
+ obj, xstrdup(refname));
mark_object_reachable(obj);
return 0;
@@ -539,6 +572,9 @@ static int fsck_cache_tree(struct cache_tree *it)
return 1;
}
obj->used = 1;
+ if (name_objects)
+ add_decoration(fsck_walk_options.object_names,
+ obj, xstrdup(":"));
mark_object_reachable(obj);
if (obj->type != OBJ_TREE)
err |= objerror(obj, "non-tree in cache-tree");
@@ -567,6 +603,7 @@ static struct option fsck_opts[] = {
OPT_BOOL(0, "lost-found", &write_lost_and_found,
N_("write dangling objects in .git/lost-found")),
OPT_BOOL(0, "progress", &show_progress, N_("show progress")),
+ OPT_BOOL(0, "name-objects", &name_objects, N_("show verbose names for reachable objects")),
OPT_END(),
};
@@ -596,6 +633,10 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
include_reflogs = 0;
}
+ if (name_objects)
+ fsck_walk_options.object_names =
+ xcalloc(1, sizeof(struct decoration));
+
git_config(fsck_config, NULL);
fsck_head_link();
@@ -651,6 +692,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
continue;
obj->used = 1;
+ if (name_objects)
+ add_decoration(fsck_walk_options.object_names,
+ obj, xstrdup(arg));
mark_object_reachable(obj);
heads++;
continue;
@@ -683,6 +727,10 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
continue;
obj = &blob->object;
obj->used = 1;
+ if (name_objects)
+ add_decoration(fsck_walk_options.object_names,
+ obj,
+ xstrfmt(":%s", active_cache[i]->name));
mark_object_reachable(obj);
}
if (active_cache_tree)
diff --git a/builtin/gc.c b/builtin/gc.c
index c583aad6ec..332bcf7e7a 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -177,7 +177,7 @@ static int too_many_packs(void)
*/
cnt++;
}
- return gc_auto_pack_limit <= cnt;
+ return gc_auto_pack_limit < cnt;
}
static void add_repack_all_option(void)
diff --git a/builtin/grep.c b/builtin/grep.c
index 462e607901..ae738312aa 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -386,7 +386,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
for (nr = 0; nr < active_nr; nr++) {
const struct cache_entry *ce = active_cache[nr];
- if (!S_ISREG(ce->ce_mode) || ce_intent_to_add(ce))
+ if (!S_ISREG(ce->ce_mode))
continue;
if (!ce_path_match(ce, pathspec, NULL))
continue;
@@ -396,7 +396,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
* cache version instead
*/
if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) {
- if (ce_stage(ce))
+ if (ce_stage(ce) || ce_intent_to_add(ce))
continue;
hit |= grep_sha1(opt, ce->sha1, ce->name, 0, ce->name);
}
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e8c71fc1d2..1d2ea583a4 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -77,6 +77,7 @@ static int strict;
static int do_fsck_object;
static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
static int verbose;
+static int show_resolving_progress;
static int show_stat;
static int check_self_contained_and_connected;
@@ -338,10 +339,10 @@ static void parse_pack_header(void)
use(sizeof(struct pack_header));
}
-static NORETURN void bad_object(unsigned long offset, const char *format,
+static NORETURN void bad_object(off_t offset, const char *format,
...) __attribute__((format (printf, 2, 3)));
-static NORETURN void bad_object(unsigned long offset, const char *format, ...)
+static NORETURN void bad_object(off_t offset, const char *format, ...)
{
va_list params;
char buf[1024];
@@ -349,7 +350,8 @@ static NORETURN void bad_object(unsigned long offset, const char *format, ...)
va_start(params, format);
vsnprintf(buf, sizeof(buf), format, params);
va_end(params);
- die(_("pack has bad object at offset %lu: %s"), offset, buf);
+ die(_("pack has bad object at offset %"PRIuMAX": %s"),
+ (uintmax_t)offset, buf);
}
static inline struct thread_local *get_thread_data(void)
@@ -429,7 +431,7 @@ static int is_delta_type(enum object_type type)
return (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA);
}
-static void *unpack_entry_data(unsigned long offset, unsigned long size,
+static void *unpack_entry_data(off_t offset, unsigned long size,
enum object_type type, unsigned char *sha1)
{
static char fixed_buf[8192];
@@ -549,13 +551,13 @@ static void *unpack_data(struct object_entry *obj,
void *cb_data)
{
off_t from = obj[0].idx.offset + obj[0].hdr_size;
- unsigned long len = obj[1].idx.offset - from;
+ off_t len = obj[1].idx.offset - from;
unsigned char *data, *inbuf;
git_zstream stream;
int status;
data = xmallocz(consume ? 64*1024 : obj->size);
- inbuf = xmalloc((len < 64*1024) ? len : 64*1024);
+ inbuf = xmalloc((len < 64*1024) ? (int)len : 64*1024);
memset(&stream, 0, sizeof(stream));
git_inflate_init(&stream);
@@ -563,15 +565,15 @@ static void *unpack_data(struct object_entry *obj,
stream.avail_out = consume ? 64*1024 : obj->size;
do {
- ssize_t n = (len < 64*1024) ? len : 64*1024;
+ ssize_t n = (len < 64*1024) ? (ssize_t)len : 64*1024;
n = xpread(get_thread_data()->pack_fd, inbuf, n, from);
if (n < 0)
die_errno(_("cannot pread pack file"));
if (!n)
- die(Q_("premature end of pack file, %lu byte missing",
- "premature end of pack file, %lu bytes missing",
- len),
- len);
+ die(Q_("premature end of pack file, %"PRIuMAX" byte missing",
+ "premature end of pack file, %"PRIuMAX" bytes missing",
+ (unsigned int)len),
+ (uintmax_t)len);
from += n;
len -= n;
stream.next_in = inbuf;
@@ -1190,7 +1192,7 @@ static void resolve_deltas(void)
qsort(ref_deltas, nr_ref_deltas, sizeof(struct ref_delta_entry),
compare_ref_delta_entry);
- if (verbose)
+ if (verbose || show_resolving_progress)
progress = start_progress(_("Resolving deltas"),
nr_ref_deltas + nr_ofs_deltas);
@@ -1625,6 +1627,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
struct pack_idx_option opts;
unsigned char pack_sha1[20];
unsigned foreign_nr = 1; /* zero is a "good" value, assume bad */
+ int report_end_of_input = 0;
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(index_pack_usage);
@@ -1694,6 +1697,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
input_len = sizeof(*hdr);
} else if (!strcmp(arg, "-v")) {
verbose = 1;
+ } else if (!strcmp(arg, "--show-resolving-progress")) {
+ show_resolving_progress = 1;
+ } else if (!strcmp(arg, "--report-end-of-input")) {
+ report_end_of_input = 1;
} else if (!strcmp(arg, "-o")) {
if (index_name || (i+1) >= argc)
usage(index_pack_usage);
@@ -1751,6 +1758,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
obj_stat = xcalloc(st_add(nr_objects, 1), sizeof(struct object_stat));
ofs_deltas = xcalloc(nr_objects, sizeof(struct ofs_delta_entry));
parse_pack_objects(pack_sha1);
+ if (report_end_of_input)
+ write_in_full(2, "\0", 1);
resolve_deltas();
conclude_pack(fix_thin_pack, curr_pack, pack_sha1);
free(ofs_deltas);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index b2d8d40a67..3a45f0bcfb 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -397,13 +397,16 @@ int init_db(const char *template_dir, unsigned int flags)
if (!(flags & INIT_DB_QUIET)) {
int len = strlen(git_dir);
- /* TRANSLATORS: The first '%s' is either "Reinitialized
- existing" or "Initialized empty", the second " shared" or
- "", and the last '%s%s' is the verbatim directory name. */
- printf(_("%s%s Git repository in %s%s\n"),
- reinit ? _("Reinitialized existing") : _("Initialized empty"),
- get_shared_repository() ? _(" shared") : "",
- git_dir, len && git_dir[len-1] != '/' ? "/" : "");
+ if (reinit)
+ printf(get_shared_repository()
+ ? _("Reinitialized existing shared Git repository in %s%s\n")
+ : _("Reinitialized existing Git repository in %s%s\n"),
+ git_dir, len && git_dir[len-1] != '/' ? "/" : "");
+ else
+ printf(get_shared_repository()
+ ? _("Initialized empty shared Git repository in %s%s\n")
+ : _("Initialized empty Git repository in %s%s\n"),
+ git_dir, len && git_dir[len-1] != '/' ? "/" : "");
}
return 0;
diff --git a/builtin/log.c b/builtin/log.c
index de47b4e89a..fd1652f52b 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -33,6 +33,7 @@ static const char *default_date_mode = NULL;
static int default_abbrev_commit;
static int default_show_root = 1;
static int default_follow;
+static int default_show_signature;
static int decoration_style;
static int decoration_given;
static int use_mailmap_config;
@@ -119,6 +120,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
rev->abbrev_commit = default_abbrev_commit;
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
+ rev->show_signature = default_show_signature;
DIFF_OPT_SET(&rev->diffopt, ALLOW_TEXTCONV);
if (default_date_mode)
@@ -236,16 +238,17 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
if (rev->commit_format != CMIT_FMT_ONELINE)
putchar(rev->diffopt.line_termination);
}
- printf(_("Final output: %d %s\n"), nr, stage);
+ fprintf(rev->diffopt.file, _("Final output: %d %s\n"), nr, stage);
}
static struct itimerval early_output_timer;
static void log_show_early(struct rev_info *revs, struct commit_list *list)
{
- int i = revs->early_output;
+ int i = revs->early_output, close_file = revs->diffopt.close_file;
int show_header = 1;
+ revs->diffopt.close_file = 0;
sort_in_topological_order(&list, revs->sort_order);
while (list && i) {
struct commit *commit = list->item;
@@ -262,14 +265,19 @@ static void log_show_early(struct rev_info *revs, struct commit_list *list)
case commit_ignore:
break;
case commit_error:
+ if (close_file)
+ fclose(revs->diffopt.file);
return;
}
list = list->next;
}
/* Did we already get enough commits for the early output? */
- if (!i)
+ if (!i) {
+ if (close_file)
+ fclose(revs->diffopt.file);
return;
+ }
/*
* ..if no, then repeat it twice a second until we
@@ -331,7 +339,7 @@ static int cmd_log_walk(struct rev_info *rev)
{
struct commit *commit;
int saved_nrl = 0;
- int saved_dcctc = 0;
+ int saved_dcctc = 0, close_file = rev->diffopt.close_file;
if (rev->early_output)
setup_early_output(rev);
@@ -347,6 +355,7 @@ static int cmd_log_walk(struct rev_info *rev)
* and HAS_CHANGES being accumulated in rev->diffopt, so be careful to
* retain that state information if replacing rev->diffopt in this loop
*/
+ rev->diffopt.close_file = 0;
while ((commit = get_revision(rev)) != NULL) {
if (!log_tree_commit(rev, commit) && rev->max_count >= 0)
/*
@@ -367,6 +376,8 @@ static int cmd_log_walk(struct rev_info *rev)
}
rev->diffopt.degraded_cc_to_c = saved_dcctc;
rev->diffopt.needed_rename_limit = saved_nrl;
+ if (close_file)
+ fclose(rev->diffopt.file);
if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF &&
DIFF_OPT_TST(&rev->diffopt, CHECK_FAILED)) {
@@ -409,6 +420,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
use_mailmap_config = git_config_bool(var, value);
return 0;
}
+ if (!strcmp(var, "log.showsignature")) {
+ default_show_signature = git_config_bool(var, value);
+ return 0;
+ }
if (grep_config(var, value, cb) < 0)
return -1;
@@ -445,7 +460,7 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)
pp.fmt = rev->commit_format;
pp.date_mode = rev->date_mode;
pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
- printf("%s", out.buf);
+ fprintf(rev->diffopt.file, "%s", out.buf);
strbuf_release(&out);
}
@@ -456,7 +471,7 @@ static int show_blob_object(const unsigned char *sha1, struct rev_info *rev, con
char *buf;
unsigned long size;
- fflush(stdout);
+ fflush(rev->diffopt.file);
if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) ||
!DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
return stream_blob_to_fd(1, sha1, NULL, 0);
@@ -496,7 +511,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
}
if (offset < size)
- fwrite(buf + offset, size - offset, 1, stdout);
+ fwrite(buf + offset, size - offset, 1, rev->diffopt.file);
free(buf);
return 0;
}
@@ -505,7 +520,8 @@ static int show_tree_object(const unsigned char *sha1,
struct strbuf *base,
const char *pathname, unsigned mode, int stage, void *context)
{
- printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
+ FILE *file = context;
+ fprintf(file, "%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
return 0;
}
@@ -565,7 +581,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
if (rev.shown_one)
putchar('\n');
- printf("%stag %s%s\n",
+ fprintf(rev.diffopt.file, "%stag %s%s\n",
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
t->tag,
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
@@ -584,12 +600,12 @@ int cmd_show(int argc, const char **argv, const char *prefix)
case OBJ_TREE:
if (rev.shown_one)
putchar('\n');
- printf("%stree %s%s\n\n",
+ fprintf(rev.diffopt.file, "%stree %s%s\n\n",
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, &match_all,
- show_tree_object, NULL);
+ show_tree_object, rev.diffopt.file);
rev.shown_one = 1;
break;
case OBJ_COMMIT:
@@ -795,11 +811,10 @@ static int git_format_config(const char *var, const char *value, void *cb)
return git_log_config(var, value, cb);
}
-static FILE *realstdout = NULL;
static const char *output_directory = NULL;
static int outdir_offset;
-static int reopen_stdout(struct commit *commit, const char *subject,
+static int open_next_file(struct commit *commit, const char *subject,
struct rev_info *rev, int quiet)
{
struct strbuf filename = STRBUF_INIT;
@@ -821,9 +836,9 @@ static int reopen_stdout(struct commit *commit, const char *subject,
fmt_output_subject(&filename, subject, rev);
if (!quiet)
- fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
+ printf("%s\n", filename.buf + outdir_offset);
- if (freopen(filename.buf, "w", stdout) == NULL)
+ if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL)
return error(_("Cannot open patch file %s"), filename.buf);
strbuf_release(&filename);
@@ -882,15 +897,15 @@ static void gen_message_id(struct rev_info *info, char *base)
info->message_id = strbuf_detach(&buf, NULL);
}
-static void print_signature(void)
+static void print_signature(FILE *file)
{
if (!signature || !*signature)
return;
- printf("-- \n%s", signature);
+ fprintf(file, "-- \n%s", signature);
if (signature[strlen(signature)-1] != '\n')
- putchar('\n');
- putchar('\n');
+ putc('\n', file);
+ putc('\n', file);
}
static void add_branch_description(struct strbuf *buf, const char *branch_name)
@@ -959,7 +974,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
committer = git_committer_info(0);
if (!use_stdout &&
- reopen_stdout(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
+ open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
return;
log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
@@ -982,7 +997,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
pp_remainder(&pp, &msg, &sb, 0);
add_branch_description(&sb, branch_name);
- printf("%s\n", sb.buf);
+ fprintf(rev->diffopt.file, "%s\n", sb.buf);
strbuf_release(&sb);
@@ -991,6 +1006,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
log.wrap = 72;
log.in1 = 2;
log.in2 = 4;
+ log.file = rev->diffopt.file;
for (i = 0; i < nr; i++)
shortlog_add_commit(&log, list[i]);
@@ -1013,8 +1029,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
diffcore_std(&opts);
diff_flush(&opts);
- printf("\n");
- print_signature();
+ fprintf(rev->diffopt.file, "\n");
+ print_signature(rev->diffopt.file);
}
static const char *clean_message_id(const char *msg_id)
@@ -1324,7 +1340,7 @@ static void prepare_bases(struct base_tree_info *bases,
}
}
-static void print_bases(struct base_tree_info *bases)
+static void print_bases(struct base_tree_info *bases, FILE *file)
{
int i;
@@ -1333,11 +1349,11 @@ static void print_bases(struct base_tree_info *bases)
return;
/* Show the base commit */
- printf("base-commit: %s\n", oid_to_hex(&bases->base_commit));
+ fprintf(file, "base-commit: %s\n", oid_to_hex(&bases->base_commit));
/* Show the prerequisite patches */
for (i = bases->nr_patch_id - 1; i >= 0; i--)
- printf("prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
+ fprintf(file, "prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
free(bases->patch_id);
bases->nr_patch_id = 0;
@@ -1569,6 +1585,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
setup_pager();
if (output_directory) {
+ if (rev.diffopt.use_color != GIT_COLOR_ALWAYS)
+ rev.diffopt.use_color = GIT_COLOR_NEVER;
if (use_stdout)
die(_("standard output, or directory, which one?"));
if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
@@ -1626,9 +1644,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
get_patch_ids(&rev, &ids);
}
- if (!use_stdout)
- realstdout = xfdopen(xdup(1), "w");
-
if (prepare_revision_walk(&rev))
die(_("revision walk setup failed"));
rev.boundary = 1;
@@ -1693,7 +1708,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
gen_message_id(&rev, "cover");
make_cover_letter(&rev, use_stdout,
origin, nr, list, branch_name, quiet);
- print_bases(&bases);
+ print_bases(&bases, rev.diffopt.file);
total++;
start_number--;
}
@@ -1739,7 +1754,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
}
if (!use_stdout &&
- reopen_stdout(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
+ open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
die(_("Failed to create output files"));
shown = log_tree_commit(&rev, commit);
free_commit_buffer(commit);
@@ -1754,15 +1769,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.shown_one = 0;
if (shown) {
if (rev.mime_boundary)
- printf("\n--%s%s--\n\n\n",
+ fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
mime_boundary_leader,
rev.mime_boundary);
else
- print_signature();
- print_bases(&bases);
+ print_signature(rev.diffopt.file);
+ print_bases(&bases, rev.diffopt.file);
}
if (!use_stdout)
- fclose(stdout);
+ fclose(rev.diffopt.file);
}
free(list);
free(branch_name);
@@ -1794,15 +1809,15 @@ static const char * const cherry_usage[] = {
};
static void print_commit(char sign, struct commit *commit, int verbose,
- int abbrev)
+ int abbrev, FILE *file)
{
if (!verbose) {
- printf("%c %s\n", sign,
+ fprintf(file, "%c %s\n", sign,
find_unique_abbrev(commit->object.oid.hash, abbrev));
} else {
struct strbuf buf = STRBUF_INIT;
pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
- printf("%c %s %s\n", sign,
+ fprintf(file, "%c %s %s\n", sign,
find_unique_abbrev(commit->object.oid.hash, abbrev),
buf.buf);
strbuf_release(&buf);
@@ -1883,7 +1898,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
commit = list->item;
if (has_commit_patch_id(commit, &ids))
sign = '-';
- print_commit(sign, commit, verbose, abbrev);
+ print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
list = list->next;
}
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index 491efd556e..fd2c4556e1 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -9,10 +9,10 @@ static const char builtin_merge_recursive_usage[] =
static const char *better_branch_name(const char *branch)
{
- static char githead_env[8 + 40 + 1];
+ static char githead_env[8 + GIT_SHA1_HEXSZ + 1];
char *name;
- if (strlen(branch) != 40)
+ if (strlen(branch) != GIT_SHA1_HEXSZ)
return branch;
xsnprintf(githead_env, sizeof(githead_env), "GITHEAD_%s", branch);
name = getenv(githead_env);
@@ -21,10 +21,10 @@ static const char *better_branch_name(const char *branch)
int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
{
- const unsigned char *bases[21];
+ const struct object_id *bases[21];
unsigned bases_count = 0;
int i, failed;
- unsigned char h1[20], h2[20];
+ struct object_id h1, h2;
struct merge_options o;
struct commit *result;
@@ -46,10 +46,10 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
continue;
}
if (bases_count < ARRAY_SIZE(bases)-1) {
- unsigned char *sha = xmalloc(20);
- if (get_sha1(argv[i], sha))
+ struct object_id *oid = xmalloc(sizeof(struct object_id));
+ if (get_oid(argv[i], oid))
die("Could not parse object '%s'", argv[i]);
- bases[bases_count++] = sha;
+ bases[bases_count++] = oid;
}
else
warning("Cannot handle more than %d bases. "
@@ -62,9 +62,9 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
o.branch1 = argv[++i];
o.branch2 = argv[++i];
- if (get_sha1(o.branch1, h1))
+ if (get_oid(o.branch1, &h1))
die("Could not resolve ref '%s'", o.branch1);
- if (get_sha1(o.branch2, h2))
+ if (get_oid(o.branch2, &h2))
die("Could not resolve ref '%s'", o.branch2);
o.branch1 = better_branch_name(o.branch1);
@@ -73,7 +73,7 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
if (o.verbosity >= 3)
printf("Merging %s with %s\n", o.branch1, o.branch2);
- failed = merge_recursive_generic(&o, h1, h2, bases_count, bases, &result);
+ failed = merge_recursive_generic(&o, &h1, &h2, bases_count, bases, &result);
if (failed < 0)
return 128; /* die() error code */
return failed;
diff --git a/builtin/merge.c b/builtin/merge.c
index b555a1bf9c..19b3bc2f2f 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -211,7 +211,7 @@ static struct option builtin_merge_options[] = {
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, FF_ONLY },
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
OPT_BOOL(0, "verify-signatures", &verify_signatures,
- N_("Verify that the named commit has a valid GPG signature")),
+ N_("verify that the named commit has a valid GPG signature")),
OPT_CALLBACK('s', "strategy", &use_strategies, N_("strategy"),
N_("merge strategy to use"), option_parse_strategy),
OPT_CALLBACK('X', "strategy-option", &xopts, N_("option=value"),
@@ -336,15 +336,9 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead
struct rev_info rev;
struct strbuf out = STRBUF_INIT;
struct commit_list *j;
- const char *filename;
- int fd;
struct pretty_print_context ctx = {0};
printf(_("Squash commit -- not updating HEAD\n"));
- filename = git_path_squash_msg();
- fd = open(filename, O_WRONLY | O_CREAT, 0666);
- if (fd < 0)
- die_errno(_("Could not write to '%s'"), filename);
init_revisions(&rev, NULL);
rev.ignore_merges = 1;
@@ -371,10 +365,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead
oid_to_hex(&commit->object.oid));
pretty_print_commit(&ctx, commit, &out);
}
- if (write_in_full(fd, out.buf, out.len) != out.len)
- die_errno(_("Writing SQUASH_MSG"));
- if (close(fd))
- die_errno(_("Finishing SQUASH_MSG"));
+ write_file_buf(git_path_squash_msg(), out.buf, out.len);
strbuf_release(&out);
}
@@ -501,7 +492,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
if (ref_exists(truname.buf)) {
strbuf_addf(msg,
"%s\t\tbranch '%s'%s of .\n",
- sha1_to_hex(remote_head->object.oid.hash),
+ oid_to_hex(&remote_head->object.oid),
truname.buf + 11,
(early ? " (early part)" : ""));
strbuf_release(&truname);
@@ -515,7 +506,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
desc = merge_remote_util(remote_head);
if (desc && desc->obj && desc->obj->type == OBJ_TAG) {
strbuf_addf(msg, "%s\t\t%s '%s'\n",
- sha1_to_hex(desc->obj->oid.hash),
+ oid_to_hex(&desc->obj->oid),
typename(desc->obj->type),
remote);
goto cleanup;
@@ -523,7 +514,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
}
strbuf_addf(msg, "%s\t\tcommit '%s'\n",
- sha1_to_hex(remote_head->object.oid.hash), remote);
+ oid_to_hex(&remote_head->object.oid), remote);
cleanup:
strbuf_release(&buf);
strbuf_release(&bname);
@@ -756,18 +747,6 @@ static void add_strategies(const char *string, unsigned attr)
}
-static void write_merge_msg(struct strbuf *msg)
-{
- const char *filename = git_path_merge_msg();
- int fd = open(filename, O_WRONLY | O_CREAT, 0666);
- if (fd < 0)
- die_errno(_("Could not open '%s' for writing"),
- filename);
- if (write_in_full(fd, msg->buf, msg->len) != msg->len)
- die_errno(_("Could not write to '%s'"), filename);
- close(fd);
-}
-
static void read_merge_msg(struct strbuf *msg)
{
const char *filename = git_path_merge_msg();
@@ -801,7 +780,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
strbuf_addch(&msg, '\n');
if (0 < option_edit)
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
- write_merge_msg(&msg);
+ write_file_buf(git_path_merge_msg(), msg.buf, msg.len);
if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
git_path_merge_msg(), "merge", NULL))
abort_commit(remoteheads, NULL);
@@ -964,8 +943,6 @@ static int setup_with_upstream(const char ***argv)
static void write_merge_state(struct commit_list *remoteheads)
{
- const char *filename;
- int fd;
struct commit_list *j;
struct strbuf buf = STRBUF_INIT;
@@ -979,26 +956,14 @@ static void write_merge_state(struct commit_list *remoteheads)
}
strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
}
- filename = git_path_merge_head();
- fd = open(filename, O_WRONLY | O_CREAT, 0666);
- if (fd < 0)
- die_errno(_("Could not open '%s' for writing"), filename);
- if (write_in_full(fd, buf.buf, buf.len) != buf.len)
- die_errno(_("Could not write to '%s'"), filename);
- close(fd);
+ write_file_buf(git_path_merge_head(), buf.buf, buf.len);
strbuf_addch(&merge_msg, '\n');
- write_merge_msg(&merge_msg);
+ write_file_buf(git_path_merge_msg(), merge_msg.buf, merge_msg.len);
- filename = git_path_merge_mode();
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd < 0)
- die_errno(_("Could not open '%s' for writing"), filename);
strbuf_reset(&buf);
if (fast_forward == FF_NO)
strbuf_addf(&buf, "no-ff");
- if (write_in_full(fd, buf.buf, buf.len) != buf.len)
- die_errno(_("Could not write to '%s'"), filename);
- close(fd);
+ write_file_buf(git_path_merge_mode(), buf.buf, buf.len);
}
static int default_edit_option(void)
@@ -1014,7 +979,7 @@ static int default_edit_option(void)
if (e) {
int v = git_config_maybe_bool(name, e);
if (v < 0)
- die("Bad value '%s' in environment '%s'", e, name);
+ die(_("Bad value '%s' in environment '%s'"), e, name);
return v;
}
@@ -1115,7 +1080,7 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge
if (!commit) {
if (ptr)
*ptr = '\0';
- die("not something we can merge in %s: %s",
+ die(_("not something we can merge in %s: %s"),
filename, merge_names->buf + pos);
}
remotes = &commit_list_insert(commit, remotes)->next;
@@ -1149,7 +1114,7 @@ static struct commit_list *collect_parents(struct commit *head_commit,
struct commit *commit = get_merge_parent(argv[i]);
if (!commit)
help_unknown_ref(argv[i], "merge",
- "not something we can merge");
+ _("not something we can merge"));
remotes = &commit_list_insert(commit, remotes)->next;
}
remoteheads = reduce_parents(head_commit, head_subsumed, remoteheads);
@@ -1366,7 +1331,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
for (p = remoteheads; p; p = p->next) {
struct commit *commit = p->item;
strbuf_addf(&buf, "GITHEAD_%s",
- sha1_to_hex(commit->object.oid.hash));
+ oid_to_hex(&commit->object.oid));
setenv(buf.buf, merge_remote_util(commit)->name, 1);
strbuf_reset(&buf);
if (fast_forward != FF_ONLY &&
@@ -1421,11 +1386,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* If head can reach all the merge then we are up to date.
* but first the most common case of merging one remote.
*/
- finish_up_to_date("Already up-to-date.");
+ finish_up_to_date(_("Already up-to-date."));
goto done;
} else if (fast_forward != FF_NO && !remoteheads->next &&
!common->next &&
- !hashcmp(common->item->object.oid.hash, head_commit->object.oid.hash)) {
+ !oidcmp(&common->item->object.oid, &head_commit->object.oid)) {
/* Again the most common case of merging one remote. */
struct strbuf msg = STRBUF_INIT;
struct commit *commit;
@@ -1499,14 +1464,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* HEAD^^" would be missed.
*/
common_one = get_merge_bases(head_commit, j->item);
- if (hashcmp(common_one->item->object.oid.hash,
- j->item->object.oid.hash)) {
+ if (oidcmp(&common_one->item->object.oid, &j->item->object.oid)) {
up_to_date = 0;
break;
}
}
if (up_to_date) {
- finish_up_to_date("Already up-to-date. Yeeah!");
+ finish_up_to_date(_("Already up-to-date. Yeeah!"));
goto done;
}
}
@@ -1530,7 +1494,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* Stash away the local changes so that we can try more than one.
*/
save_state(stash))
- hashcpy(stash, null_sha1);
+ hashclr(stash);
for (i = 0; i < use_strategies_nr; i++) {
int ret;
diff --git a/builtin/notes.c b/builtin/notes.c
index c65b59ad9a..0572051762 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -749,7 +749,7 @@ static int git_config_get_notes_strategy(const char *key,
if (git_config_get_string(key, &value))
return 1;
if (parse_notes_merge_strategy(value, strategy))
- git_die_config(key, "unknown notes merge strategy %s", value);
+ git_die_config(key, _("unknown notes merge strategy %s"), value);
free(value);
return 0;
@@ -788,15 +788,15 @@ static int merge(int argc, const char **argv, const char *prefix)
if (strategy || do_commit + do_abort == 0)
do_merge = 1;
if (do_merge + do_commit + do_abort != 1) {
- error("cannot mix --commit, --abort or -s/--strategy");
+ error(_("cannot mix --commit, --abort or -s/--strategy"));
usage_with_options(git_notes_merge_usage, options);
}
if (do_merge && argc != 1) {
- error("Must specify a notes ref to merge");
+ error(_("Must specify a notes ref to merge"));
usage_with_options(git_notes_merge_usage, options);
} else if (!do_merge && argc) {
- error("too many parameters");
+ error(_("too many parameters"));
usage_with_options(git_notes_merge_usage, options);
}
@@ -817,7 +817,7 @@ static int merge(int argc, const char **argv, const char *prefix)
if (strategy) {
if (parse_notes_merge_strategy(strategy, &o.strategy)) {
- error("Unknown -s/--strategy: %s", strategy);
+ error(_("Unknown -s/--strategy: %s"), strategy);
usage_with_options(git_notes_merge_usage, options);
}
} else {
@@ -857,11 +857,11 @@ static int merge(int argc, const char **argv, const char *prefix)
die(_("A notes merge into %s is already in-progress at %s"),
default_notes_ref(), wt->path);
if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL))
- die("Failed to store link to current notes ref (%s)",
+ die(_("Failed to store link to current notes ref (%s)"),
default_notes_ref());
- printf("Automatic notes merge failed. Fix conflicts in %s and "
- "commit the result with 'git notes merge --commit', or "
- "abort the merge with 'git notes merge --abort'.\n",
+ printf(_("Automatic notes merge failed. Fix conflicts in %s and "
+ "commit the result with 'git notes merge --commit', or "
+ "abort the merge with 'git notes merge --abort'.\n"),
git_path(NOTES_MERGE_WORKTREE));
}
@@ -934,8 +934,8 @@ 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__DRY_RUN(&show_only, "do not remove, show only"),
- OPT__VERBOSE(&verbose, "report pruned notes"),
+ OPT__DRY_RUN(&show_only, N_("do not remove, show only")),
+ OPT__VERBOSE(&verbose, N_("report pruned notes")),
OPT_END()
};
@@ -964,7 +964,7 @@ static int get_ref(int argc, const char **argv, const char *prefix)
git_notes_get_ref_usage, 0);
if (argc) {
- error("too many parameters");
+ error(_("too many parameters"));
usage_with_options(git_notes_get_ref_usage, options);
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index a2f8cfdec0..92e2e5f7a8 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -342,15 +342,15 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
}
/* Return 0 if we will bust the pack-size limit */
-static unsigned long write_reuse_object(struct sha1file *f, struct object_entry *entry,
- unsigned long limit, int usable_delta)
+static off_t write_reuse_object(struct sha1file *f, struct object_entry *entry,
+ unsigned long limit, int usable_delta)
{
struct packed_git *p = entry->in_pack;
struct pack_window *w_curs = NULL;
struct revindex_entry *revidx;
off_t offset;
enum object_type type = entry->type;
- unsigned long datalen;
+ off_t datalen;
unsigned char header[10], dheader[10];
unsigned hdrlen;
@@ -416,11 +416,12 @@ static unsigned long write_reuse_object(struct sha1file *f, struct object_entry
}
/* Return 0 if we will bust the pack-size limit */
-static unsigned long write_object(struct sha1file *f,
- struct object_entry *entry,
- off_t write_offset)
+static off_t write_object(struct sha1file *f,
+ struct object_entry *entry,
+ off_t write_offset)
{
- unsigned long limit, len;
+ unsigned long limit;
+ off_t len;
int usable_delta, to_reuse;
if (!pack_to_stdout)
@@ -492,7 +493,7 @@ static enum write_one_status write_one(struct sha1file *f,
struct object_entry *e,
off_t *offset)
{
- unsigned long size;
+ off_t size;
int recursing;
/*
diff --git a/builtin/pull.c b/builtin/pull.c
index 897a7f4e4e..398aae16c0 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -855,7 +855,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
git_config(git_pull_config, NULL);
if (read_cache_unmerged())
- die_resolve_conflict("Pull");
+ die_resolve_conflict("pull");
if (file_exists(git_path("MERGE_HEAD")))
die_conclude_merge();
diff --git a/builtin/push.c b/builtin/push.c
index 4e9e4dbab2..3bb9d6b7e6 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -353,7 +353,8 @@ static int push_with_options(struct transport *transport, int flags)
return 1;
}
-static int do_push(const char *repo, int flags)
+static int do_push(const char *repo, int flags,
+ const struct string_list *push_options)
{
int i, errs;
struct remote *remote = pushremote_get(repo);
@@ -376,6 +377,9 @@ static int do_push(const char *repo, int flags)
if (remote->mirror)
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
+ if (push_options->nr)
+ flags |= TRANSPORT_PUSH_OPTIONS;
+
if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
if (!strcmp(*refspec, "refs/tags/*"))
return error(_("--all and --tags are incompatible"));
@@ -406,13 +410,16 @@ static int do_push(const char *repo, int flags)
for (i = 0; i < url_nr; i++) {
struct transport *transport =
transport_get(remote, url[i]);
+ if (flags & TRANSPORT_PUSH_OPTIONS)
+ transport->push_options = push_options;
if (push_with_options(transport, flags))
errs++;
}
} else {
struct transport *transport =
transport_get(remote, NULL);
-
+ if (flags & TRANSPORT_PUSH_OPTIONS)
+ transport->push_options = push_options;
if (push_with_options(transport, flags))
errs++;
}
@@ -500,6 +507,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
int push_cert = -1;
int rc;
const char *repo = NULL; /* default repository */
+ static struct string_list push_options = STRING_LIST_INIT_DUP;
+ static struct string_list_item *item;
+
struct option options[] = {
OPT__VERBOSITY(&verbosity),
OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
@@ -533,6 +543,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
PARSE_OPT_OPTARG, option_parse_push_signed },
OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
+ OPT_STRING_LIST('o', "push-option", &push_options, N_("server-specific"), N_("option to transmit")),
OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
TRANSPORT_FAMILY_IPV4),
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
@@ -563,7 +574,11 @@ int cmd_push(int argc, const char **argv, const char *prefix)
set_refspecs(argv + 1, argc - 1, repo);
}
- rc = do_push(repo, flags);
+ for_each_string_list_item(item, &push_options)
+ if (strchr(item->string, '\n'))
+ die(_("push options must not have new line characters"));
+
+ rc = do_push(repo, flags, &push_options);
if (rc == -1)
usage_with_options(push_usage, options);
else
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 15c323a7cd..92e1213ecc 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -44,10 +44,12 @@ static struct strbuf fsck_msg_types = STRBUF_INIT;
static int receive_unpack_limit = -1;
static int transfer_unpack_limit = -1;
static int advertise_atomic_push = 1;
+static int advertise_push_options;
static int unpack_limit = 100;
static int report_status;
static int use_sideband;
static int use_atomic;
+static int use_push_options;
static int quiet;
static int prefer_ofs_delta = 1;
static int auto_update_server_info;
@@ -76,6 +78,13 @@ static long nonce_stamp_slop;
static unsigned long nonce_stamp_slop_limit;
static struct ref_transaction *transaction;
+static enum {
+ KEEPALIVE_NEVER = 0,
+ KEEPALIVE_AFTER_NUL,
+ KEEPALIVE_ALWAYS
+} use_keepalive;
+static int keepalive_in_sec = 5;
+
static enum deny_action parse_deny_action(const char *var, const char *value)
{
if (value) {
@@ -193,6 +202,16 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (strcmp(var, "receive.advertisepushoptions") == 0) {
+ advertise_push_options = git_config_bool(var, value);
+ return 0;
+ }
+
+ if (strcmp(var, "receive.keepalive") == 0) {
+ keepalive_in_sec = git_config_int(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
@@ -211,6 +230,8 @@ static void show_ref(const char *path, const unsigned char *sha1)
strbuf_addstr(&cap, " ofs-delta");
if (push_cert_nonce)
strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
+ if (advertise_push_options)
+ strbuf_addstr(&cap, " push-options");
strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
packet_write(1, "%s %s%c%s\n",
sha1_to_hex(sha1), path, 0, cap.buf);
@@ -319,10 +340,60 @@ static void rp_error(const char *err, ...)
static int copy_to_sideband(int in, int out, void *arg)
{
char data[128];
+ int keepalive_active = 0;
+
+ if (keepalive_in_sec <= 0)
+ use_keepalive = KEEPALIVE_NEVER;
+ if (use_keepalive == KEEPALIVE_ALWAYS)
+ keepalive_active = 1;
+
while (1) {
- ssize_t sz = xread(in, data, sizeof(data));
+ ssize_t sz;
+
+ if (keepalive_active) {
+ struct pollfd pfd;
+ int ret;
+
+ pfd.fd = in;
+ pfd.events = POLLIN;
+ ret = poll(&pfd, 1, 1000 * keepalive_in_sec);
+
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ break;
+ } else if (ret == 0) {
+ /* no data; send a keepalive packet */
+ static const char buf[] = "0005\1";
+ write_or_die(1, buf, sizeof(buf) - 1);
+ continue;
+ } /* else there is actual data to read */
+ }
+
+ sz = xread(in, data, sizeof(data));
if (sz <= 0)
break;
+
+ if (use_keepalive == KEEPALIVE_AFTER_NUL && !keepalive_active) {
+ const char *p = memchr(data, '\0', sz);
+ if (p) {
+ /*
+ * The NUL tells us to start sending keepalives. Make
+ * sure we send any other data we read along
+ * with it.
+ */
+ keepalive_active = 1;
+ send_sideband(1, 2, data, p - data, use_sideband);
+ send_sideband(1, 2, p + 1, sz - (p - data + 1), use_sideband);
+ continue;
+ }
+ }
+
+ /*
+ * Either we're not looking for a NUL signal, or we didn't see
+ * it yet; just pass along the data.
+ */
send_sideband(1, 2, data, sz, use_sideband);
}
close(in);
@@ -550,8 +621,16 @@ static void prepare_push_cert_sha1(struct child_process *proc)
}
}
+struct receive_hook_feed_state {
+ struct command *cmd;
+ int skip_broken;
+ struct strbuf buf;
+ const struct string_list *push_options;
+};
+
typedef int (*feed_fn)(void *, const char **, size_t *);
-static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)
+static int run_and_feed_hook(const char *hook_name, feed_fn feed,
+ struct receive_hook_feed_state *feed_state)
{
struct child_process proc = CHILD_PROCESS_INIT;
struct async muxer;
@@ -567,6 +646,16 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_sta
proc.argv = argv;
proc.in = -1;
proc.stdout_to_stderr = 1;
+ if (feed_state->push_options) {
+ int i;
+ for (i = 0; i < feed_state->push_options->nr; i++)
+ argv_array_pushf(&proc.env_array,
+ "GIT_PUSH_OPTION_%d=%s", i,
+ feed_state->push_options->items[i].string);
+ argv_array_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%d",
+ feed_state->push_options->nr);
+ } else
+ argv_array_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT");
if (use_sideband) {
memset(&muxer, 0, sizeof(muxer));
@@ -606,12 +695,6 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_sta
return finish_command(&proc);
}
-struct receive_hook_feed_state {
- struct command *cmd;
- int skip_broken;
- struct strbuf buf;
-};
-
static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
{
struct receive_hook_feed_state *state = state_;
@@ -634,8 +717,10 @@ static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
return 0;
}
-static int run_receive_hook(struct command *commands, const char *hook_name,
- int skip_broken)
+static int run_receive_hook(struct command *commands,
+ const char *hook_name,
+ int skip_broken,
+ const struct string_list *push_options)
{
struct receive_hook_feed_state state;
int status;
@@ -646,6 +731,7 @@ static int run_receive_hook(struct command *commands, const char *hook_name,
if (feed_receive_hook(&state, NULL, NULL))
return 0;
state.cmd = commands;
+ state.push_options = push_options;
status = run_and_feed_hook(hook_name, feed_receive_hook, &state);
strbuf_release(&state.buf);
return status;
@@ -737,7 +823,7 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
{
static struct lock_file shallow_lock;
struct sha1_array extra = SHA1_ARRAY_INIT;
- const char *alt_file;
+ struct check_connected_options opt = CHECK_CONNECTED_INIT;
uint32_t mask = 1 << (cmd->index % 32);
int i;
@@ -749,9 +835,8 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
!delayed_reachability_test(si, i))
sha1_array_append(&extra, si->shallow->sha1[i]);
- setup_alternate_shallow(&shallow_lock, &alt_file, &extra);
- if (check_shallow_connected(command_singleton_iterator,
- 0, cmd, alt_file)) {
+ setup_alternate_shallow(&shallow_lock, &opt.shallow_file, &extra);
+ if (check_connected(command_singleton_iterator, cmd, &opt)) {
rollback_lock_file(&shallow_lock);
sha1_array_clear(&extra);
return -1;
@@ -1160,8 +1245,8 @@ static void set_connectivity_errors(struct command *commands,
if (shallow_update && si->shallow_ref[cmd->index])
/* to be checked in update_shallow_ref() */
continue;
- if (!check_everything_connected(command_singleton_iterator,
- 0, &singleton))
+ if (!check_connected(command_singleton_iterator, &singleton,
+ NULL))
continue;
cmd->error_string = "missing necessary objects";
}
@@ -1316,11 +1401,15 @@ cleanup:
static void execute_commands(struct command *commands,
const char *unpacker_error,
- struct shallow_info *si)
+ struct shallow_info *si,
+ const struct string_list *push_options)
{
+ struct check_connected_options opt = CHECK_CONNECTED_INIT;
struct command *cmd;
unsigned char sha1[20];
struct iterate_data data;
+ struct async muxer;
+ int err_fd = 0;
if (unpacker_error) {
for (cmd = commands; cmd; cmd = cmd->next)
@@ -1328,14 +1417,28 @@ static void execute_commands(struct command *commands,
return;
}
+ if (use_sideband) {
+ memset(&muxer, 0, sizeof(muxer));
+ muxer.proc = copy_to_sideband;
+ muxer.in = -1;
+ if (!start_async(&muxer))
+ err_fd = muxer.in;
+ /* ...else, continue without relaying sideband */
+ }
+
data.cmds = commands;
data.si = si;
- if (check_everything_connected(iterate_receive_command_list, 0, &data))
+ opt.err_fd = err_fd;
+ opt.progress = err_fd && !quiet;
+ if (check_connected(iterate_receive_command_list, &data, &opt))
set_connectivity_errors(commands, si);
+ if (use_sideband)
+ finish_async(&muxer);
+
reject_updates_to_hidden(commands);
- if (run_receive_hook(commands, "pre-receive", 0)) {
+ if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->error_string)
cmd->error_string = "pre-receive hook declined";
@@ -1439,6 +1542,9 @@ static struct command *read_head_info(struct sha1_array *shallow)
if (advertise_atomic_push
&& parse_feature_request(feature_list, "atomic"))
use_atomic = 1;
+ if (advertise_push_options
+ && parse_feature_request(feature_list, "push-options"))
+ use_push_options = 1;
}
if (!strcmp(line, "push-cert")) {
@@ -1471,6 +1577,21 @@ static struct command *read_head_info(struct sha1_array *shallow)
return commands;
}
+static void read_push_options(struct string_list *options)
+{
+ while (1) {
+ char *line;
+ int len;
+
+ line = packet_read_line(0, &len);
+
+ if (!line)
+ break;
+
+ string_list_append(options, line);
+ }
+}
+
static const char *parse_pack_header(struct pack_header *hdr)
{
switch (read_pack_header(0, hdr)) {
@@ -1548,6 +1669,10 @@ static const char *unpack(int err_fd, struct shallow_info *si)
(uintmax_t)getpid(),
hostname);
+ if (!quiet && err_fd)
+ argv_array_push(&child.args, "--show-resolving-progress");
+ if (use_sideband)
+ argv_array_push(&child.args, "--report-end-of-input");
if (fsck_objects)
argv_array_pushf(&child.args, "--strict%s",
fsck_msg_types.buf);
@@ -1577,6 +1702,7 @@ static const char *unpack_with_sideband(struct shallow_info *si)
if (!use_sideband)
return unpack(0, si);
+ use_keepalive = KEEPALIVE_AFTER_NUL;
memset(&muxer, 0, sizeof(muxer));
muxer.proc = copy_to_sideband;
muxer.in = -1;
@@ -1756,6 +1882,10 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
if ((commands = read_head_info(&shallow)) != NULL) {
const char *unpack_status = NULL;
+ struct string_list push_options = STRING_LIST_INIT_DUP;
+
+ if (use_push_options)
+ read_push_options(&push_options);
prepare_shallow_info(&si, &shallow);
if (!si.nr_ours && !si.nr_theirs)
@@ -1764,13 +1894,18 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
unpack_status = unpack_with_sideband(&si);
update_shallow_info(commands, &si, &ref);
}
- execute_commands(commands, unpack_status, &si);
+ use_keepalive = KEEPALIVE_ALWAYS;
+ execute_commands(commands, unpack_status, &si,
+ &push_options);
if (pack_lockfile)
unlink_or_warn(pack_lockfile);
if (report_status)
report(commands, unpack_status);
- run_receive_hook(commands, "post-receive", 1);
+ run_receive_hook(commands, "post-receive", 1,
+ &push_options);
run_update_post_hook(commands);
+ if (push_options.nr)
+ string_list_clear(&push_options, 0);
if (auto_gc) {
const char *argv_gc_auto[] = {
"gc", "--auto", "--quiet", NULL,
diff --git a/builtin/remote.c b/builtin/remote.c
index 5ded3018af..9f6a6b3a9c 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -539,10 +539,6 @@ static int add_branch_for_removal(const char *refname,
return 0;
}
- /* make sure that symrefs are deleted */
- if (flags & REF_ISSYMREF)
- return unlink(git_path("%s", refname));
-
string_list_append(branches->branches, refname);
return 0;
@@ -788,7 +784,7 @@ static int rm(int argc, const char **argv)
strbuf_release(&buf);
if (!result)
- result = delete_refs(&branches);
+ result = delete_refs(&branches, REF_NODEREF);
string_list_clear(&branches, 0);
if (skipped.nr) {
@@ -952,7 +948,7 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
struct show_info *show_info = cb_data;
struct branch_info *branch_info = item->util;
struct string_list *merge = &branch_info->merge;
- const char *also;
+ int width = show_info->width + 4;
int i;
if (branch_info->rebase && branch_info->merge.nr > 1) {
@@ -963,19 +959,18 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
printf(" %-*s ", show_info->width, item->string);
if (branch_info->rebase) {
- printf_ln(_(branch_info->rebase == INTERACTIVE_REBASE ?
- "rebases interactively onto remote %s" :
- "rebases onto remote %s"), merge->items[0].string);
+ printf_ln(branch_info->rebase == INTERACTIVE_REBASE
+ ? _("rebases interactively onto remote %s")
+ : _("rebases onto remote %s"), merge->items[0].string);
return 0;
} else if (show_info->any_rebase) {
printf_ln(_(" merges with remote %s"), merge->items[0].string);
- also = _(" and with remote");
+ width++;
} else {
printf_ln(_("merges with remote %s"), merge->items[0].string);
- also = _(" and with remote");
}
for (i = 1; i < merge->nr; i++)
- printf(" %-*s %s %s\n", show_info->width, "", also,
+ printf(_("%-*s and with remote %s\n"), width, "",
merge->items[i].string);
return 0;
@@ -1158,11 +1153,11 @@ static int show(int argc, const char **argv)
the one in " Fetch URL: %s" translation */
printf_ln(_(" Push URL: %s"), url[i]);
if (!i)
- printf_ln(_(" Push URL: %s"), "(no URL)");
+ printf_ln(_(" Push URL: %s"), _("(no URL)"));
if (no_query)
- printf_ln(_(" HEAD branch: %s"), "(not queried)");
+ printf_ln(_(" HEAD branch: %s"), _("(not queried)"));
else if (!states.heads.nr)
- printf_ln(_(" HEAD branch: %s"), "(unknown)");
+ printf_ln(_(" HEAD branch: %s"), _("(unknown)"));
else if (states.heads.nr == 1)
printf_ln(_(" HEAD branch: %s"), states.heads.items[0].string);
else {
@@ -1305,7 +1300,7 @@ static int prune_remote(const char *remote, int dry_run)
string_list_sort(&refs_to_prune);
if (!dry_run)
- result |= delete_refs(&refs_to_prune);
+ result |= delete_refs(&refs_to_prune, 0);
for_each_string_list_item(item, &states.stale) {
const char *refname = item->util;
diff --git a/builtin/repack.c b/builtin/repack.c
index f7b7409cb7..80dd06b4a2 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -388,7 +388,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
item->string,
exts[ext].name);
if (remove_path(fname))
- warning(_("removing '%s' failed"), fname);
+ warning(_("failed to remove '%s'"), fname);
free(fname);
}
}
diff --git a/builtin/reset.c b/builtin/reset.c
index acd6278868..9020ec66c8 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -103,7 +103,7 @@ static void print_new_head_line(struct commit *commit)
if (body) {
const char *eol;
size_t len;
- body += 2;
+ body = skip_blank_lines(body + 2);
eol = strchr(body, '\n');
len = eol ? eol - body : strlen(body);
printf(" %.*s\n", (int) len, body);
@@ -121,7 +121,7 @@ static void update_index_from_diff(struct diff_queue_struct *q,
for (i = 0; i < q->nr; i++) {
struct diff_filespec *one = q->queue[i]->one;
- int is_missing = !(one->mode && !is_null_sha1(one->sha1));
+ int is_missing = !(one->mode && !is_null_oid(&one->oid));
struct cache_entry *ce;
if (is_missing && !intent_to_add) {
@@ -129,7 +129,7 @@ static void update_index_from_diff(struct diff_queue_struct *q,
continue;
}
- ce = make_cache_entry(one->mode, one->sha1, one->path,
+ ce = make_cache_entry(one->mode, one->oid.hash, one->path,
0, 0);
if (!ce)
die(_("make_cache_entry failed for path '%s'"),
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index b82bcc3436..0ba82b1635 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -9,6 +9,7 @@
#include "log-tree.h"
#include "graph.h"
#include "bisect.h"
+#include "progress.h"
static const char rev_list_usage[] =
"git rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
@@ -49,12 +50,17 @@ static const char rev_list_usage[] =
" --bisect-all"
;
+static struct progress *progress;
+static unsigned progress_counter;
+
static void finish_commit(struct commit *commit, void *data);
static void show_commit(struct commit *commit, void *data)
{
struct rev_list_info *info = data;
struct rev_info *revs = info->revs;
+ display_progress(progress, ++progress_counter);
+
if (info->flags & REV_LIST_QUIET) {
finish_commit(commit, data);
return;
@@ -190,6 +196,7 @@ static void show_object(struct object *obj, const char *name, void *cb_data)
{
struct rev_list_info *info = cb_data;
finish_object(obj, name, cb_data);
+ display_progress(progress, ++progress_counter);
if (info->flags & REV_LIST_QUIET)
return;
show_object_with_name(stdout, obj, name);
@@ -276,6 +283,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
int bisect_show_vars = 0;
int bisect_find_all = 0;
int use_bitmap_index = 0;
+ const char *show_progress = NULL;
git_config(git_default_config, NULL);
init_revisions(&revs, prefix);
@@ -325,6 +333,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
test_bitmap_walk(&revs);
return 0;
}
+ if (skip_prefix(arg, "--progress=", &arg)) {
+ show_progress = arg;
+ continue;
+ }
usage(rev_list_usage);
}
@@ -355,6 +367,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
if (bisect_list)
revs.limited = 1;
+ if (show_progress)
+ progress = start_progress_delay(show_progress, 0, 0, 2);
+
if (use_bitmap_index && !revs.prune) {
if (revs.count && !revs.left_right && !revs.cherry_mark) {
uint32_t commit_count;
@@ -392,6 +407,8 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
traverse_commit_list(&revs, show_commit, show_object, &info);
+ stop_progress(&progress);
+
if (revs.count) {
if (revs.left_right && revs.cherry_mark)
printf("%d\t%d\t%d\n", revs.count_left, revs.count_right, revs.count_same);
diff --git a/builtin/revert.c b/builtin/revert.c
index 56a2c36669..4e693808b1 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -76,7 +76,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
const char *me = action_name(opts);
int cmd = 0;
- struct option options[] = {
+ struct option base_options[] = {
OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'),
OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'),
OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'),
@@ -91,13 +91,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
N_("option for merge strategy"), option_parse_x),
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
- OPT_END(),
- OPT_END(),
- OPT_END(),
- OPT_END(),
- OPT_END(),
- OPT_END(),
+ OPT_END()
};
+ struct option *options = base_options;
if (opts->action == REPLAY_PICK) {
struct option cp_extra[] = {
@@ -108,8 +104,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
OPT_BOOL(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
OPT_END(),
};
- if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
- die(_("program error"));
+ options = parse_options_concat(options, cp_extra);
}
argc = parse_options(argc, argv, NULL, options, usage_str,
diff --git a/builtin/rm.c b/builtin/rm.c
index 8abb0207fa..b2fee3e90a 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -387,6 +387,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
*/
if (!index_only) {
int removed = 0, gitmodules_modified = 0;
+ struct strbuf buf = STRBUF_INIT;
for (i = 0; i < list.nr; i++) {
const char *path = list.entry[i].name;
if (list.entry[i].is_submodule) {
@@ -398,7 +399,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
continue;
}
} else {
- struct strbuf buf = STRBUF_INIT;
+ strbuf_reset(&buf);
strbuf_addstr(&buf, path);
if (!remove_dir_recursively(&buf, 0)) {
removed = 1;
@@ -410,7 +411,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
/* Submodule was removed by user */
if (!remove_path_from_gitmodules(path))
gitmodules_modified = 1;
- strbuf_release(&buf);
/* Fallthrough and let remove_path() fail. */
}
}
@@ -421,6 +421,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (!removed)
die_errno("git rm: '%s'", path);
}
+ strbuf_release(&buf);
if (gitmodules_modified)
stage_updated_gitmodules();
}
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index f83984e8a1..25fa8a6aed 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -276,6 +276,7 @@ parse_done:
log.user_format = rev.commit_format == CMIT_FMT_USERFORMAT;
log.abbrev = rev.abbrev;
+ log.file = rev.diffopt.file;
/* assume HEAD if from a tty */
if (!nongit && !rev.pending.nr && isatty(0))
@@ -289,6 +290,8 @@ parse_done:
get_from_rev(&rev, &log);
shortlog_output(&log);
+ if (log.file != stdout)
+ fclose(log.file);
return 0;
}
@@ -310,22 +313,24 @@ void shortlog_output(struct shortlog *log)
for (i = 0; i < log->list.nr; i++) {
const struct string_list_item *item = &log->list.items[i];
if (log->summary) {
- printf("%6d\t%s\n", (int)UTIL_TO_INT(item), item->string);
+ fprintf(log->file, "%6d\t%s\n",
+ (int)UTIL_TO_INT(item), item->string);
} else {
struct string_list *onelines = item->util;
- printf("%s (%d):\n", item->string, onelines->nr);
+ fprintf(log->file, "%s (%d):\n",
+ item->string, onelines->nr);
for (j = onelines->nr - 1; j >= 0; j--) {
const char *msg = onelines->items[j].string;
if (log->wrap_lines) {
strbuf_reset(&sb);
add_wrapped_shortlog_msg(&sb, msg, log);
- fwrite(sb.buf, sb.len, 1, stdout);
+ fwrite(sb.buf, sb.len, 1, log->file);
}
else
- printf(" %s\n", msg);
+ fprintf(log->file, " %s\n", msg);
}
- putchar('\n');
+ putc('\n', log->file);
onelines->strdup_strings = 1;
string_list_clear(onelines, 0);
free(onelines);
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 875e7ed998..172470bf24 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -355,7 +355,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
return; /* we are done */
else {
/* cannot resolve yet --- queue it */
- hashcpy(obj_list[nr].sha1, null_sha1);
+ hashclr(obj_list[nr].sha1);
add_delta_to_list(nr, base_sha1, 0, delta_data, delta_size);
return;
}
@@ -406,7 +406,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
* The delta base object is itself a delta that
* has not been resolved yet.
*/
- hashcpy(obj_list[nr].sha1, null_sha1);
+ hashclr(obj_list[nr].sha1);
add_delta_to_list(nr, null_sha1, base_offset, delta_data, delta_size);
return;
}
diff --git a/builtin/worktree.c b/builtin/worktree.c
index e866844685..5a41788edb 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -14,7 +14,9 @@
static const char * const worktree_usage[] = {
N_("git worktree add [<options>] <path> [<branch>]"),
N_("git worktree list [<options>]"),
+ N_("git worktree lock [<options>] <path>"),
N_("git worktree prune [<options>]"),
+ N_("git worktree unlock <path>"),
NULL
};
@@ -262,7 +264,7 @@ static int add_worktree(const char *path, const char *refname,
*/
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
- write_file(sb.buf, sha1_to_hex(null_sha1));
+ write_file(sb.buf, "%s", sha1_to_hex(null_sha1));
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
@@ -462,6 +464,66 @@ static int list(int ac, const char **av, const char *prefix)
return 0;
}
+static int lock_worktree(int ac, const char **av, const char *prefix)
+{
+ const char *reason = "", *old_reason;
+ struct option options[] = {
+ OPT_STRING(0, "reason", &reason, N_("string"),
+ N_("reason for locking")),
+ OPT_END()
+ };
+ struct worktree **worktrees, *wt;
+
+ ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ if (ac != 1)
+ usage_with_options(worktree_usage, options);
+
+ worktrees = get_worktrees();
+ wt = find_worktree(worktrees, prefix, av[0]);
+ if (!wt)
+ die(_("'%s' is not a working tree"), av[0]);
+ if (is_main_worktree(wt))
+ die(_("The main working tree cannot be locked or unlocked"));
+
+ old_reason = is_worktree_locked(wt);
+ if (old_reason) {
+ if (*old_reason)
+ die(_("'%s' is already locked, reason: %s"),
+ av[0], old_reason);
+ die(_("'%s' is already locked"), av[0]);
+ }
+
+ write_file(git_common_path("worktrees/%s/locked", wt->id),
+ "%s", reason);
+ free_worktrees(worktrees);
+ return 0;
+}
+
+static int unlock_worktree(int ac, const char **av, const char *prefix)
+{
+ struct option options[] = {
+ OPT_END()
+ };
+ struct worktree **worktrees, *wt;
+ int ret;
+
+ ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
+ if (ac != 1)
+ usage_with_options(worktree_usage, options);
+
+ worktrees = get_worktrees();
+ wt = find_worktree(worktrees, prefix, av[0]);
+ if (!wt)
+ die(_("'%s' is not a working tree"), av[0]);
+ if (is_main_worktree(wt))
+ die(_("The main working tree cannot be locked or unlocked"));
+ if (!is_worktree_locked(wt))
+ die(_("'%s' is not locked"), av[0]);
+ ret = unlink_or_warn(git_common_path("worktrees/%s/locked", wt->id));
+ free_worktrees(worktrees);
+ return ret;
+}
+
int cmd_worktree(int ac, const char **av, const char *prefix)
{
struct option options[] = {
@@ -478,5 +540,9 @@ int cmd_worktree(int ac, const char **av, const char *prefix)
return prune(ac - 1, av + 1, prefix);
if (!strcmp(av[1], "list"))
return list(ac - 1, av + 1, prefix);
+ if (!strcmp(av[1], "lock"))
+ return lock_worktree(ac - 1, av + 1, prefix);
+ if (!strcmp(av[1], "unlock"))
+ return unlock_worktree(ac - 1, av + 1, prefix);
usage_with_options(worktree_usage, options);
}