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

[PATCH] show: add --follow-symlinks option for <rev>:<path>

From
Michael Vogt <mvo@ubuntu.com>
Date
Apr 16, 2018, 09:36 UTC
Message-ID
<20180416093625.15752-2-mvo@ubuntu.com>
In-Reply-To
<20180416093625.15752-1-mvo@ubuntu.com>

Add a --follow-symlinks option that'll resolve symlinks to their targets when the target is of the form <rev>:<path>.

Without it, git will show the path of the link itself if the symlink is the leaf node of <path>, or otherwise an error if some component of <path> is a symlink to another location in the repository. With the new --follow-symlinks option both will be resolved to their target, and its content shown instead.

Signed-off-by: Michael Vogt <mvo@ubuntu.com>
---
 Documentation/git-show.txt |  7 +++++++
 builtin/log.c              |  6 +++++-
 revision.c                 |  2 ++
 revision.h                 |  1 +
 t/t1800-git-show.sh        | 41 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100755 t/t1800-git-show.sh
diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index e73ef5401..e2634b27e 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -39,6 +39,13 @@ OPTIONS
 	For a more complete list of ways to spell object names, see
 	"SPECIFYING REVISIONS" section in linkgit:gitrevisions[7].
 
+--follow-symlinks::
+	Follow symlinks inside the repository when requesting objects
+	in extended revision syntax of the form tree-ish:path-in-tree.
+	It will resolve any symlinks in <path-in-tree> and shows the
+	content	of the link if the symlink is the leaf node of
+	<path-in-tree>.
+
 include::pretty-options.txt[]
 
 
diff --git a/builtin/log.c b/builtin/log.c
index 94ee177d5..7d815b8ea 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -142,7 +142,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 			 struct rev_info *rev, struct setup_revision_opt *opt)
 {
 	struct userformat_want w;
-	int quiet = 0, source = 0, mailmap = 0;
+	int quiet = 0, source = 0, mailmap = 0, follow_symlinks = 0;
 	static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
 	static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
 	static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
@@ -162,6 +162,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 		OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
 			     N_("Process line range n,m in file, counting from 1"),
 			     log_line_range_callback),
+		OPT_BOOL(0, "follow-symlinks", &follow_symlinks,
+			 N_("follow in-tree symlinks (used when showing file content)")),
 		OPT_END()
 	};
 
@@ -176,6 +178,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 
 	if (quiet)
 		rev->diffopt.output_format |= DIFF_FORMAT_NO_OUTPUT;
+	if (follow_symlinks)
+		rev->follow_symlinks = 1;
 	argc = setup_revisions(argc, argv, rev, opt);
 
 	/* Any arguments at this point are not recognized */
diff --git a/revision.c b/revision.c
index b42c836d7..4ab22313f 100644
--- a/revision.c
+++ b/revision.c
@@ -1678,6 +1678,8 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
 
 	if (revarg_opt & REVARG_COMMITTISH)
 		get_sha1_flags |= GET_OID_COMMITTISH;
+	if (revs && revs->follow_symlinks)
+		get_sha1_flags |= GET_OID_FOLLOW_SYMLINKS;
 
 	if (get_oid_with_context(arg, get_sha1_flags, &oid, &oc))
 		return revs->ignore_missing ? 0 : -1;
diff --git a/revision.h b/revision.h
index b8c47b98e..060f1038a 100644
--- a/revision.h
+++ b/revision.h
@@ -122,6 +122,7 @@ struct rev_info {
 			first_parent_only:1,
 			line_level_traverse:1,
 			tree_blobs_in_commit_order:1,
+			follow_symlinks:1,
 
 			/* for internal use only */
 			exclude_promisor_objects:1;
diff --git a/t/t1800-git-show.sh b/t/t1800-git-show.sh
new file mode 100755
index 000000000..7a02438ec
--- /dev/null
+++ b/t/t1800-git-show.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+test_description='Test git show works'
+
+. ./test-lib.sh
+
+test_expect_success 'verify git show HEAD:foo works' '
+	test_commit A &&
+	git show HEAD:A.t >actual &&
+	echo A >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success SYMLINKS 'verify git show HEAD:symlink shows symlink points to foo' '
+	ln -s A.t A.link &&
+	git add A.link &&
+	git commit -m"Added symlink to A.t" &&
+	git show HEAD:A.link >actual &&
+	printf "%s" A.t >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success SYMLINKS 'verify git show --follow-symlinks HEAD:symlink shows foo' '
+	git show --follow-symlinks HEAD:A.link >actual &&
+	echo A >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success SYMLINKS 'verify git show --follow-symlinks HEAD:symlink works with subdirs' '
+	mkdir dir &&
+	ln -s dir symlink-to-dir &&
+	test_commit dir/B &&
+	git add dir symlink-to-dir &&
+	git commit -m "add dir and symlink-to-dir" &&
+	test_must_fail git show HEAD:symlink-to-dir/B.t >actual &&
+	git show --follow-symlinks HEAD:symlink-to-dir/B.t >actual &&
+	echo dir/B >expected &&
+	test_cmp expected actual
+'
+
+test_done
-- 
2.17.0
Previous: Michael VogtNext: Junio C Hamano
Message 10 of 12 in “Add "git show --follow-symlinks HEAD:symlink"”
  1. Add "git show --follow-symlinks HEAD:symlink"Michael Vogt, Apr 9, 2018
  2. Ævar Arnfjörð BjarmasonApr 9, 2018
  3. Michael VogtApr 13, 2018
  4. Stefan BellerApr 13, 2018
  5. Michael VogtApr 13, 2018
  6. Ævar Arnfjörð BjarmasonApr 13, 2018
  7. support: git show --follow-symlinks HEAD:symlinkMichael Vogt, Apr 13, 2018
  8. Ævar Arnfjörð BjarmasonApr 13, 2018
  9. show: add --follow-symlinks option for <rev>:<path>Michael Vogt, Apr 16, 2018
  10. show: add --follow-symlinks option for <rev>:<path>Michael Vogt, Apr 16, 2018
  11. Junio C HamanoApr 16, 2018
  12. Michael VogtApr 13, 2018

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.