For simplicity, the note of commit A implies rename correction between A^ and A. If parents are manipulated (e.g. "git log --reflog") then the rename output may surprise people. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- Documentation/pretty-options.txt | 5 +++++ log-tree.c | 32 ++++++++++++++++++++++++++++++++ revision.c | 10 ++++++++++ revision.h | 1 + t/t4001-diff-rename.sh | 24 ++++++++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt index 4b659ac..15a2971 100644 --- a/Documentation/pretty-options.txt +++ b/Documentation/pretty-options.txt @@ -75,6 +75,11 @@ being displayed. Examples: "--notes=foo" will show only notes from --[no-]standard-notes:: These options are deprecated. Use the above --notes/--no-notes options instead. + +--rename-notes=<ref>:: + Get per-commit rename instructions from notes. See option + `--rename-file` for more information. If both `--rename-notes` + and `--rename-file` are specified, the last one takes effect. endif::git-rev-list[] --show-signature:: diff --git a/log-tree.c b/log-tree.c index f70a30e..e5766a6 100644 --- a/log-tree.c +++ b/log-tree.c @@ -788,6 +788,36 @@ static int do_diff_combined(struct rev_info *opt, struct commit *commit) return !opt->loginfo; } +static void populate_rename_notes(struct rev_info *opt, const struct object_id *oid) +{ + static char *last_note; + enum object_type type; + unsigned long size; + const unsigned char *sha1; + + if (!opt->rename_notes) + return; + + /* + * "--rename-notes=abc --rename-file=def" is specified in this + * order, --rename-file wins. + */ + if (opt->diffopt.manual_renames != NULL && + opt->diffopt.manual_renames != last_note) + return; + + free(last_note); + opt->diffopt.manual_renames = NULL; + + sha1 = get_note(opt->rename_notes, oid->hash); + if (!sha1) + return; + + last_note = read_sha1_file(sha1, &type, &size); + if (type == OBJ_BLOB) + opt->diffopt.manual_renames = last_note; +} + /* * Show the diff of a commit. * @@ -805,6 +835,8 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log parse_commit_or_die(commit); oid = &commit->tree->object.oid; + populate_rename_notes(opt, &commit->object.oid); + /* Root commit? */ parents = get_saved_parents(opt, commit); if (!parents) { diff --git a/revision.c b/revision.c index 14daefb..20346c1 100644 --- a/revision.c +++ b/revision.c @@ -1958,6 +1958,16 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->notes_opt.use_default_notes = 1; } else if (!strcmp(arg, "--no-standard-notes")) { revs->notes_opt.use_default_notes = 0; + } else if (skip_prefix(arg, "--rename-notes=", &optarg)) { + struct strbuf buf = STRBUF_INIT; + struct notes_tree *nt; + + strbuf_addstr(&buf, optarg); + expand_notes_ref(&buf); + revs->rename_notes = nt = xcalloc(1, sizeof(*nt)); + init_notes(nt, buf.buf, NULL, 0); + strbuf_release(&buf); + revs->diffopt.manual_renames = NULL; } else if (!strcmp(arg, "--oneline")) { revs->verbose_header = 1; get_commit_format("oneline", revs); diff --git a/revision.h b/revision.h index 23857c0..db2f225 100644 --- a/revision.h +++ b/revision.h @@ -189,6 +189,7 @@ struct rev_info { /* diff info for patches and for paths limiting */ struct diff_options diffopt; struct diff_options pruning; + struct notes_tree *rename_notes; struct reflog_walk_info *reflog_info; struct decoration children; diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index ab9a666..21d9378 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -189,4 +189,28 @@ test_expect_success 'manual rename correction' ' ) ' +test_expect_success 'rename correction from notes' ' + ( + cd correct-rename && + git show --summary -M HEAD | grep rename >actual && + cat >expected <<-\EOF && + rename old-one => new-one (100%) + rename old-two => new-two (100%) + EOF + test_cmp expected actual && + + cat >correction <<-\EOF && + old-one => new-two + old-two => new-one + EOF + git notes --ref=rename add -F correction HEAD && + git show --summary -M --rename-notes=rename HEAD | grep rename >actual && + cat >expected <<-\EOF && + rename old-two => new-one (100%) + rename old-one => new-two (100%) + EOF + test_cmp expected actual + ) +' + test_done -- 2.7.0.125.g9eec362 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html