#include "builtin.h"
#include "tag.h"
#include "reflog-walk.h"
+#include "patch-ids.h"
+#include "refs.h"
static int default_show_root = 1;
/* this is in builtin-diff.c */
void add_head(struct rev_info *revs);
+static void add_name_decoration(const char *prefix, const char *name, struct object *obj)
+{
+ int plen = strlen(prefix);
+ int nlen = strlen(name);
+ struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen);
+ memcpy(res->name, prefix, plen);
+ memcpy(res->name + plen, name, nlen + 1);
+ res->next = add_decoration(&name_decoration, obj, res);
+}
+
+static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
+{
+ struct object *obj = parse_object(sha1);
+ if (!obj)
+ return 0;
+ add_name_decoration("", refname, obj);
+ while (obj->type == OBJ_TAG) {
+ obj = ((struct tag *)obj)->tagged;
+ if (!obj)
+ break;
+ add_name_decoration("tag: ", refname, obj);
+ }
+ return 0;
+}
+
static void cmd_log_init(int argc, const char **argv, const char *prefix,
struct rev_info *rev)
{
int i;
+ int decorate = 0;
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
if (!prefixcmp(arg, "--encoding=")) {
arg += 11;
if (strcmp(arg, "none"))
- git_log_output_encoding = strdup(arg);
+ git_log_output_encoding = xstrdup(arg);
else
git_log_output_encoding = "";
- }
- else
+ } else if (!strcmp(arg, "--decorate")) {
+ if (!decorate)
+ for_each_ref(add_ref_decoration, NULL);
+ decorate = 1;
+ } else
die("unrecognized argument: %s", arg);
}
}
}
-static int get_patch_id(struct commit *commit, struct diff_options *options,
- unsigned char *sha1)
-{
- if (commit->parents)
- diff_tree_sha1(commit->parents->item->object.sha1,
- commit->object.sha1, "", options);
- else
- diff_root_tree_sha1(commit->object.sha1, "", options);
- diffcore_std(options);
- return diff_flush_patch_id(options, sha1);
-}
-
-static void get_patch_ids(struct rev_info *rev, struct diff_options *options, const char *prefix)
+static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const char *prefix)
{
struct rev_info check_rev;
struct commit *commit;
struct object *o1, *o2;
unsigned flags1, flags2;
- unsigned char sha1[20];
if (rev->pending.nr != 2)
die("Need exactly one range.");
if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
die("Not a range.");
- diff_setup(options);
- options->recursive = 1;
- if (diff_setup_done(options) < 0)
- die("diff_setup_done failed");
+ init_patch_ids(ids);
/* given a range a..b get all patch ids for b..a */
init_revisions(&check_rev, prefix);
if (commit->parents && commit->parents->next)
continue;
- if (!get_patch_id(commit, options, sha1))
- created_object(sha1, xcalloc(1, sizeof(struct object)));
+ add_commit_patch_id(commit, ids);
}
/* reset for next revision walk */
int numbered = 0;
int start_number = -1;
int keep_subject = 0;
+ int subject_prefix = 0;
int ignore_if_in_upstream = 0;
int thread = 0;
const char *in_reply_to = NULL;
- struct diff_options patch_id_opts;
+ struct patch_ids ids;
char *add_signoff = NULL;
char message_id[1024];
char ref_message_id[1024];
memcpy(add_signoff, committer, endpos - committer + 1);
add_signoff[endpos - committer + 1] = 0;
}
- else if (!strcmp(argv[i], "--attach"))
+ else if (!strcmp(argv[i], "--attach")) {
+ rev.mime_boundary = git_version_string;
+ rev.no_inline = 1;
+ }
+ else if (!prefixcmp(argv[i], "--attach=")) {
+ rev.mime_boundary = argv[i] + 9;
+ rev.no_inline = 1;
+ }
+ else if (!strcmp(argv[i], "--inline")) {
rev.mime_boundary = git_version_string;
- else if (!prefixcmp(argv[i], "--attach="))
+ rev.no_inline = 0;
+ }
+ else if (!prefixcmp(argv[i], "--inline=")) {
rev.mime_boundary = argv[i] + 9;
+ rev.no_inline = 0;
+ }
else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
ignore_if_in_upstream = 1;
else if (!strcmp(argv[i], "--thread"))
if (i == argc)
die("Need a Message-Id for --in-reply-to");
in_reply_to = argv[i];
- }
- else if (!prefixcmp(argv[i], "--suffix="))
+ } else if (!prefixcmp(argv[i], "--subject-prefix=")) {
+ subject_prefix = 1;
+ rev.subject_prefix = argv[i] + 17;
+ } else if (!prefixcmp(argv[i], "--suffix="))
fmt_patch_suffix = argv[i] + 9;
else
argv[j++] = argv[i];
start_number = 1;
if (numbered && keep_subject)
die ("-n and -k are mutually exclusive.");
+ if (keep_subject && subject_prefix)
+ die ("--subject-prefix and -k are mutually exclusive.");
argc = setup_revisions(argc, argv, &rev, "HEAD");
if (argc > 1)
}
if (ignore_if_in_upstream)
- get_patch_ids(&rev, &patch_id_opts, prefix);
+ get_patch_ids(&rev, &ids, prefix);
if (!use_stdout)
realstdout = fdopen(dup(1), "w");
prepare_revision_walk(&rev);
while ((commit = get_revision(&rev)) != NULL) {
- unsigned char sha1[20];
-
/* ignore merges */
if (commit->parents && commit->parents->next)
continue;
if (ignore_if_in_upstream &&
- !get_patch_id(commit, &patch_id_opts, sha1) &&
- lookup_object(sha1))
+ has_commit_patch_id(commit, &ids))
continue;
nr++;
fclose(stdout);
}
free(list);
+ if (ignore_if_in_upstream)
+ free_patch_ids(&ids);
return 0;
}
int cmd_cherry(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
- struct diff_options patch_id_opts;
+ struct patch_ids ids;
struct commit *commit;
struct commit_list *list = NULL;
const char *upstream;
return 0;
}
- get_patch_ids(&revs, &patch_id_opts, prefix);
+ get_patch_ids(&revs, &ids, prefix);
if (limit && add_pending_commit(limit, &revs, UNINTERESTING))
die("Unknown commit %s", limit);
}
while (list) {
- unsigned char sha1[20];
char sign = '+';
commit = list->item;
- if (!get_patch_id(commit, &patch_id_opts, sha1) &&
- lookup_object(sha1))
+ if (has_commit_patch_id(commit, &ids))
sign = '-';
if (verbose) {
list = list->next;
}
+ free_patch_ids(&ids);
return 0;
}