summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c21
-rw-r--r--builtin/blame.c2
-rw-r--r--builtin/cat-file.c15
-rw-r--r--builtin/checkout.c8
-rw-r--r--builtin/clone.c4
-rw-r--r--builtin/commit.c49
-rw-r--r--builtin/gc.c10
-rw-r--r--builtin/index-pack.c4
-rw-r--r--builtin/merge.c6
-rw-r--r--builtin/mv.c9
-rw-r--r--builtin/pack-objects.c42
11 files changed, 117 insertions, 53 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 4b045bace1..459208a326 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -15,6 +15,7 @@
#include "diffcore.h"
#include "revision.h"
#include "bulk-checkin.h"
+#include "argv-array.h"
static const char * const builtin_add_usage[] = {
N_("git add [options] [--] <pathspec>..."),
@@ -141,23 +142,21 @@ static void refresh(int verbose, const struct pathspec *pathspec)
int run_add_interactive(const char *revision, const char *patch_mode,
const struct pathspec *pathspec)
{
- int status, ac, i;
- const char **args;
+ int status, i;
+ struct argv_array argv = ARGV_ARRAY_INIT;
- args = xcalloc(sizeof(const char *), (pathspec->nr + 6));
- ac = 0;
- args[ac++] = "add--interactive";
+ argv_array_push(&argv, "add--interactive");
if (patch_mode)
- args[ac++] = patch_mode;
+ argv_array_push(&argv, patch_mode);
if (revision)
- args[ac++] = revision;
- args[ac++] = "--";
+ argv_array_push(&argv, revision);
+ argv_array_push(&argv, "--");
for (i = 0; i < pathspec->nr; i++)
/* pass original pathspec, to be re-parsed */
- args[ac++] = pathspec->items[i].original;
+ argv_array_push(&argv, pathspec->items[i].original);
- status = run_command_v_opt(args, RUN_GIT_CMD);
- free(args);
+ status = run_command_v_opt(argv.argv, RUN_GIT_CMD);
+ argv_array_clear(&argv);
return status;
}
diff --git a/builtin/blame.c b/builtin/blame.c
index e5b5d71bad..88cb799727 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -74,7 +74,7 @@ static unsigned blame_copy_score;
#define BLAME_DEFAULT_MOVE_SCORE 20
#define BLAME_DEFAULT_COPY_SCORE 40
-/* bits #0..7 in revision.h, #8..11 used for merge_bases() in commit.c */
+/* Remember to update object flag allocation in object.h */
#define METAINFO_SHOWN (1u<<12)
#define MORE_THAN_ONE_PATH (1u<<13)
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index d5a93e0e91..707330499f 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -269,6 +269,8 @@ static int batch_objects(struct batch_options *opt)
{
struct strbuf buf = STRBUF_INIT;
struct expand_data data;
+ int save_warning;
+ int retval = 0;
if (!opt->format)
opt->format = "%(objectname) %(objecttype) %(objectsize)";
@@ -297,11 +299,10 @@ static int batch_objects(struct batch_options *opt)
* warn) ends up dwarfing the actual cost of the object lookups
* themselves. We can work around it by just turning off the warning.
*/
+ save_warning = warn_on_object_refname_ambiguity;
warn_on_object_refname_ambiguity = 0;
while (strbuf_getline(&buf, stdin, '\n') != EOF) {
- int error;
-
if (data.split_on_whitespace) {
/*
* Split at first whitespace, tying off the beginning
@@ -316,12 +317,14 @@ static int batch_objects(struct batch_options *opt)
data.rest = p;
}
- error = batch_one_object(buf.buf, opt, &data);
- if (error)
- return error;
+ retval = batch_one_object(buf.buf, opt, &data);
+ if (retval)
+ break;
}
- return 0;
+ strbuf_release(&buf);
+ warn_on_object_refname_ambiguity = save_warning;
+ return retval;
}
static const char * const cat_file_usage[] = {
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a0e72d21e0..5b07757d4f 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -53,10 +53,10 @@ struct checkout_opts {
static int post_checkout_hook(struct commit *old, struct commit *new,
int changed)
{
- return run_hook(NULL, "post-checkout",
- sha1_to_hex(old ? old->object.sha1 : null_sha1),
- sha1_to_hex(new ? new->object.sha1 : null_sha1),
- changed ? "1" : "0", NULL);
+ return run_hook_le(NULL, "post-checkout",
+ sha1_to_hex(old ? old->object.sha1 : null_sha1),
+ sha1_to_hex(new ? new->object.sha1 : null_sha1),
+ changed ? "1" : "0", NULL);
/* "new" can be NULL when checking out from the index before
a commit exists. */
diff --git a/builtin/clone.c b/builtin/clone.c
index 43e772ccdb..9b3c04d914 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -660,8 +660,8 @@ static int checkout(void)
commit_locked_index(lock_file))
die(_("unable to write new index file"));
- err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
- sha1_to_hex(sha1), "1", NULL);
+ err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
+ sha1_to_hex(sha1), "1", NULL);
if (!err && option_recursive)
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
diff --git a/builtin/commit.c b/builtin/commit.c
index 96bf7620c5..215b5bec19 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -113,6 +113,7 @@ static char *sign_commit;
static enum {
CLEANUP_SPACE,
CLEANUP_NONE,
+ CLEANUP_SCISSORS,
CLEANUP_ALL
} cleanup_mode;
static const char *cleanup_arg;
@@ -610,7 +611,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
/* This checks and barfs if author is badly specified */
determine_author_info(author_ident);
- if (!no_verify && run_hook(index_file, "pre-commit", NULL))
+ if (!no_verify && run_commit_hook(use_editor, index_file, "pre-commit", NULL))
return 0;
if (squash_message) {
@@ -755,7 +756,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
int ident_shown = 0;
int saved_color_setting;
char *ai_tmp, *ci_tmp;
- if (whence != FROM_COMMIT)
+ if (whence != FROM_COMMIT) {
+ if (cleanup_mode == CLEANUP_SCISSORS)
+ wt_status_add_cut_line(s->fp);
status_printf_ln(s, GIT_COLOR_NORMAL,
whence == FROM_MERGE
? _("\n"
@@ -771,6 +774,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
git_path(whence == FROM_MERGE
? "MERGE_HEAD"
: "CHERRY_PICK_HEAD"));
+ }
fprintf(s->fp, "\n");
if (cleanup_mode == CLEANUP_ALL)
@@ -778,6 +782,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
_("Please enter the commit message for your changes."
" Lines starting\nwith '%c' will be ignored, and an empty"
" message aborts the commit.\n"), comment_line_char);
+ else if (cleanup_mode == CLEANUP_SCISSORS && whence == FROM_COMMIT)
+ wt_status_add_cut_line(s->fp);
else /* CLEANUP_SPACE, that is. */
status_printf(s, GIT_COLOR_NORMAL,
_("Please enter the commit message for your changes."
@@ -867,8 +873,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
return 0;
}
- if (run_hook(index_file, "prepare-commit-msg",
- git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
+ if (run_commit_hook(use_editor, index_file, "prepare-commit-msg",
+ git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
return 0;
if (use_editor) {
@@ -884,7 +890,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
}
if (!no_verify &&
- run_hook(index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
+ run_commit_hook(use_editor, index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
return 0;
}
@@ -1068,8 +1074,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
use_editor = 0;
if (0 <= edit_flag)
use_editor = edit_flag;
- if (!use_editor)
- setenv("GIT_EDITOR", ":", 1);
/* Sanity check options */
if (amend && !current_head)
@@ -1133,6 +1137,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
cleanup_mode = CLEANUP_SPACE;
else if (!strcmp(cleanup_arg, "strip"))
cleanup_mode = CLEANUP_ALL;
+ else if (!strcmp(cleanup_arg, "scissors"))
+ cleanup_mode = use_editor ? CLEANUP_SCISSORS : CLEANUP_SPACE;
else
die(_("Invalid cleanup mode %s"), cleanup_arg);
@@ -1450,6 +1456,29 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
return finish_command(&proc);
}
+int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...)
+{
+ const char *hook_env[3] = { NULL };
+ char index[PATH_MAX];
+ va_list args;
+ int ret;
+
+ snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
+ hook_env[0] = index;
+
+ /*
+ * Let the hook know that no editor will be launched.
+ */
+ if (!editor_is_used)
+ hook_env[1] = "GIT_EDITOR=:";
+
+ va_start(args, name);
+ ret = run_hook_ve(hook_env, name, args);
+ va_end(args);
+
+ return ret;
+}
+
int cmd_commit(int argc, const char **argv, const char *prefix)
{
static struct wt_status s;
@@ -1605,8 +1634,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
die(_("could not read commit message: %s"), strerror(saved_errno));
}
- /* Truncate the message just before the diff, if any. */
- if (verbose)
+ if (verbose || /* Truncate the message just before the diff, if any. */
+ cleanup_mode == CLEANUP_SCISSORS)
wt_status_truncate_message_at_cut_line(&sb);
if (cleanup_mode != CLEANUP_NONE)
@@ -1674,7 +1703,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
"not exceeded, and then \"git reset HEAD\" to recover."));
rerere(0);
- run_hook(get_index_file(), "post-commit", NULL);
+ run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
if (amend && !no_post_rewrite) {
struct notes_rewrite_cfg *cfg;
cfg = init_copy_notes_for_rewrite("amend");
diff --git a/builtin/gc.c b/builtin/gc.c
index 63d400bcb2..85f5c2bc62 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -26,6 +26,7 @@ static const char * const builtin_gc_usage[] = {
};
static int pack_refs = 1;
+static int aggressive_depth = 250;
static int aggressive_window = 250;
static int gc_auto_threshold = 6700;
static int gc_auto_pack_limit = 50;
@@ -66,6 +67,10 @@ static int gc_config(const char *var, const char *value, void *cb)
aggressive_window = git_config_int(var, value);
return 0;
}
+ if (!strcmp(var, "gc.aggressivedepth")) {
+ aggressive_depth = git_config_int(var, value);
+ return 0;
+ }
if (!strcmp(var, "gc.auto")) {
gc_auto_threshold = git_config_int(var, value);
return 0;
@@ -184,7 +189,7 @@ static int need_to_gc(void)
else if (!too_many_loose_objects())
return 0;
- if (run_hook(NULL, "pre-auto-gc", NULL))
+ if (run_hook_le(NULL, "pre-auto-gc", NULL))
return 0;
return 1;
}
@@ -294,7 +299,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (aggressive) {
argv_array_push(&repack, "-f");
- argv_array_push(&repack, "--depth=250");
+ if (aggressive_depth > 0)
+ argv_array_pushf(&repack, "--depth=%d", aggressive_depth);
if (aggressive_window > 0)
argv_array_pushf(&repack, "--window=%d", aggressive_window);
}
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index a6b1c17996..b9f6e12c0e 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1291,7 +1291,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
if (keep_fd < 0) {
if (errno != EEXIST)
die_errno(_("cannot write keep file '%s'"),
- keep_name);
+ keep_name ? keep_name : name);
} else {
if (keep_msg_len > 0) {
write_or_die(keep_fd, keep_msg, keep_msg_len);
@@ -1299,7 +1299,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
}
if (close(keep_fd) != 0)
die_errno(_("cannot close written keep file '%s'"),
- keep_name);
+ keep_name ? keep_name : name);
report = "keep";
}
}
diff --git a/builtin/merge.c b/builtin/merge.c
index 2a144e1200..66d8843301 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -421,7 +421,7 @@ static void finish(struct commit *head_commit,
}
/* Run a post-merge hook */
- run_hook(NULL, "post-merge", squash ? "1" : "0", NULL);
+ run_hook_le(NULL, "post-merge", squash ? "1" : "0", NULL);
strbuf_release(&reflog_message);
}
@@ -824,8 +824,8 @@ static void prepare_to_commit(struct commit_list *remoteheads)
if (0 < option_edit)
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
write_merge_msg(&msg);
- if (run_hook(get_index_file(), "prepare-commit-msg",
- git_path("MERGE_MSG"), "merge", NULL, NULL))
+ if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
+ git_path("MERGE_MSG"), "merge", NULL))
abort_commit(remoteheads, NULL);
if (0 < option_edit) {
if (launch_editor(git_path("MERGE_MSG"), NULL, NULL))
diff --git a/builtin/mv.c b/builtin/mv.c
index 7e26eb5229..2a7243f52e 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -180,6 +180,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
modes = xrealloc(modes,
(argc + last - first)
* sizeof(enum update_mode));
+ submodule_gitfile = xrealloc(submodule_gitfile,
+ (argc + last - first)
+ * sizeof(char *));
}
dst = add_slash(dst);
@@ -193,6 +196,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
prefix_path(dst, dst_len,
path + length + 1);
modes[argc + j] = INDEX;
+ submodule_gitfile[argc + j] = NULL;
}
argc += last - first;
}
@@ -228,6 +232,11 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
memmove(destination + i,
destination + i + 1,
(argc - i) * sizeof(char *));
+ memmove(modes + i, modes + i + 1,
+ (argc - i) * sizeof(enum update_mode));
+ memmove(submodule_gitfile + i,
+ submodule_gitfile + i + 1,
+ (argc - i) * sizeof(char *));
i--;
}
} else
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 0ee5f1ff94..7950c4342f 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -708,7 +708,7 @@ static struct object_entry **compute_write_order(void)
static off_t write_reused_pack(struct sha1file *f)
{
unsigned char buffer[8192];
- off_t to_write;
+ off_t to_write, total;
int fd;
if (!is_pack_valid(reuse_packfile))
@@ -725,7 +725,7 @@ static off_t write_reused_pack(struct sha1file *f)
if (reuse_packfile_offset < 0)
reuse_packfile_offset = reuse_packfile->pack_size - 20;
- to_write = reuse_packfile_offset - sizeof(struct pack_header);
+ total = to_write = reuse_packfile_offset - sizeof(struct pack_header);
while (to_write) {
int read_pack = xread(fd, buffer, sizeof(buffer));
@@ -738,10 +738,23 @@ static off_t write_reused_pack(struct sha1file *f)
sha1write(f, buffer, read_pack);
to_write -= read_pack;
+
+ /*
+ * We don't know the actual number of objects written,
+ * only how many bytes written, how many bytes total, and
+ * how many objects total. So we can fake it by pretending all
+ * objects we are writing are the same size. This gives us a
+ * smooth progress meter, and at the end it matches the true
+ * answer.
+ */
+ written = reuse_packfile_objects *
+ (((double)(total - to_write)) / total);
+ display_progress(progress_state, written);
}
close(fd);
- written += reuse_packfile_objects;
+ written = reuse_packfile_objects;
+ display_progress(progress_state, written);
return reuse_packfile_offset - sizeof(struct pack_header);
}
@@ -995,6 +1008,10 @@ static void create_object_entry(const unsigned char *sha1,
entry->no_try_delta = no_try_delta;
}
+static const char no_closure_warning[] = N_(
+"disabling bitmap writing, as some objects are not being packed"
+);
+
static int add_object_entry(const unsigned char *sha1, enum object_type type,
const char *name, int exclude)
{
@@ -1005,14 +1022,20 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type,
if (have_duplicate_entry(sha1, exclude, &index_pos))
return 0;
- if (!want_object_in_pack(sha1, exclude, &found_pack, &found_offset))
+ if (!want_object_in_pack(sha1, exclude, &found_pack, &found_offset)) {
+ /* The pack is missing an object, so it will not have closure */
+ if (write_bitmap_index) {
+ warning(_(no_closure_warning));
+ write_bitmap_index = 0;
+ }
return 0;
+ }
create_object_entry(sha1, type, pack_name_hash(name),
exclude, name && no_try_delta(name),
index_pos, found_pack, found_offset);
- display_progress(progress_state, to_pack.nr_objects);
+ display_progress(progress_state, nr_result);
return 1;
}
@@ -1028,7 +1051,7 @@ static int add_object_entry_from_bitmap(const unsigned char *sha1,
create_object_entry(sha1, type, name_hash, 0, 0, index_pos, pack, offset);
- display_progress(progress_state, to_pack.nr_objects);
+ display_progress(progress_state, nr_result);
return 1;
}
@@ -2427,12 +2450,7 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
&reuse_packfile_offset)) {
assert(reuse_packfile_objects);
nr_result += reuse_packfile_objects;
-
- if (progress) {
- fprintf(stderr, "Reusing existing pack: %d, done.\n",
- reuse_packfile_objects);
- fflush(stderr);
- }
+ display_progress(progress_state, nr_result);
}
traverse_bitmap_commit_list(&add_object_entry_from_bitmap);