TEST_BUILTINS_OBJS += test-read-cache.o
TEST_BUILTINS_OBJS += test-ref-store.o
TEST_BUILTINS_OBJS += test-regex.o
+TEST_BUILTINS_OBJS += test-repository.o
TEST_BUILTINS_OBJS += test-revision-walking.o
TEST_BUILTINS_OBJS += test-run-command.o
TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
LIB_OBJS += ewah/ewah_io.o
LIB_OBJS += ewah/ewah_rlw.o
LIB_OBJS += exec-cmd.o
+LIB_OBJS += fetch-negotiator.o
LIB_OBJS += fetch-object.o
LIB_OBJS += fetch-pack.o
LIB_OBJS += fsck.o
LIB_OBJS += graph.o
LIB_OBJS += grep.o
LIB_OBJS += hashmap.o
+LIB_OBJS += linear-assignment.o
LIB_OBJS += help.o
LIB_OBJS += hex.o
LIB_OBJS += ident.o
+ LIB_OBJS += interdiff.o
LIB_OBJS += kwset.o
LIB_OBJS += levenshtein.o
LIB_OBJS += line-log.o
LIB_OBJS += merge-recursive.o
LIB_OBJS += mergesort.o
LIB_OBJS += name-hash.o
+LIB_OBJS += negotiator/default.o
+LIB_OBJS += negotiator/skipping.o
LIB_OBJS += notes.o
LIB_OBJS += notes-cache.o
LIB_OBJS += notes-merge.o
LIB_OBJS += prompt.o
LIB_OBJS += protocol.o
LIB_OBJS += quote.o
+LIB_OBJS += range-diff.o
LIB_OBJS += reachable.o
LIB_OBJS += read-cache.o
LIB_OBJS += reflog-walk.o
BUILTIN_OBJS += builtin/prune.o
BUILTIN_OBJS += builtin/pull.o
BUILTIN_OBJS += builtin/push.o
+BUILTIN_OBJS += builtin/range-diff.o
BUILTIN_OBJS += builtin/read-tree.o
BUILTIN_OBJS += builtin/rebase--helper.o
BUILTIN_OBJS += builtin/receive-pack.o
#include "gpg-interface.h"
#include "progress.h"
#include "commit-slab.h"
+#include "repository.h"
+ #include "interdiff.h"
#define MAIL_DEFAULT_WRAP 72
rev.shown_one = 1;
if (ret)
break;
- o = parse_object(&t->tagged->oid);
+ o = parse_object(the_repository, &t->tagged->oid);
if (!o)
ret = error(_("Could not read object %s"),
oid_to_hex(&t->tagged->oid));
o2 = rev->pending.objects[1].item;
flags1 = o1->flags;
flags2 = o2->flags;
- c1 = lookup_commit_reference(&o1->oid);
- c2 = lookup_commit_reference(&o2->oid);
+ c1 = lookup_commit_reference(the_repository, &o1->oid);
+ c2 = lookup_commit_reference(the_repository, &o2->oid);
if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
die(_("Not a range."));
return branch;
}
+ static void show_diffstat(struct rev_info *rev,
+ struct commit *origin, struct commit *head)
+ {
+ struct diff_options opts;
+
+ memcpy(&opts, &rev->diffopt, sizeof(opts));
+ opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
+ opts.stat_width = MAIL_DEFAULT_WRAP;
+
+ diff_setup_done(&opts);
+
+ diff_tree_oid(get_commit_tree_oid(origin),
+ get_commit_tree_oid(head),
+ "", &opts);
+ diffcore_std(&opts);
+ diff_flush(&opts);
+
+ fprintf(rev->diffopt.file, "\n");
+ }
+
static void make_cover_letter(struct rev_info *rev, int use_stdout,
struct commit *origin,
int nr, struct commit **list,
struct strbuf sb = STRBUF_INIT;
int i;
const char *encoding = "UTF-8";
- struct diff_options opts;
int need_8bit_cte = 0;
struct pretty_print_context pp = {0};
struct commit *head = list[0];
shortlog_output(&log);
- /*
- * We can only do diffstat with a unique reference point
- */
- if (!origin)
- return;
+ /* We can only do diffstat with a unique reference point */
+ if (origin)
+ show_diffstat(rev, origin, head);
- memcpy(&opts, &rev->diffopt, sizeof(opts));
- opts.output_format = DIFF_FORMAT_SUMMARY | DIFF_FORMAT_DIFFSTAT;
- opts.stat_width = MAIL_DEFAULT_WRAP;
-
- diff_setup_done(&opts);
-
- diff_tree_oid(get_commit_tree_oid(origin),
- get_commit_tree_oid(head),
- "", &opts);
- diffcore_std(&opts);
- diff_flush(&opts);
-
- fprintf(rev->diffopt.file, "\n");
+ if (rev->idiff_oid1) {
+ fprintf_ln(rev->diffopt.file, "%s", rev->idiff_title);
+ show_interdiff(rev, 0);
+ }
}
static const char *clean_message_id(const char *msg_id)
oidclr(&bases->base_commit);
}
+ static const char *diff_title(struct strbuf *sb, int reroll_count,
+ const char *generic, const char *rerolled)
+ {
+ if (reroll_count <= 0)
+ strbuf_addstr(sb, generic);
+ else /* RFC may be v0, so allow -v1 to diff against v0 */
+ strbuf_addf(sb, rerolled, reroll_count - 1);
+ return sb->buf;
+ }
+
int cmd_format_patch(int argc, const char **argv, const char *prefix)
{
struct commit *commit;
struct base_tree_info bases;
int show_progress = 0;
struct progress *progress = NULL;
+ struct oid_array idiff_prev = OID_ARRAY_INIT;
+ struct strbuf idiff_title = STRBUF_INIT;
const struct option builtin_format_patch_options[] = {
{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
OPT__QUIET(&quiet, N_("don't print the patch filenames")),
OPT_BOOL(0, "progress", &show_progress,
N_("show progress while generating patches")),
+ OPT_CALLBACK(0, "interdiff", &idiff_prev, N_("rev"),
+ N_("show changes against <rev> in cover letter or single patch"),
+ parse_opt_object_name),
OPT_END()
};
if (rev.pending.nr == 2) {
struct object_array_entry *o = rev.pending.objects;
if (oidcmp(&o[0].item->oid, &o[1].item->oid) == 0)
- return 0;
+ goto done;
}
get_patch_ids(&rev, &ids);
}
}
if (nr == 0)
/* nothing to do */
- return 0;
+ goto done;
total = nr;
if (cover_letter == -1) {
if (config_cover_letter == COVER_AUTO)
if (numbered)
rev.total = total + start_number - 1;
+ if (idiff_prev.nr) {
+ if (!cover_letter && total != 1)
+ die(_("--interdiff requires --cover-letter or single patch"));
+ rev.idiff_oid1 = &idiff_prev.oid[idiff_prev.nr - 1];
+ rev.idiff_oid2 = get_commit_tree_oid(list[0]);
+ rev.idiff_title = diff_title(&idiff_title, reroll_count,
+ _("Interdiff:"),
+ _("Interdiff against v%d:"));
+ }
+
if (!signature) {
; /* --no-signature inhibits all signatures */
} else if (signature && signature != git_version_string) {
print_signature(rev.diffopt.file);
total++;
start_number--;
+ /* interdiff in cover-letter; omit from patches */
+ rev.idiff_oid1 = NULL;
}
rev.add_signoff = do_signoff;
string_list_clear(&extra_hdr, 0);
if (ignore_if_in_upstream)
free_patch_ids(&ids);
+
+ done:
+ oid_array_clear(&idiff_prev);
+ strbuf_release(&idiff_title);
return 0;
}
{
struct object_id oid;
if (get_oid(arg, &oid) == 0) {
- struct commit *commit = lookup_commit_reference(&oid);
+ struct commit *commit = lookup_commit_reference(the_repository,
+ &oid);
if (commit) {
commit->object.flags |= flags;
add_pending_object(revs, &commit->object, arg);
#include "config.h"
#include "diff.h"
#include "object-store.h"
+#include "repository.h"
#include "commit.h"
#include "tag.h"
#include "graph.h"
#include "sequencer.h"
#include "line-log.h"
#include "help.h"
+ #include "interdiff.h"
static struct decoration name_decoration = { "object names" };
static int decoration_loaded;
warning("invalid replace ref %s", refname);
return 0;
}
- obj = parse_object(&original_oid);
+ obj = parse_object(the_repository, &original_oid);
if (obj)
add_name_decoration(DECORATION_GRAFTED, "replaced", obj);
return 0;
}
- obj = parse_object(oid);
+ obj = parse_object(the_repository, oid);
if (!obj)
return 0;
if (!obj)
break;
if (!obj->parsed)
- parse_object(&obj->oid);
+ parse_object(the_repository, &obj->oid);
add_name_decoration(DECORATION_REF_TAG, refname, obj);
}
return 0;
static int add_graft_decoration(const struct commit_graft *graft, void *cb_data)
{
- struct commit *commit = lookup_commit(&graft->oid);
+ struct commit *commit = lookup_commit(the_repository, &graft->oid);
if (!commit)
return 0;
add_name_decoration(DECORATION_GRAFTED, "grafted", &commit->object);
size_t payload_size, gpg_message_offset;
hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &oid);
- tag = lookup_tag(&oid);
+ tag = lookup_tag(the_repository, &oid);
if (!tag)
return -1; /* error message already given */
strbuf_init(&verify_message, 256);
- if (parse_tag_buffer(tag, extra->value, extra->len))
+ if (parse_tag_buffer(the_repository, tag, extra->value, extra->len))
strbuf_addstr(&verify_message, "malformed mergetag\n");
else if (is_common_merge(commit) &&
!oidcmp(&tag->tagged->oid,
return for_each_mergetag(show_one_mergetag, commit, opt);
}
+ static void next_commentary_block(struct rev_info *opt, struct strbuf *sb)
+ {
+ const char *x = opt->shown_dashes ? "\n" : "---\n";
+ if (sb)
+ strbuf_addstr(sb, x);
+ else
+ fputs(x, opt->diffopt.file);
+ opt->shown_dashes = 1;
+ }
+
void show_log(struct rev_info *opt)
{
struct strbuf msgbuf = STRBUF_INIT;
struct log_info *log = opt->loginfo;
struct commit *commit = log->commit, *parent = log->parent;
- int abbrev_commit = opt->abbrev_commit ? opt->abbrev : GIT_SHA1_HEXSZ;
+ int abbrev_commit = opt->abbrev_commit ? opt->abbrev : the_hash_algo->hexsz;
const char *extra_headers = opt->extra_headers;
struct pretty_print_context ctx = {0};
if ((ctx.fmt != CMIT_FMT_USERFORMAT) &&
ctx.notes_message && *ctx.notes_message) {
- if (cmit_fmt_is_mail(ctx.fmt)) {
- strbuf_addstr(&msgbuf, "---\n");
- opt->shown_dashes = 1;
- }
+ if (cmit_fmt_is_mail(ctx.fmt))
+ next_commentary_block(opt, &msgbuf);
strbuf_addstr(&msgbuf, ctx.notes_message);
}
strbuf_release(&msgbuf);
free(ctx.notes_message);
+
+ if (cmit_fmt_is_mail(ctx.fmt) && opt->idiff_oid1) {
+ struct diff_queue_struct dq;
+
+ memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));
+ DIFF_QUEUE_CLEAR(&diff_queued_diff);
+
+ next_commentary_block(opt, NULL);
+ fprintf_ln(opt->diffopt.file, "%s", opt->idiff_title);
+ show_interdiff(opt, 2);
+
+ memcpy(&diff_queued_diff, &dq, sizeof(diff_queued_diff));
+ }
}
int log_tree_diff_flush(struct rev_info *opt)
/*
* We may have shown three-dashes line early
- * between notes and the log message, in which
- * case we only want a blank line after the
- * notes without (an extra) three-dashes line.
+ * between generated commentary (notes, etc.)
+ * and the log message, in which case we only
+ * want a blank line after the commentary
+ * without (an extra) three-dashes line.
* Otherwise, we show the three-dashes line if
* we are showing the patch with diffstat, but
* in that case, there is no extra blank line
#define SYMMETRIC_LEFT (1u<<8)
#define PATCHSAME (1u<<9)
#define BOTTOM (1u<<10)
+#define USER_GIVEN (1u<<25) /* given directly by the user */
#define TRACK_LINEAR (1u<<26)
-#define ALL_REV_FLAGS (((1u<<11)-1) | TRACK_LINEAR)
+#define ALL_REV_FLAGS (((1u<<11)-1) | USER_GIVEN | TRACK_LINEAR)
#define DECORATE_SHORT_REFS 1
#define DECORATE_FULL_REFS 2
/* notes-specific options: which refs to show */
struct display_notes_opt notes_opt;
+ /* interdiff */
+ const struct object_id *idiff_oid1;
+ const struct object_id *idiff_oid2;
+ const char *idiff_title;
+
/* commit counts */
int count_left;
int count_right;