summaryrefslogtreecommitdiff
path: root/sequencer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sequencer.c')
-rw-r--r--sequencer.c128
1 files changed, 78 insertions, 50 deletions
diff --git a/sequencer.c b/sequencer.c
index 9d5964fd81..e65076f221 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -131,7 +131,7 @@ static GIT_PATH_FUNC(rebase_path_rewritten_pending,
"rebase-merge/rewritten-pending")
/*
- * The path of the file containig the OID of the "squash onto" commit, i.e.
+ * The path of the file containing the OID of the "squash onto" commit, i.e.
* the dummy commit used for `reset [new root]`.
*/
static GIT_PATH_FUNC(rebase_path_squash_onto, "rebase-merge/squash-onto")
@@ -1126,25 +1126,22 @@ static int run_prepare_commit_msg_hook(struct repository *r,
struct strbuf *msg,
const char *commit)
{
- struct argv_array hook_env = ARGV_ARRAY_INIT;
- int ret;
- const char *name;
+ int ret = 0;
+ const char *name, *arg1 = NULL, *arg2 = NULL;
name = git_path_commit_editmsg();
if (write_message(msg->buf, msg->len, name, 0))
return -1;
- argv_array_pushf(&hook_env, "GIT_INDEX_FILE=%s", r->index_file);
- argv_array_push(&hook_env, "GIT_EDITOR=:");
- if (commit)
- ret = run_hook_le(hook_env.argv, "prepare-commit-msg", name,
- "commit", commit, NULL);
- else
- ret = run_hook_le(hook_env.argv, "prepare-commit-msg", name,
- "message", NULL);
- if (ret)
+ if (commit) {
+ arg1 = "commit";
+ arg2 = commit;
+ } else {
+ arg1 = "message";
+ }
+ if (run_commit_hook(0, r->index_file, "prepare-commit-msg", name,
+ arg1, arg2, NULL))
ret = error(_("'prepare-commit-msg' hook failed"));
- argv_array_clear(&hook_env);
return ret;
}
@@ -1403,6 +1400,7 @@ static int try_to_commit(struct repository *r,
goto out;
}
+ run_commit_hook(0, r->index_file, "post-commit", NULL);
if (flags & AMEND_MSG)
commit_post_rewrite(r, current_head, oid);
@@ -1576,6 +1574,7 @@ static int update_squash_messages(struct repository *r,
struct strbuf buf = STRBUF_INIT;
int res;
const char *message, *body;
+ const char *encoding = get_commit_output_encoding();
if (opts->current_fixup_count > 0) {
struct strbuf header = STRBUF_INIT;
@@ -1602,7 +1601,7 @@ static int update_squash_messages(struct repository *r,
return error(_("need a HEAD to fixup"));
if (!(head_commit = lookup_commit_reference(r, &head)))
return error(_("could not read HEAD"));
- if (!(head_message = get_commit_buffer(head_commit, NULL)))
+ if (!(head_message = logmsg_reencode(head_commit, NULL, encoding)))
return error(_("could not read HEAD's commit message"));
find_commit_subject(head_message, &body);
@@ -1623,7 +1622,7 @@ static int update_squash_messages(struct repository *r,
unuse_commit_buffer(head_commit, head_message);
}
- if (!(message = get_commit_buffer(commit, NULL)))
+ if (!(message = logmsg_reencode(commit, NULL, encoding)))
return error(_("could not read commit message of %s"),
oid_to_hex(&commit->object.oid));
find_commit_subject(message, &body);
@@ -2564,14 +2563,17 @@ static int walk_revs_populate_todo(struct todo_list *todo_list,
enum todo_command command = opts->action == REPLAY_PICK ?
TODO_PICK : TODO_REVERT;
const char *command_string = todo_command_info[command].str;
+ const char *encoding;
struct commit *commit;
if (prepare_revs(opts))
return -1;
+ encoding = get_log_output_encoding();
+
while ((commit = get_revision(opts->revs))) {
struct todo_item *item = append_new_todo(todo_list);
- const char *commit_buffer = get_commit_buffer(commit, NULL);
+ const char *commit_buffer = logmsg_reencode(commit, NULL, encoding);
const char *subject;
int subject_len;
@@ -2968,7 +2970,8 @@ static int make_patch(struct repository *r,
strbuf_addf(&buf, "%s/message", get_dir(opts));
if (!file_exists(buf.buf)) {
- const char *commit_buffer = get_commit_buffer(commit, NULL);
+ const char *encoding = get_commit_output_encoding();
+ const char *commit_buffer = logmsg_reencode(commit, NULL, encoding);
find_commit_subject(commit_buffer, &subject);
res |= write_message(subject, strlen(subject), buf.buf, 1);
unuse_commit_buffer(commit, commit_buffer);
@@ -3370,7 +3373,8 @@ static int do_merge(struct repository *r,
}
if (commit) {
- const char *message = get_commit_buffer(commit, NULL);
+ const char *encoding = get_commit_output_encoding();
+ const char *message = logmsg_reencode(commit, NULL, encoding);
const char *body;
int len;
@@ -4151,9 +4155,10 @@ static int commit_staged_changes(struct repository *r,
*/
struct commit *commit;
const char *path = rebase_path_squash_msg();
+ const char *encoding = get_commit_output_encoding();
if (parse_head(r, &commit) ||
- !(p = get_commit_buffer(commit, NULL)) ||
+ !(p = logmsg_reencode(commit, NULL, encoding)) ||
write_message(p, strlen(p), path, 0)) {
unuse_commit_buffer(commit, p);
return error(_("could not write file: "
@@ -4425,7 +4430,6 @@ static const char *label_oid(struct object_id *oid, const char *label,
struct labels_entry *labels_entry;
struct string_entry *string_entry;
struct object_id dummy;
- size_t len;
int i;
string_entry = oidmap_get(&state->commit2label, oid);
@@ -4445,10 +4449,10 @@ static const char *label_oid(struct object_id *oid, const char *label,
* abbreviation for any uninteresting commit's names that does not
* clash with any other label.
*/
+ strbuf_reset(&state->buf);
if (!label) {
char *p;
- strbuf_reset(&state->buf);
strbuf_grow(&state->buf, GIT_MAX_HEXSZ);
label = p = state->buf.buf;
@@ -4471,32 +4475,55 @@ static const char *label_oid(struct object_id *oid, const char *label,
p[i] = save;
}
}
- } else if (((len = strlen(label)) == the_hash_algo->hexsz &&
- !get_oid_hex(label, &dummy)) ||
- (len == 1 && *label == '#') ||
- hashmap_get_from_hash(&state->labels,
- strihash(label), label)) {
+ } else {
+ struct strbuf *buf = &state->buf;
+
/*
- * If the label already exists, or if the label is a valid full
- * OID, or the label is a '#' (which we use as a separator
- * between merge heads and oneline), we append a dash and a
- * number to make it unique.
+ * Sanitize labels by replacing non-alpha-numeric characters
+ * (including white-space ones) by dashes, as they might be
+ * illegal in file names (and hence in ref names).
+ *
+ * Note that we retain non-ASCII UTF-8 characters (identified
+ * via the most significant bit). They should be all acceptable
+ * in file names. We do not validate the UTF-8 here, that's not
+ * the job of this function.
*/
- struct strbuf *buf = &state->buf;
+ for (; *label; label++)
+ if ((*label & 0x80) || isalnum(*label))
+ strbuf_addch(buf, *label);
+ /* avoid leading dash and double-dashes */
+ else if (buf->len && buf->buf[buf->len - 1] != '-')
+ strbuf_addch(buf, '-');
+ if (!buf->len) {
+ strbuf_addstr(buf, "rev-");
+ strbuf_add_unique_abbrev(buf, oid, default_abbrev);
+ }
+ label = buf->buf;
- strbuf_reset(buf);
- strbuf_add(buf, label, len);
+ if ((buf->len == the_hash_algo->hexsz &&
+ !get_oid_hex(label, &dummy)) ||
+ (buf->len == 1 && *label == '#') ||
+ hashmap_get_from_hash(&state->labels,
+ strihash(label), label)) {
+ /*
+ * If the label already exists, or if the label is a
+ * valid full OID, or the label is a '#' (which we use
+ * as a separator between merge heads and oneline), we
+ * append a dash and a number to make it unique.
+ */
+ size_t len = buf->len;
- for (i = 2; ; i++) {
- strbuf_setlen(buf, len);
- strbuf_addf(buf, "-%d", i);
- if (!hashmap_get_from_hash(&state->labels,
- strihash(buf->buf),
- buf->buf))
- break;
- }
+ for (i = 2; ; i++) {
+ strbuf_setlen(buf, len);
+ strbuf_addf(buf, "-%d", i);
+ if (!hashmap_get_from_hash(&state->labels,
+ strihash(buf->buf),
+ buf->buf))
+ break;
+ }
- label = buf->buf;
+ label = buf->buf;
+ }
}
FLEX_ALLOC_STR(labels_entry, label, label);
@@ -4540,10 +4567,15 @@ static int make_script_with_merges(struct pretty_print_context *pp,
strbuf_init(&state.buf, 32);
if (revs->cmdline.nr && (revs->cmdline.rev[0].flags & BOTTOM)) {
+ struct labels_entry *onto_label_entry;
struct object_id *oid = &revs->cmdline.rev[0].item->oid;
FLEX_ALLOC_STR(entry, string, "onto");
oidcpy(&entry->entry.oid, oid);
oidmap_put(&state.commit2label, entry);
+
+ FLEX_ALLOC_STR(onto_label_entry, label, "onto");
+ hashmap_entry_init(&onto_label_entry->entry, strihash("onto"));
+ hashmap_add(&state.labels, &onto_label_entry->entry);
}
/*
@@ -4598,10 +4630,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
else
strbuf_addbuf(&label, &oneline);
- for (p1 = label.buf; *p1; p1++)
- if (isspace(*p1))
- *(char *)p1 = '-';
-
strbuf_reset(&buf);
strbuf_addf(&buf, "%s -C %s",
cmd_merge, oid_to_hex(&commit->object.oid));
@@ -4644,7 +4672,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
label_oid(oid, "branch-point", &state);
}
- /* Add HEAD as implict "tip of branch" */
+ /* Add HEAD as implicit "tip of branch" */
if (!iter->next)
tips_tail = &commit_list_insert(iter->item,
tips_tail)->next;
@@ -4826,7 +4854,7 @@ void todo_list_add_exec_commands(struct todo_list *todo_list,
* are considered part of the pick, so we insert the commands *after*
* those chains if there are any.
*
- * As we insert the exec commands immediatly after rearranging
+ * As we insert the exec commands immediately after rearranging
* any fixups and before the user edits the list, a fixup chain
* can never contain comments (any comments are empty picks that
* have been commented out because the user did not specify
@@ -5169,7 +5197,7 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
*commit_todo_item_at(&commit_todo, item->commit) = item;
parse_commit(item->commit);
- commit_buffer = get_commit_buffer(item->commit, NULL);
+ commit_buffer = logmsg_reencode(item->commit, NULL, "UTF-8");
find_commit_subject(commit_buffer, &subject);
format_subject(&buf, subject, " ");
subject = subjects[i] = strbuf_detach(&buf, &subject_len);