From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH v3 09/17] merge: make usage of commit->util more extensible
Date: Tue, 8 Nov 2011 17:01:55 -0800 [thread overview]
Message-ID: <1320800523-5407-10-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1320800523-5407-1-git-send-email-gitster@pobox.com>
The merge-recursive code uses the commit->util field directly to annotate
the commit objects given from the command line, i.e. the remote heads to
be merged, with a single string to be used to describe it in its trace
messages and conflict markers.
Correct this short-signtedness by redefining the field to be a pointer to
a structure "struct merge_remote_desc" that later enhancements can add
more information. Store the original objects we were told to merge in a
field "obj" in this struct, so that we can recover the tag we were told to
merge.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/merge.c | 63 +++++++++++++++++++---------------------------------
commit.c | 19 ++++++++++++++++
commit.h | 13 +++++++++++
merge-recursive.c | 13 +++++------
4 files changed, 61 insertions(+), 47 deletions(-)
diff --git a/builtin/merge.c b/builtin/merge.c
index 48e7f00..8d4eb4e 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -406,20 +406,10 @@ static void finish(struct commit *head_commit,
strbuf_release(&reflog_message);
}
-static struct object *want_commit(const char *name)
-{
- struct object *obj;
- unsigned char sha1[20];
- if (get_sha1(name, sha1))
- return NULL;
- obj = parse_object(sha1);
- return peel_to_type(name, 0, obj, OBJ_COMMIT);
-}
-
/* Get the name for the merge commit's message. */
static void merge_name(const char *remote, struct strbuf *msg)
{
- struct object *remote_head;
+ struct commit *remote_head;
unsigned char branch_head[20], buf_sha[20];
struct strbuf buf = STRBUF_INIT;
struct strbuf bname = STRBUF_INIT;
@@ -431,7 +421,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
remote = bname.buf;
memset(branch_head, 0, sizeof(branch_head));
- remote_head = want_commit(remote);
+ remote_head = get_merge_parent(remote);
if (!remote_head)
die(_("'%s' does not point to a commit"), remote);
@@ -487,7 +477,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
if (resolve_ref(truname.buf, buf_sha, 1, NULL)) {
strbuf_addf(msg,
"%s\t\tbranch '%s'%s of .\n",
- sha1_to_hex(remote_head->sha1),
+ sha1_to_hex(remote_head->object.sha1),
truname.buf + 11,
(early ? " (early part)" : ""));
strbuf_release(&truname);
@@ -515,7 +505,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
goto cleanup;
}
strbuf_addf(msg, "%s\t\tcommit '%s'\n",
- sha1_to_hex(remote_head->sha1), remote);
+ sha1_to_hex(remote_head->object.sha1), remote);
cleanup:
strbuf_release(&buf);
strbuf_release(&bname);
@@ -719,7 +709,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
die(_("Unknown option for merge-recursive: -X%s"), xopts[x]);
o.branch1 = head_arg;
- o.branch2 = remoteheads->item->util;
+ o.branch2 = merge_remote_util(remoteheads->item)->name;
for (j = common; j; j = j->next)
commit_list_insert(j->item, &reversed);
@@ -1190,7 +1180,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
argv += 2;
argc -= 2;
} else if (!head_commit) {
- struct object *remote_head;
+ struct commit *remote_head;
/*
* If the merged head is a valid one there is no reason
* to forbid "git merge" into a branch yet to be born.
@@ -1204,12 +1194,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (!allow_fast_forward)
die(_("Non-fast-forward commit does not make sense into "
"an empty head"));
- remote_head = want_commit(argv[0]);
+ remote_head = get_merge_parent(argv[0]);
if (!remote_head)
die(_("%s - not something we can merge"), argv[0]);
- read_empty(remote_head->sha1, 0);
- update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
- DIE_ON_ERR);
+ read_empty(remote_head->object.sha1, 0);
+ update_ref("initial pull", "HEAD", remote_head->object.sha1,
+ NULL, 0, DIE_ON_ERR);
return 0;
} else {
struct strbuf merge_names = STRBUF_INIT;
@@ -1218,12 +1208,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
head_arg = "HEAD";
/*
- * All the rest are the commits being merged;
- * prepare the standard merge summary message to
- * be appended to the given message. If remote
- * is invalid we will die later in the common
- * codepath so we discard the error in this
- * loop.
+ * All the rest are the commits being merged; prepare
+ * the standard merge summary message to be appended
+ * to the given message.
*/
for (i = 0; i < argc; i++)
merge_name(argv[i], &merge_names);
@@ -1251,17 +1238,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
strbuf_reset(&buf);
for (i = 0; i < argc; i++) {
- struct object *o;
- struct commit *commit;
-
- o = want_commit(argv[i]);
- if (!o)
+ struct commit *commit = get_merge_parent(argv[i]);
+ if (!commit)
die(_("%s - not something we can merge"), argv[i]);
- commit = lookup_commit(o->sha1);
- commit->util = (void *)argv[i];
remotes = &commit_list_insert(commit, remotes)->next;
-
- strbuf_addf(&buf, "GITHEAD_%s", sha1_to_hex(o->sha1));
+ strbuf_addf(&buf, "GITHEAD_%s",
+ sha1_to_hex(commit->object.sha1));
setenv(buf.buf, argv[i], 1);
strbuf_reset(&buf);
}
@@ -1307,7 +1289,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
!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;
+ struct commit *commit;
char hex[41];
strcpy(hex, find_unique_abbrev(head_commit->object.sha1, DEFAULT_ABBREV));
@@ -1321,14 +1303,15 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
if (have_message)
strbuf_addstr(&msg,
" (no commit created; -m option ignored)");
- o = want_commit(sha1_to_hex(remoteheads->item->object.sha1));
- if (!o)
+ commit = remoteheads->item;
+ if (!commit)
return 1;
- if (checkout_fast_forward(head_commit->object.sha1, remoteheads->item->object.sha1))
+ if (checkout_fast_forward(head_commit->object.sha1,
+ commit->object.sha1))
return 1;
- finish(head_commit, o->sha1, msg.buf);
+ finish(head_commit, commit->object.sha1, msg.buf);
drop_save();
return 0;
} else if (!remoteheads->next && common->next)
diff --git a/commit.c b/commit.c
index 73b7e00..83ff503 100644
--- a/commit.c
+++ b/commit.c
@@ -894,3 +894,22 @@ int commit_tree(const char *msg, unsigned char *tree,
strbuf_release(&buffer);
return result;
}
+
+struct commit *get_merge_parent(const char *name)
+{
+ struct object *obj;
+ struct commit *commit;
+ unsigned char sha1[20];
+ if (get_sha1(name, sha1))
+ return NULL;
+ obj = parse_object(sha1);
+ commit = (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);
+ if (commit && !commit->util) {
+ struct merge_remote_desc *desc;
+ desc = xmalloc(sizeof(*desc));
+ desc->obj = obj;
+ desc->name = strdup(name);
+ commit->util = desc;
+ }
+ return commit;
+}
diff --git a/commit.h b/commit.h
index 009b113..5b57eab 100644
--- a/commit.h
+++ b/commit.h
@@ -185,4 +185,17 @@ extern int commit_tree(const char *msg, unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author);
+struct merge_remote_desc {
+ struct object *obj; /* the named object, could be a tag */
+ const char *name;
+};
+#define merge_remote_util(commit) ((struct merge_remote_desc *)((commit)->util))
+
+/*
+ * Given "name" from the command line to merge, find the commit object
+ * and return it, while storing merge_remote_desc in its ->util field,
+ * to allow callers to tell if we are told to merge a tag.
+ */
+struct commit *get_merge_parent(const char *name);
+
#endif /* COMMIT_H */
diff --git a/merge-recursive.c b/merge-recursive.c
index cc664c3..5a2db29 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -38,16 +38,15 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two,
return lookup_tree(shifted);
}
-/*
- * A virtual commit has (const char *)commit->util set to the name.
- */
-
static struct commit *make_virtual_commit(struct tree *tree, const char *comment)
{
struct commit *commit = xcalloc(1, sizeof(struct commit));
+ struct merge_remote_desc *desc = xmalloc(sizeof(*desc));
+
+ desc->name = comment;
+ desc->obj = (struct object *)commit;
commit->tree = tree;
- commit->util = (void*)comment;
- /* avoid warnings */
+ commit->util = desc;
commit->object.parsed = 1;
return commit;
}
@@ -184,7 +183,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
for (i = o->call_depth; i--;)
fputs(" ", stdout);
if (commit->util)
- printf("virtual %s\n", (char *)commit->util);
+ printf("virtual %s\n", merge_remote_util(commit)->name);
else {
printf("%s ", find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
if (parse_commit(commit) != 0)
--
1.7.8.rc1.82.g90e080
next prev parent reply other threads:[~2011-11-09 1:02 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-09 1:01 [PATCH v3 00/17] Pulling signed tags Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 01/17] Split GPG interface into its own helper library Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 02/17] fetch: do not store peeled tag object names in FETCH_HEAD Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 03/17] merge: notice local merging of tags and keep it unwrapped Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 04/17] fetch: allow "git fetch $there v1.0" to fetch a tag Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 05/17] refs DWIMmery: use the same rule for both "git fetch" and others Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 06/17] fmt-merge-msg: avoid early returns Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 07/17] fmt-merge-msg: package options into a structure Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 08/17] fmt-merge-msg: Add contents of merged tag in the merge message Junio C Hamano
2011-11-09 1:01 ` Junio C Hamano [this message]
2011-11-09 1:01 ` [PATCH v3 10/17] merge: record tag objects without peeling in MERGE_HEAD Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 11/17] commit: copy merged signed tags to headers of merge commit Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 12/17] merge: force edit mode when merging a tag object Junio C Hamano
2011-11-09 1:01 ` [PATCH v3 13/17] commit: teach --amend to carry forward extra headers Junio C Hamano
2011-11-09 1:02 ` [PATCH v3 14/17] commit: teach --gpg-sign option Junio C Hamano
2011-11-09 1:02 ` [PATCH v3 15/17] log: --show-signature Junio C Hamano
2011-11-09 1:02 ` [PATCH v3 16/17] test "commit -S" and "log --show-signature" Junio C Hamano
2011-11-09 1:02 ` [PATCH v3 17/17] pretty: %G[?GS] placeholders Junio C Hamano
2011-11-09 10:32 ` [PATCH v3 00/17] Pulling signed tags Robin H. Johnson
2011-11-09 13:20 ` [PATCH 18/17] request-pull: use the annotated tag contents Junio C Hamano
2011-11-09 13:39 ` [PATCH 19/17] merge: do not fast-forward when merging a tag Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1320800523-5407-10-git-send-email-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).