git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/7] log: add --rename-notes to correct renames per commit

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jan 20, 2016, 11:06 UTC
Message-ID
<1453287968-26000-5-git-send-email-pclouds@gmail.com>
In-Reply-To
<1453287968-26000-1-git-send-email-pclouds@gmail.com>

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@gmail.com>
---
 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
Previous: Junio C HamanoNext: Junio C Hamano
Message 12 of 20 in “Diff rename, manual correction, round 2”
  1. 0/7 Diff rename, manual correction, round 2Nguyễn Thái Ngọc Duy, Jan 20, 2016
  2. 1/7 diff-no-index: do not take a redundant prefix argumentNguyễn Thái Ngọc Duy, Jan 20, 2016
  3. 2/7 diff.c: take "prefix" argument in diff_opt_parse()Nguyễn Thái Ngọc Duy, Jan 20, 2016
  4. Junio C HamanoJan 20, 2016
  5. Jeff KingJan 20, 2016
  6. Junio C HamanoJan 20, 2016
  7. Duy NguyenJan 21, 2016
  8. Junio C HamanoJan 21, 2016
  9. 3/7 diff: add --rename-fileNguyễn Thái Ngọc Duy, Jan 20, 2016
  10. Junio C HamanoJan 20, 2016
  11. Junio C HamanoJan 20, 2016
  12. 4/7 log: add --rename-notes to correct renames per commitNguyễn Thái Ngọc Duy, Jan 20, 2016
  13. Junio C HamanoJan 20, 2016
  14. Duy NguyenJan 22, 2016
  15. 5/7 merge: add --rename-fileNguyễn Thái Ngọc Duy, Jan 20, 2016
  16. 6/7 diffcore-rename: allow to say "rename this blob to that blob"Nguyễn Thái Ngọc Duy, Jan 20, 2016
  17. 7/7 merge: add --rename-notesNguyễn Thái Ngọc Duy, Jan 20, 2016
  18. Junio C HamanoJan 21, 2016
  19. Duy NguyenJan 22, 2016
  20. Junio C HamanoJan 22, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.