summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c4
-rw-r--r--builtin/am.c3
-rw-r--r--builtin/archive.c4
-rw-r--r--builtin/branch.c2
-rw-r--r--builtin/bugreport.c5
-rw-r--r--builtin/checkout.c2
-rw-r--r--builtin/column.c2
-rw-r--r--builtin/commit-tree.c4
-rw-r--r--builtin/commit.c5
-rw-r--r--builtin/diff-index.c6
-rw-r--r--builtin/fast-export.c1
-rw-r--r--builtin/fetch.c4
-rw-r--r--builtin/gc.c93
-rw-r--r--builtin/hash-object.c6
-rw-r--r--builtin/index-pack.c56
-rw-r--r--builtin/ls-remote.c2
-rw-r--r--builtin/mailsplit.c4
-rw-r--r--builtin/merge.c16
-rw-r--r--builtin/notes.c4
-rw-r--r--builtin/pack-objects.c38
-rw-r--r--builtin/pull.c55
-rw-r--r--builtin/rebase.c2
-rw-r--r--builtin/repack.c2
-rw-r--r--builtin/send-pack.c1
-rw-r--r--builtin/show-branch.c15
-rw-r--r--builtin/tag.c4
-rw-r--r--builtin/update-index.c4
-rw-r--r--builtin/update-ref.c14
28 files changed, 224 insertions, 134 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 09e684585d..c37c95b45b 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -313,9 +313,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
rev.diffopt.use_color = 0;
rev.diffopt.flags.ignore_dirty_submodules = 1;
- out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (out < 0)
- die(_("Could not open '%s' for writing."), file);
+ out = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
rev.diffopt.file = xfdopen(out, "w");
rev.diffopt.close_file = 1;
if (run_diff_files(&rev, 0))
diff --git a/builtin/am.c b/builtin/am.c
index 0c2ad96b70..c79e0167e9 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -2106,7 +2106,8 @@ static void am_abort(struct am_state *state)
if (!has_orig_head)
oidcpy(&orig_head, the_hash_algo->empty_tree);
- clean_index(&curr_head, &orig_head);
+ if (clean_index(&curr_head, &orig_head))
+ die(_("failed to clean index"));
if (has_orig_head)
update_ref("am --abort", "HEAD", &orig_head,
diff --git a/builtin/archive.c b/builtin/archive.c
index 45d11669aa..7176b041b6 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -12,9 +12,7 @@
static void create_output_file(const char *output_file)
{
- int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (output_fd < 0)
- die_errno(_("could not create archive file '%s'"), output_file);
+ int output_fd = xopen(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (output_fd != 1) {
if (dup2(output_fd, 1) < 0)
die_errno(_("could not redirect output"));
diff --git a/builtin/branch.c b/builtin/branch.c
index b23b1d1752..03c7b7253a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -168,7 +168,7 @@ static int check_branch_commit(const char *branchname, const char *refname,
int kinds, int force)
{
struct commit *rev = lookup_commit_reference(the_repository, oid);
- if (!rev) {
+ if (!force && !rev) {
error(_("Couldn't look up commit object for '%s'"), refname);
return -1;
}
diff --git a/builtin/bugreport.c b/builtin/bugreport.c
index 9915a5841d..06ed10dc92 100644
--- a/builtin/bugreport.c
+++ b/builtin/bugreport.c
@@ -171,10 +171,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
get_populated_hooks(&buffer, !startup_info->have_repository);
/* fopen doesn't offer us an O_EXCL alternative, except with glibc. */
- report = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);
-
- if (report < 0)
- die(_("couldn't create a new file at '%s'"), report_path.buf);
+ report = xopen(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (write_in_full(report, buffer.buf, buffer.len) < 0)
die_errno(_("unable to write to %s"), report_path.buf);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index b5d477919a..b23bc149d1 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -404,7 +404,7 @@ static int checkout_worktree(const struct checkout_opts *opts,
mem_pool_discard(&ce_mem_pool, should_validate_cache_entries());
remove_marked_cache_entries(&the_index, 1);
remove_scheduled_dirs();
- errs |= finish_delayed_checkout(&state, &nr_checkouts);
+ errs |= finish_delayed_checkout(&state, &nr_checkouts, opts->show_progress);
if (opts->count_checkout_paths) {
if (nr_unmerged)
diff --git a/builtin/column.c b/builtin/column.c
index 40d4b3bee2..158fdf53d9 100644
--- a/builtin/column.c
+++ b/builtin/column.c
@@ -29,7 +29,7 @@ int cmd_column(int argc, const char **argv, const char *prefix)
OPT_INTEGER(0, "raw-mode", &colopts, N_("layout to use")),
OPT_INTEGER(0, "width", &copts.width, N_("maximum width")),
OPT_STRING(0, "indent", &copts.indent, N_("string"), N_("padding space on left border")),
- OPT_INTEGER(0, "nl", &copts.nl, N_("padding space on right border")),
+ OPT_STRING(0, "nl", &copts.nl, N_("string"), N_("padding space on right border")),
OPT_INTEGER(0, "padding", &copts.padding, N_("padding space between columns")),
OPT_END()
};
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index 1031b9a491..63ea322933 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -88,9 +88,7 @@ static int parse_file_arg_callback(const struct option *opt,
if (!strcmp(arg, "-"))
fd = 0;
else {
- fd = open(arg, O_RDONLY);
- if (fd < 0)
- die_errno(_("git commit-tree: failed to open '%s'"), arg);
+ fd = xopen(arg, O_RDONLY);
}
if (strbuf_read(buf, fd, 0) < 0)
die_errno(_("git commit-tree: failed to read '%s'"), arg);
diff --git a/builtin/commit.c b/builtin/commit.c
index 243c626307..7c9b1e7be3 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1253,8 +1253,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (logfile || have_option_m || use_message)
use_editor = 0;
- if (0 <= edit_flag)
- use_editor = edit_flag;
/* Sanity check options */
if (amend && !current_head)
@@ -1344,6 +1342,9 @@ static int parse_and_validate_options(int argc, const char *argv[],
}
}
+ if (0 <= edit_flag)
+ use_editor = edit_flag;
+
cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor);
handle_untracked_files_arg(s);
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index cf09559e42..5fd23ab5b6 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -29,10 +29,10 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
prefix = precompose_argv_prefix(argc, argv, prefix);
/*
- * We need no diff for merges options, and we need to avoid conflict
- * with our own meaning of "-m".
+ * We need (some of) diff for merges options (e.g., --cc), and we need
+ * to avoid conflict with our own meaning of "-m".
*/
- diff_merges_suppress_options_parsing();
+ diff_merges_suppress_m_parsing();
argc = setup_revisions(argc, argv, &rev, NULL);
for (i = 1; i < argc; i++) {
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 3c20f164f0..95e8e89e81 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -821,6 +821,7 @@ static void handle_tag(const char *name, struct tag *tag)
static struct hashmap tags;
message = anonymize_str(&tags, anonymize_tag,
message, message_size, NULL);
+ message_size = strlen(message);
}
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 25740c13df..e064687dbd 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1428,7 +1428,9 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
if (!has_glob_specials(s)) {
struct object_id oid;
if (get_oid(s, &oid))
- die("%s is not a valid object", s);
+ die(_("%s is not a valid object"), s);
+ if (!has_object(the_repository, &oid, 0))
+ die(_("the object %s does not exist"), s);
oid_array_append(oids, &oid);
continue;
}
diff --git a/builtin/gc.c b/builtin/gc.c
index f05d2f0a1a..ac60662619 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -502,7 +502,7 @@ static int report_last_gc_error(void)
*/
warning(_("The last gc run reported the following. "
"Please correct the root cause\n"
- "and remove %s.\n"
+ "and remove %s\n"
"Automatic cleanup will not be performed "
"until the file is removed.\n\n"
"%s"),
@@ -1600,18 +1600,40 @@ static int launchctl_remove_plists(const char *cmd)
launchctl_remove_plist(SCHEDULE_WEEKLY, cmd);
}
+static int launchctl_list_contains_plist(const char *name, const char *cmd)
+{
+ int result;
+ struct child_process child = CHILD_PROCESS_INIT;
+ char *uid = launchctl_get_uid();
+
+ strvec_split(&child.args, cmd);
+ strvec_pushl(&child.args, "list", name, NULL);
+
+ child.no_stderr = 1;
+ child.no_stdout = 1;
+
+ if (start_command(&child))
+ die(_("failed to start launchctl"));
+
+ result = finish_command(&child);
+
+ free(uid);
+
+ /* Returns failure if 'name' doesn't exist. */
+ return !result;
+}
+
static int launchctl_schedule_plist(const char *exec_path, enum schedule_priority schedule, const char *cmd)
{
- FILE *plist;
- int i;
+ int i, fd;
const char *preamble, *repeat;
const char *frequency = get_frequency(schedule);
char *name = launchctl_service_name(frequency);
char *filename = launchctl_service_filename(name);
-
- if (safe_create_leading_directories(filename))
- die(_("failed to create directories for '%s'"), filename);
- plist = xfopen(filename, "w");
+ struct lock_file lk = LOCK_INIT;
+ static unsigned long lock_file_timeout_ms = ULONG_MAX;
+ struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT;
+ struct stat st;
preamble = "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
@@ -1630,7 +1652,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"</array>\n"
"<key>StartCalendarInterval</key>\n"
"<array>\n";
- fprintf(plist, preamble, name, exec_path, exec_path, frequency);
+ strbuf_addf(&plist, preamble, name, exec_path, exec_path, frequency);
switch (schedule) {
case SCHEDULE_HOURLY:
@@ -1639,7 +1661,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n";
for (i = 1; i <= 23; i++)
- fprintf(plist, repeat, i);
+ strbuf_addf(&plist, repeat, i);
break;
case SCHEDULE_DAILY:
@@ -1649,32 +1671,59 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit
"<key>Minute</key><integer>0</integer>\n"
"</dict>\n";
for (i = 1; i <= 6; i++)
- fprintf(plist, repeat, i);
+ strbuf_addf(&plist, repeat, i);
break;
case SCHEDULE_WEEKLY:
- fprintf(plist,
- "<dict>\n"
- "<key>Day</key><integer>0</integer>\n"
- "<key>Hour</key><integer>0</integer>\n"
- "<key>Minute</key><integer>0</integer>\n"
- "</dict>\n");
+ strbuf_addstr(&plist,
+ "<dict>\n"
+ "<key>Day</key><integer>0</integer>\n"
+ "<key>Hour</key><integer>0</integer>\n"
+ "<key>Minute</key><integer>0</integer>\n"
+ "</dict>\n");
break;
default:
/* unreachable */
break;
}
- fprintf(plist, "</array>\n</dict>\n</plist>\n");
- fclose(plist);
+ strbuf_addstr(&plist, "</array>\n</dict>\n</plist>\n");
+
+ if (safe_create_leading_directories(filename))
+ die(_("failed to create directories for '%s'"), filename);
+
+ if ((long)lock_file_timeout_ms < 0 &&
+ git_config_get_ulong("gc.launchctlplistlocktimeoutms",
+ &lock_file_timeout_ms))
+ lock_file_timeout_ms = 150;
+
+ fd = hold_lock_file_for_update_timeout(&lk, filename, LOCK_DIE_ON_ERROR,
+ lock_file_timeout_ms);
- /* bootout might fail if not already running, so ignore */
- launchctl_boot_plist(0, filename, cmd);
- if (launchctl_boot_plist(1, filename, cmd))
- die(_("failed to bootstrap service %s"), filename);
+ /*
+ * Does this file already exist? With the intended contents? Is it
+ * registered already? Then it does not need to be re-registered.
+ */
+ if (!stat(filename, &st) && st.st_size == plist.len &&
+ strbuf_read_file(&plist2, filename, plist.len) == plist.len &&
+ !strbuf_cmp(&plist, &plist2) &&
+ launchctl_list_contains_plist(name, cmd))
+ rollback_lock_file(&lk);
+ else {
+ if (write_in_full(fd, plist.buf, plist.len) < 0 ||
+ commit_lock_file(&lk))
+ die_errno(_("could not write '%s'"), filename);
+
+ /* bootout might fail if not already running, so ignore */
+ launchctl_boot_plist(0, filename, cmd);
+ if (launchctl_boot_plist(1, filename, cmd))
+ die(_("failed to bootstrap service %s"), filename);
+ }
free(filename);
free(name);
+ strbuf_release(&plist);
+ strbuf_release(&plist2);
return 0;
}
diff --git a/builtin/hash-object.c b/builtin/hash-object.c
index 640ef4ded5..c7b3ad74c6 100644
--- a/builtin/hash-object.c
+++ b/builtin/hash-object.c
@@ -53,9 +53,7 @@ static void hash_object(const char *path, const char *type, const char *vpath,
unsigned flags, int literally)
{
int fd;
- fd = open(path, O_RDONLY);
- if (fd < 0)
- die_errno("Cannot open '%s'", path);
+ fd = xopen(path, O_RDONLY);
hash_fd(fd, type, vpath, flags, literally);
}
@@ -117,7 +115,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
prefix = setup_git_directory_gently(&nongit);
if (vpath && prefix)
- vpath = xstrdup(prefix_filename(prefix, vpath));
+ vpath = prefix_filename(prefix, vpath);
git_config(git_default_config, NULL);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 8336466865..f267dce49e 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -338,15 +338,11 @@ static const char *open_pack_file(const char *pack_name)
"pack/tmp_pack_XXXXXX");
pack_name = strbuf_detach(&tmp_file, NULL);
} else {
- output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
- if (output_fd < 0)
- die_errno(_("unable to create '%s'"), pack_name);
+ output_fd = xopen(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
}
nothread_data.pack_fd = output_fd;
} else {
- input_fd = open(pack_name, O_RDONLY);
- if (input_fd < 0)
- die_errno(_("cannot open packfile '%s'"), pack_name);
+ input_fd = xopen(pack_name, O_RDONLY);
output_fd = -1;
nothread_data.pack_fd = input_fd;
}
@@ -1481,6 +1477,22 @@ static void write_special_file(const char *suffix, const char *msg,
strbuf_release(&name_buf);
}
+static void rename_tmp_packfile(const char **final_name,
+ const char *curr_name,
+ struct strbuf *name, unsigned char *hash,
+ const char *ext, int make_read_only_if_same)
+{
+ if (*final_name != curr_name) {
+ if (!*final_name)
+ *final_name = odb_pack_name(name, hash, ext);
+ if (finalize_object_file(curr_name, *final_name))
+ die(_("unable to rename temporary '*.%s' file to '%s"),
+ ext, *final_name);
+ } else if (make_read_only_if_same) {
+ chmod(*final_name, 0444);
+ }
+}
+
static void final(const char *final_pack_name, const char *curr_pack_name,
const char *final_index_name, const char *curr_index_name,
const char *final_rev_index_name, const char *curr_rev_index_name,
@@ -1509,31 +1521,13 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
write_special_file("promisor", promisor_msg, final_pack_name,
hash, NULL);
- if (final_pack_name != curr_pack_name) {
- if (!final_pack_name)
- final_pack_name = odb_pack_name(&pack_name, hash, "pack");
- if (finalize_object_file(curr_pack_name, final_pack_name))
- die(_("cannot store pack file"));
- } else if (from_stdin)
- chmod(final_pack_name, 0444);
-
- if (final_index_name != curr_index_name) {
- if (!final_index_name)
- final_index_name = odb_pack_name(&index_name, hash, "idx");
- if (finalize_object_file(curr_index_name, final_index_name))
- die(_("cannot store index file"));
- } else
- chmod(final_index_name, 0444);
-
- if (curr_rev_index_name) {
- if (final_rev_index_name != curr_rev_index_name) {
- if (!final_rev_index_name)
- final_rev_index_name = odb_pack_name(&rev_index_name, hash, "rev");
- if (finalize_object_file(curr_rev_index_name, final_rev_index_name))
- die(_("cannot store reverse index file"));
- } else
- chmod(final_rev_index_name, 0444);
- }
+ rename_tmp_packfile(&final_pack_name, curr_pack_name, &pack_name,
+ hash, "pack", from_stdin);
+ if (curr_rev_index_name)
+ rename_tmp_packfile(&final_rev_index_name, curr_rev_index_name,
+ &rev_index_name, hash, "rev", 1);
+ rename_tmp_packfile(&final_index_name, curr_index_name, &index_name,
+ hash, "idx", 1);
if (do_fsck_object) {
struct packed_git *p;
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index 1794548c71..f4fd823af8 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -84,6 +84,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
PARSE_OPT_STOP_AT_NON_OPTION);
dest = argv[0];
+ packet_trace_identity("ls-remote");
+
UNLEAK(sorting);
if (argc > 1) {
diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c
index 664400b816..7baef30569 100644
--- a/builtin/mailsplit.c
+++ b/builtin/mailsplit.c
@@ -75,9 +75,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
fprintf(stderr, "corrupt mailbox\n");
exit(1);
}
- fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
- if (fd < 0)
- die_errno("cannot open output file '%s'", name);
+ fd = xopen(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
output = xfdopen(fd, "w");
/* Copy it out, while searching for a line that begins with
diff --git a/builtin/merge.c b/builtin/merge.c
index 22f23990b3..8949a9c2fb 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -739,7 +739,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
for (x = 0; x < xopts_nr; x++)
if (parse_merge_opt(&o, xopts[x]))
- die(_("Unknown option for merge-recursive: -X%s"), xopts[x]);
+ die(_("unknown strategy option: -X%s"), xopts[x]);
o.branch1 = head_arg;
o.branch2 = merge_remote_util(remoteheads->item)->name;
@@ -862,9 +862,11 @@ static void prepare_to_commit(struct commit_list *remoteheads)
strbuf_commented_addf(&msg, "\n");
}
strbuf_commented_addf(&msg, _(merge_editor_comment));
- strbuf_commented_addf(&msg, _(cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS ?
- scissors_editor_comment :
- no_scissors_editor_comment), comment_line_char);
+ if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
+ strbuf_commented_addf(&msg, _(scissors_editor_comment));
+ else
+ strbuf_commented_addf(&msg,
+ _(no_scissors_editor_comment), comment_line_char);
}
if (signoff)
append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0);
@@ -1136,9 +1138,7 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge
merge_names = &fetch_head_file;
filename = git_path_fetch_head(the_repository);
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- die_errno(_("could not open '%s' for reading"), filename);
+ fd = xopen(filename, O_RDONLY);
if (strbuf_read(merge_names, fd, 0) < 0)
die_errno(_("could not read '%s'"), filename);
@@ -1622,7 +1622,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
}
if (fast_forward == FF_ONLY)
- die(_("Not possible to fast-forward, aborting."));
+ die_ff_impossible();
if (autostash)
create_autostash(the_repository,
diff --git a/builtin/notes.c b/builtin/notes.c
index 74bba39ca8..71c59583a1 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -172,9 +172,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data *
/* write the template message before editing: */
d->edit_path = git_pathdup("NOTES_EDITMSG");
- fd = open(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- if (fd < 0)
- die_errno(_("could not create file '%s'"), d->edit_path);
+ fd = xopen(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (d->given)
write_or_die(fd, d->buf.buf, d->buf.len);
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index de00adbb9e..a01767a384 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1217,6 +1217,7 @@ static void write_pack_file(void)
if (!pack_to_stdout) {
struct stat st;
struct strbuf tmpname = STRBUF_INIT;
+ char *idx_tmp_name = NULL;
/*
* Packs are runtime accessed in their mtime
@@ -1237,7 +1238,8 @@ static void write_pack_file(void)
warning_errno(_("failed utime() on %s"), pack_tmp_name);
}
- strbuf_addf(&tmpname, "%s-", base_name);
+ strbuf_addf(&tmpname, "%s-%s.", base_name,
+ hash_to_hex(hash));
if (write_bitmap_index) {
bitmap_writer_set_checksum(hash);
@@ -1245,13 +1247,14 @@ static void write_pack_file(void)
&to_pack, written_list, nr_written);
}
- finish_tmp_packfile(&tmpname, pack_tmp_name,
+ stage_tmp_packfiles(&tmpname, pack_tmp_name,
written_list, nr_written,
- &pack_idx_opts, hash);
+ &pack_idx_opts, hash, &idx_tmp_name);
if (write_bitmap_index) {
- strbuf_addf(&tmpname, "%s.bitmap", hash_to_hex(hash));
+ size_t tmpname_len = tmpname.len;
+ strbuf_addstr(&tmpname, "bitmap");
stop_progress(&progress_state);
bitmap_writer_show_progress(progress);
@@ -1260,8 +1263,12 @@ static void write_pack_file(void)
bitmap_writer_finish(written_list, nr_written,
tmpname.buf, write_bitmap_options);
write_bitmap_index = 0;
+ strbuf_setlen(&tmpname, tmpname_len);
}
+ rename_tmp_packfile_idx(&tmpname, &idx_tmp_name);
+
+ free(idx_tmp_name);
strbuf_release(&tmpname);
free(pack_tmp_name);
puts(hash_to_hex(hash));
@@ -3311,9 +3318,26 @@ static void read_packs_list_from_stdin(void)
}
/*
- * First handle all of the excluded packs, marking them as kept in-core
- * so that later calls to add_object_entry() discards any objects that
- * are also found in excluded packs.
+ * Arguments we got on stdin may not even be packs. First
+ * check that to avoid segfaulting later on in
+ * e.g. pack_mtime_cmp(), excluded packs are handled below.
+ *
+ * Since we first parsed our STDIN and then sorted the input
+ * lines the pack we error on will be whatever line happens to
+ * sort first. This is lazy, it's enough that we report one
+ * bad case here, we don't need to report the first/last one,
+ * or all of them.
+ */
+ for_each_string_list_item(item, &include_packs) {
+ struct packed_git *p = item->util;
+ if (!p)
+ die(_("could not find pack '%s'"), item->string);
+ }
+
+ /*
+ * Then, handle all of the excluded packs, marking them as
+ * kept in-core so that later calls to add_object_entry()
+ * discards any objects that are also found in excluded packs.
*/
for_each_string_list_item(item, &exclude_packs) {
struct packed_git *p = item->util;
diff --git a/builtin/pull.c b/builtin/pull.c
index 3e13f81084..b311ea6b9d 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -893,6 +893,8 @@ static int run_rebase(const struct object_id *newbase,
strvec_pushv(&args, opt_strategy_opts.v);
if (opt_gpg_sign)
strvec_push(&args, opt_gpg_sign);
+ if (opt_signoff)
+ strvec_push(&args, opt_signoff);
if (opt_autostash == 0)
strvec_push(&args, "--no-autostash");
else if (opt_autostash == 1)
@@ -911,12 +913,18 @@ static int run_rebase(const struct object_id *newbase,
return ret;
}
-static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_head)
+static int get_can_ff(struct object_id *orig_head,
+ struct oid_array *merge_heads)
{
int ret;
struct commit_list *list = NULL;
struct commit *merge_head, *head;
+ struct object_id *orig_merge_head;
+ if (merge_heads->nr > 1)
+ return 0;
+
+ orig_merge_head = &merge_heads->oid[0];
head = lookup_commit_reference(the_repository, orig_head);
commit_list_insert(head, &list);
merge_head = lookup_commit_reference(the_repository, orig_merge_head);
@@ -927,9 +935,9 @@ static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_
static void show_advice_pull_non_ff(void)
{
- advise(_("Pulling without specifying how to reconcile divergent branches is\n"
- "discouraged. You can squelch this message by running one of the following\n"
- "commands sometime before your next pull:\n"
+ advise(_("You have divergent branches and need to specify how to reconcile them.\n"
+ "You can do so by running one of the following commands sometime before\n"
+ "your next pull:\n"
"\n"
" git config pull.rebase false # merge (the default strategy)\n"
" git config pull.rebase true # rebase\n"
@@ -966,8 +974,22 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
parse_repo_refspecs(argc, argv, &repo, &refspecs);
- if (!opt_ff)
+ if (!opt_ff) {
opt_ff = xstrdup_or_null(config_get_ff());
+ /*
+ * A subtle point: opt_ff was set on the line above via
+ * reading from config. opt_rebase, in contrast, is set
+ * before this point via command line options. The setting
+ * of opt_rebase via reading from config (using
+ * config_get_rebase()) does not happen until later. We
+ * are relying on the next if-condition happening before
+ * the config_get_rebase() call so that an explicit
+ * "--rebase" can override a config setting of
+ * pull.ff=only.
+ */
+ if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only"))
+ opt_ff = "--ff";
+ }
if (opt_rebase < 0)
opt_rebase = config_get_rebase(&rebase_unspecified);
@@ -1041,14 +1063,25 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
die(_("Cannot merge multiple branches into empty head."));
return pull_into_void(merge_heads.oid, &curr_head);
}
- if (opt_rebase && merge_heads.nr > 1)
- die(_("Cannot rebase onto multiple branches."));
+ if (merge_heads.nr > 1) {
+ if (opt_rebase)
+ die(_("Cannot rebase onto multiple branches."));
+ if (opt_ff && !strcmp(opt_ff, "--ff-only"))
+ die(_("Cannot fast-forward to multiple branches."));
+ }
- can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
+ can_ff = get_can_ff(&orig_head, &merge_heads);
- if (rebase_unspecified && !opt_ff && !can_ff) {
- if (opt_verbosity >= 0)
- show_advice_pull_non_ff();
+ /* ff-only takes precedence over rebase */
+ if (opt_ff && !strcmp(opt_ff, "--ff-only")) {
+ if (!can_ff)
+ die_ff_impossible();
+ opt_rebase = REBASE_FALSE;
+ }
+ /* If no action specified and we can't fast forward, then warn. */
+ if (!opt_ff && rebase_unspecified && !can_ff) {
+ show_advice_pull_non_ff();
+ die(_("Need to specify how to reconcile divergent branches."));
}
if (opt_rebase) {
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 33e0961900..66a0a0f0d0 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -1918,7 +1918,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
&options.orig_head))
options.head_name = NULL;
else
- die(_("fatal: no such branch/commit '%s'"),
+ die(_("no such branch/commit '%s'"),
branch_name);
} else if (argc == 0) {
/* Do not need to switch branches, we are already on it. */
diff --git a/builtin/repack.c b/builtin/repack.c
index 5f9bc74adc..c3e4771609 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -208,10 +208,10 @@ static struct {
unsigned optional:1;
} exts[] = {
{".pack"},
- {".idx"},
{".rev", 1},
{".bitmap", 1},
{".promisor", 1},
+ {".idx"},
};
static unsigned populate_pack_exts(char *name)
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index a7e01667b0..729dea1d25 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -230,6 +230,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
args.atomic = atomic;
args.stateless_rpc = stateless_rpc;
args.push_options = push_options.nr ? &push_options : NULL;
+ args.url = dest;
if (from_stdin) {
if (args.stateless_rpc) {
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index d77ce7aeb3..bea4bbf468 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -482,10 +482,9 @@ static void snarf_refs(int head, int remotes)
}
}
-static int rev_is_head(const char *head, const char *name,
- unsigned char *head_sha1, unsigned char *sha1)
+static int rev_is_head(const char *head, const char *name)
{
- if (!head || (head_sha1 && sha1 && !hasheq(head_sha1, sha1)))
+ if (!head)
return 0;
skip_prefix(head, "refs/heads/", &head);
if (!skip_prefix(name, "refs/heads/", &name))
@@ -806,9 +805,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
/* We are only interested in adding the branch
* HEAD points at.
*/
- if (rev_is_head(head,
- ref_name[i],
- head_oid.hash, NULL))
+ if (rev_is_head(head, ref_name[i]))
has_head++;
}
if (!has_head) {
@@ -867,10 +864,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
if (1 < num_rev || extra < 0) {
for (i = 0; i < num_rev; i++) {
int j;
- int is_head = rev_is_head(head,
- ref_name[i],
- head_oid.hash,
- rev[i]->object.oid.hash);
+ int is_head = rev_is_head(head, ref_name[i]) &&
+ oideq(&head_oid, &rev[i]->object.oid);
if (extra < 0)
printf("%c [%s] ",
is_head ? '*' : ' ', ref_name[i]);
diff --git a/builtin/tag.c b/builtin/tag.c
index 82fcfc0982..87552ae6ac 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -293,9 +293,7 @@ static void create_tag(const struct object_id *object, const char *object_ref,
/* write the template message before editing: */
path = git_pathdup("TAG_EDITMSG");
- fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- if (fd < 0)
- die_errno(_("could not create file '%s'"), path);
+ fd = xopen(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (opt->message_given) {
write_or_die(fd, buf->buf, buf->len);
diff --git a/builtin/update-index.c b/builtin/update-index.c
index f1f16f2de5..187203e8bb 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -95,9 +95,7 @@ static int create_file(const char *path)
{
int fd;
path = get_mtime_path(path);
- fd = open(path, O_CREAT | O_RDWR, 0644);
- if (fd < 0)
- die_errno(_("failed to create file %s"), path);
+ fd = xopen(path, O_CREAT | O_RDWR, 0644);
return fd;
}
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 6029a80544..a84e7b47a2 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -302,6 +302,12 @@ static void parse_cmd_verify(struct ref_transaction *transaction,
strbuf_release(&err);
}
+static void report_ok(const char *command)
+{
+ fprintf(stdout, "%s: ok\n", command);
+ fflush(stdout);
+}
+
static void parse_cmd_option(struct ref_transaction *transaction,
const char *next, const char *end)
{
@@ -317,7 +323,7 @@ static void parse_cmd_start(struct ref_transaction *transaction,
{
if (*next != line_termination)
die("start: extra input: %s", next);
- puts("start: ok");
+ report_ok("start");
}
static void parse_cmd_prepare(struct ref_transaction *transaction,
@@ -328,7 +334,7 @@ static void parse_cmd_prepare(struct ref_transaction *transaction,
die("prepare: extra input: %s", next);
if (ref_transaction_prepare(transaction, &error))
die("prepare: %s", error.buf);
- puts("prepare: ok");
+ report_ok("prepare");
}
static void parse_cmd_abort(struct ref_transaction *transaction,
@@ -339,7 +345,7 @@ static void parse_cmd_abort(struct ref_transaction *transaction,
die("abort: extra input: %s", next);
if (ref_transaction_abort(transaction, &error))
die("abort: %s", error.buf);
- puts("abort: ok");
+ report_ok("abort");
}
static void parse_cmd_commit(struct ref_transaction *transaction,
@@ -350,7 +356,7 @@ static void parse_cmd_commit(struct ref_transaction *transaction,
die("commit: extra input: %s", next);
if (ref_transaction_commit(transaction, &error))
die("commit: %s", error.buf);
- puts("commit: ok");
+ report_ok("commit");
ref_transaction_free(transaction);
}