merge: remove global variable head[]
Also kill head_invalid in favor of "head_commit == NULL". Local variable "head" in cmd_merge() is renamed to "head_sha1" to make sure I don't miss any access because this variable should not be used after head_commit is set (use head_commit->object.sha1 instead). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
10b98fa5b3
commit
894642f68d
@ -50,7 +50,6 @@ static int fast_forward_only;
|
||||
static int allow_trivial = 1, have_message;
|
||||
static struct strbuf merge_msg;
|
||||
static struct commit_list *remoteheads;
|
||||
static unsigned char head[20];
|
||||
static struct strategy **use_strategies;
|
||||
static size_t use_strategies_nr, use_strategies_alloc;
|
||||
static const char **xopts;
|
||||
@ -279,7 +278,8 @@ static void reset_hard(unsigned const char *sha1, int verbose)
|
||||
die(_("read-tree failed"));
|
||||
}
|
||||
|
||||
static void restore_state(const unsigned char *stash)
|
||||
static void restore_state(const unsigned char *head,
|
||||
const unsigned char *stash)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
const char *args[] = { "stash", "apply", NULL, NULL };
|
||||
@ -309,10 +309,9 @@ static void finish_up_to_date(const char *msg)
|
||||
drop_save();
|
||||
}
|
||||
|
||||
static void squash_message(void)
|
||||
static void squash_message(struct commit *commit)
|
||||
{
|
||||
struct rev_info rev;
|
||||
struct commit *commit;
|
||||
struct strbuf out = STRBUF_INIT;
|
||||
struct commit_list *j;
|
||||
int fd;
|
||||
@ -327,7 +326,6 @@ static void squash_message(void)
|
||||
rev.ignore_merges = 1;
|
||||
rev.commit_format = CMIT_FMT_MEDIUM;
|
||||
|
||||
commit = lookup_commit(head);
|
||||
commit->object.flags |= UNINTERESTING;
|
||||
add_pending_object(&rev, &commit->object, NULL);
|
||||
|
||||
@ -356,9 +354,11 @@ static void squash_message(void)
|
||||
strbuf_release(&out);
|
||||
}
|
||||
|
||||
static void finish(const unsigned char *new_head, const char *msg)
|
||||
static void finish(struct commit *head_commit,
|
||||
const unsigned char *new_head, const char *msg)
|
||||
{
|
||||
struct strbuf reflog_message = STRBUF_INIT;
|
||||
const unsigned char *head = head_commit->object.sha1;
|
||||
|
||||
if (!msg)
|
||||
strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION"));
|
||||
@ -369,7 +369,7 @@ static void finish(const unsigned char *new_head, const char *msg)
|
||||
getenv("GIT_REFLOG_ACTION"), msg);
|
||||
}
|
||||
if (squash) {
|
||||
squash_message();
|
||||
squash_message(head_commit);
|
||||
} else {
|
||||
if (verbosity >= 0 && !merge_msg.len)
|
||||
printf(_("No merge message -- not updating HEAD\n"));
|
||||
@ -664,7 +664,7 @@ int try_merge_command(const char *strategy, size_t xopts_nr,
|
||||
}
|
||||
|
||||
static int try_merge_strategy(const char *strategy, struct commit_list *common,
|
||||
const char *head_arg)
|
||||
struct commit *head, const char *head_arg)
|
||||
{
|
||||
int index_fd;
|
||||
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
|
||||
@ -710,7 +710,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
|
||||
commit_list_insert(j->item, &reversed);
|
||||
|
||||
index_fd = hold_locked_index(lock, 1);
|
||||
clean = merge_recursive(&o, lookup_commit(head),
|
||||
clean = merge_recursive(&o, head,
|
||||
remoteheads->item, reversed, &result);
|
||||
if (active_cache_changed &&
|
||||
(write_cache(index_fd, active_cache, active_nr) ||
|
||||
@ -861,25 +861,26 @@ static void run_prepare_commit_msg(void)
|
||||
read_merge_msg();
|
||||
}
|
||||
|
||||
static int merge_trivial(void)
|
||||
static int merge_trivial(struct commit *head)
|
||||
{
|
||||
unsigned char result_tree[20], result_commit[20];
|
||||
struct commit_list *parent = xmalloc(sizeof(*parent));
|
||||
|
||||
write_tree_trivial(result_tree);
|
||||
printf(_("Wonderful.\n"));
|
||||
parent->item = lookup_commit(head);
|
||||
parent->item = head;
|
||||
parent->next = xmalloc(sizeof(*parent->next));
|
||||
parent->next->item = remoteheads->item;
|
||||
parent->next->next = NULL;
|
||||
run_prepare_commit_msg();
|
||||
commit_tree(merge_msg.buf, result_tree, parent, result_commit, NULL);
|
||||
finish(result_commit, "In-index merge");
|
||||
finish(head, result_commit, "In-index merge");
|
||||
drop_save();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finish_automerge(struct commit_list *common,
|
||||
static int finish_automerge(struct commit *head,
|
||||
struct commit_list *common,
|
||||
unsigned char *result_tree,
|
||||
const char *wt_strategy)
|
||||
{
|
||||
@ -890,12 +891,12 @@ static int finish_automerge(struct commit_list *common,
|
||||
free_commit_list(common);
|
||||
if (allow_fast_forward) {
|
||||
parents = remoteheads;
|
||||
commit_list_insert(lookup_commit(head), &parents);
|
||||
commit_list_insert(head, &parents);
|
||||
parents = reduce_heads(parents);
|
||||
} else {
|
||||
struct commit_list **pptr = &parents;
|
||||
|
||||
pptr = &commit_list_insert(lookup_commit(head),
|
||||
pptr = &commit_list_insert(head,
|
||||
pptr)->next;
|
||||
for (j = remoteheads; j; j = j->next)
|
||||
pptr = &commit_list_insert(j->item, pptr)->next;
|
||||
@ -905,7 +906,7 @@ static int finish_automerge(struct commit_list *common,
|
||||
run_prepare_commit_msg();
|
||||
commit_tree(merge_msg.buf, result_tree, parents, result_commit, NULL);
|
||||
strbuf_addf(&buf, "Merge made by %s.", wt_strategy);
|
||||
finish(result_commit, buf.buf);
|
||||
finish(head, result_commit, buf.buf);
|
||||
strbuf_release(&buf);
|
||||
drop_save();
|
||||
return 0;
|
||||
@ -939,7 +940,8 @@ static int suggest_conflicts(int renormalizing)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct commit *is_old_style_invocation(int argc, const char **argv)
|
||||
static struct commit *is_old_style_invocation(int argc, const char **argv,
|
||||
const unsigned char *head)
|
||||
{
|
||||
struct commit *second_token = NULL;
|
||||
if (argc > 2) {
|
||||
@ -1012,9 +1014,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
unsigned char result_tree[20];
|
||||
unsigned char stash[20];
|
||||
unsigned char head_sha1[20];
|
||||
struct commit *head_commit;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *head_arg;
|
||||
int flag, head_invalid = 0, i;
|
||||
int flag, i;
|
||||
int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0;
|
||||
struct commit_list *common = NULL;
|
||||
const char *best_strategy = NULL, *wt_strategy = NULL;
|
||||
@ -1027,11 +1031,16 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
* Check if we are _not_ on a detached HEAD, i.e. if there is a
|
||||
* current branch.
|
||||
*/
|
||||
branch = resolve_ref("HEAD", head, 0, &flag);
|
||||
branch = resolve_ref("HEAD", head_sha1, 0, &flag);
|
||||
if (branch && !prefixcmp(branch, "refs/heads/"))
|
||||
branch += 11;
|
||||
if (!branch || is_null_sha1(head))
|
||||
head_invalid = 1;
|
||||
if (!branch || is_null_sha1(head_sha1))
|
||||
head_commit = NULL;
|
||||
else {
|
||||
head_commit = lookup_commit(head_sha1);
|
||||
if (!head_commit)
|
||||
die(_("could not parse HEAD"));
|
||||
}
|
||||
|
||||
git_config(git_merge_config, NULL);
|
||||
|
||||
@ -1112,12 +1121,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
* additional safety measure to check for it.
|
||||
*/
|
||||
|
||||
if (!have_message && is_old_style_invocation(argc, argv)) {
|
||||
if (!have_message && head_commit &&
|
||||
is_old_style_invocation(argc, argv, head_commit->object.sha1)) {
|
||||
strbuf_addstr(&merge_msg, argv[0]);
|
||||
head_arg = argv[1];
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
} else if (head_invalid) {
|
||||
} else if (!head_commit) {
|
||||
struct object *remote_head;
|
||||
/*
|
||||
* If the merged head is a valid one there is no reason
|
||||
@ -1164,7 +1174,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
}
|
||||
|
||||
if (head_invalid || !argc)
|
||||
if (!head_commit || !argc)
|
||||
usage_with_options(builtin_merge_usage,
|
||||
builtin_merge_options);
|
||||
|
||||
@ -1205,17 +1215,16 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
if (!remoteheads->next)
|
||||
common = get_merge_bases(lookup_commit(head),
|
||||
remoteheads->item, 1);
|
||||
common = get_merge_bases(head_commit, remoteheads->item, 1);
|
||||
else {
|
||||
struct commit_list *list = remoteheads;
|
||||
commit_list_insert(lookup_commit(head), &list);
|
||||
commit_list_insert(head_commit, &list);
|
||||
common = get_octopus_merge_bases(list);
|
||||
free(list);
|
||||
}
|
||||
|
||||
update_ref("updating ORIG_HEAD", "ORIG_HEAD", head, NULL, 0,
|
||||
DIE_ON_ERR);
|
||||
update_ref("updating ORIG_HEAD", "ORIG_HEAD", head_commit->object.sha1,
|
||||
NULL, 0, DIE_ON_ERR);
|
||||
|
||||
if (!common)
|
||||
; /* No common ancestors found. We need a real merge. */
|
||||
@ -1229,13 +1238,13 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
return 0;
|
||||
} else if (allow_fast_forward && !remoteheads->next &&
|
||||
!common->next &&
|
||||
!hashcmp(common->item->object.sha1, head)) {
|
||||
!hashcmp(common->item->object.sha1, head_commit->object.sha1)) {
|
||||
/* Again the most common case of merging one remote. */
|
||||
struct strbuf msg = STRBUF_INIT;
|
||||
struct object *o;
|
||||
char hex[41];
|
||||
|
||||
strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV));
|
||||
strcpy(hex, find_unique_abbrev(head_commit->object.sha1, DEFAULT_ABBREV));
|
||||
|
||||
if (verbosity >= 0)
|
||||
printf(_("Updating %s..%s\n"),
|
||||
@ -1251,10 +1260,10 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
if (!o)
|
||||
return 1;
|
||||
|
||||
if (checkout_fast_forward(head, remoteheads->item->object.sha1))
|
||||
if (checkout_fast_forward(head_commit->object.sha1, remoteheads->item->object.sha1))
|
||||
return 1;
|
||||
|
||||
finish(o->sha1, msg.buf);
|
||||
finish(head_commit, o->sha1, msg.buf);
|
||||
drop_save();
|
||||
return 0;
|
||||
} else if (!remoteheads->next && common->next)
|
||||
@ -1274,8 +1283,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
git_committer_info(IDENT_ERROR_ON_NO_NAME);
|
||||
printf(_("Trying really trivial in-index merge...\n"));
|
||||
if (!read_tree_trivial(common->item->object.sha1,
|
||||
head, remoteheads->item->object.sha1))
|
||||
return merge_trivial();
|
||||
head_commit->object.sha1, remoteheads->item->object.sha1))
|
||||
return merge_trivial(head_commit);
|
||||
printf(_("Nope.\n"));
|
||||
}
|
||||
} else {
|
||||
@ -1294,8 +1303,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
* merge_bases again, otherwise "git merge HEAD^
|
||||
* HEAD^^" would be missed.
|
||||
*/
|
||||
common_one = get_merge_bases(lookup_commit(head),
|
||||
j->item, 1);
|
||||
common_one = get_merge_bases(head_commit, j->item, 1);
|
||||
if (hashcmp(common_one->item->object.sha1,
|
||||
j->item->object.sha1)) {
|
||||
up_to_date = 0;
|
||||
@ -1333,7 +1341,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
int ret;
|
||||
if (i) {
|
||||
printf(_("Rewinding the tree to pristine...\n"));
|
||||
restore_state(stash);
|
||||
restore_state(head_commit->object.sha1, stash);
|
||||
}
|
||||
if (use_strategies_nr != 1)
|
||||
printf(_("Trying merge strategy %s...\n"),
|
||||
@ -1345,7 +1353,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
wt_strategy = use_strategies[i]->name;
|
||||
|
||||
ret = try_merge_strategy(use_strategies[i]->name,
|
||||
common, head_arg);
|
||||
common, head_commit, head_arg);
|
||||
if (!option_commit && !ret) {
|
||||
merge_was_ok = 1;
|
||||
/*
|
||||
@ -1387,14 +1395,15 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
* auto resolved the merge cleanly.
|
||||
*/
|
||||
if (automerge_was_ok)
|
||||
return finish_automerge(common, result_tree, wt_strategy);
|
||||
return finish_automerge(head_commit, common, result_tree,
|
||||
wt_strategy);
|
||||
|
||||
/*
|
||||
* Pick the result from the best strategy and have the user fix
|
||||
* it up.
|
||||
*/
|
||||
if (!best_strategy) {
|
||||
restore_state(stash);
|
||||
restore_state(head_commit->object.sha1, stash);
|
||||
if (use_strategies_nr > 1)
|
||||
fprintf(stderr,
|
||||
_("No merge strategy handled the merge.\n"));
|
||||
@ -1406,14 +1415,14 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
; /* We already have its result in the working tree. */
|
||||
else {
|
||||
printf(_("Rewinding the tree to pristine...\n"));
|
||||
restore_state(stash);
|
||||
restore_state(head_commit->object.sha1, stash);
|
||||
printf(_("Using the %s to prepare resolving by hand.\n"),
|
||||
best_strategy);
|
||||
try_merge_strategy(best_strategy, common, head_arg);
|
||||
try_merge_strategy(best_strategy, common, head_commit, head_arg);
|
||||
}
|
||||
|
||||
if (squash)
|
||||
finish(NULL, NULL);
|
||||
finish(head_commit, NULL, NULL);
|
||||
else {
|
||||
int fd;
|
||||
struct commit_list *j;
|
||||
|
Loading…
Reference in New Issue
Block a user