Subject: Re: gitattributes export-subst and software versioning

From: René Scharfe <[email-masked]>
Date: Sun, 14 Feb 2021 11:04:25 +0100

Am 09.02.21 um 01:19 schrieb Eli Schwartz:
> On the other hand, with my zero knowledge of the code but having read
> lots of man pages... %S documents that it "only works with git log", so
> maybe it is possible to add an option that is documented to only work
> for git archive?
>
> e.g. if you do use it,
>
> $ cat VERSION
> $Format:%d$
> $Format:%S$
>
> $ git archive HEAD | bsdtar -xOf - VERSION
>  (HEAD -> master, tag: 1.0)
> %S
>
> It's apparently completely ignored and treated as raw characters. The
> same restriction could theoretically be added in the other direction for
> a new placeholder.

That's a curious case.  Supporting %S in git archive would be easy  --
it's just a matter of recording the name given at the command line for
the pretty format code to find, like in the sloppy patch below (missing
doc update, missing test, leaks memory, adds a static variable to
library code).

The inconsistent support of %S is not ideal and I think that set a bad
precedent, but on the other hand I don't see its usefulness for git
archive in particular.  So I dunno.  Perhaps worth doing once rev-list
gains support, for completeness.

René

---
 archive.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/archive.c b/archive.c
index 5919d9e505..ffe4c35961 100644
--- a/archive.c
+++ b/archive.c
@@ -9,6 +9,7 @@
 #include "parse-options.h"
 #include "unpack-trees.h"
 #include "dir.h"
+#include "revision.h"

 static char const * const archive_usage[] = {
 	N_("git archive [<options>] <tree-ish> [<path>...]"),
@@ -23,6 +24,8 @@ static int nr_archivers;
 static int alloc_archivers;
 static int remote_allow_unreachable;

+static struct revision_sources revision_sources;
+
 void register_archiver(struct archiver *ar)
 {
 	ALLOC_GROW(archivers, nr_archivers + 1, alloc_archivers);
@@ -41,7 +44,8 @@ static void format_subst(const struct commit *commit,
 {
 	char *to_free = NULL;
 	struct strbuf fmt = STRBUF_INIT;
-	struct pretty_print_context ctx = {0};
+	struct rev_info rev = { .sources = &revision_sources };
+	struct pretty_print_context ctx = { .rev = &rev };
 	ctx.date_mode.type = DATE_NORMAL;
 	ctx.abbrev = DEFAULT_ABBREV;

@@ -461,6 +465,8 @@ static void parse_treeish_arg(const char **argv,

 	commit = lookup_commit_reference_gently(ar_args->repo, &oid, 1);
 	if (commit) {
+		init_revision_sources(&revision_sources);
+		*revision_sources_at(&revision_sources, commit) = xstrdup(name);
 		commit_oid = &commit->object.oid;
 		archive_time = commit->date;
 	} else {
--
2.30.1