RFC: snapshot tarball information in refs/notes/snapshots

John Keeping john at keeping.me.uk
Fri Mar 30 13:53:57 CEST 2018

On Wed, Mar 21, 2018 at 10:03:11AM -0400, Konstantin Ryabitsev wrote:
> It would be easy to load and parse refs/notes/cgitrc, and the security
> implications shouldn't be much different than loading the same from
> gitconfig.

Based on this comment, I had a go at just wiring up config parsing to
the existing parsing for gitconfig files; I don't think it's ideal
because that's in gitconfig format not cgitrc format but it's an easy
proof of concept.

Unfortunately there is one big gotcha I encountered doing this, which is
that we don't have the repository set up when we are scanning this
configuration, because this is done when building the repository list
not just for loading repository-specific pages.  Since one of the
configuration options is the repository description, I think this is

The ongoing work in git.git to support submodules in-process may help us
load multiple repositories into the same process while we're building
the repo list, but it looks like the changes we need haven't hit master
yet (although there are some changes in pu that look like they might be
exactly what we need, so maybe Git 2.18 will let us make this work).

Here's the patch I have for wiring up "read from ref", the idea is to
point to a blob containing the config, so it could be any of the

	refs/heads/master:cgitrc	# stored in master branch
	refs/heads/config:cgitrc	# stored in a config branch
	refs/blobs/cgitrc		# ref points directly at a blob

If you try it you'll find it promptly BUGs because the repo isn't set
up, but I'm interested in opinions on the configuration aspect of this.

-- >8 --
 cgit.c      | 2 ++
 cgit.h      | 1 +
 scan-tree.c | 8 ++++++++
 3 files changed, 11 insertions(+)

diff --git a/cgit.c b/cgit.c
index bd9cb3f..4170533 100644
--- a/cgit.c
+++ b/cgit.c
@@ -207,6 +207,8 @@ static void config_cb(const char *name, const char *value)
 		ctx.cfg.cache_snapshot_ttl = atoi(value);
 	else if (!strcmp(name, "case-sensitive-sort"))
 		ctx.cfg.case_sensitive_sort = atoi(value);
+	else if (!strcmp(name, "config-ref"))
+		ctx.cfg.config_ref = xstrdup(value);
 	else if (!strcmp(name, "about-filter"))
 		ctx.cfg.about_filter = cgit_new_filter(value, ABOUT);
 	else if (!strcmp(name, "commit-filter"))
diff --git a/cgit.h b/cgit.h
index 005ae63..fa2c35e 100644
--- a/cgit.h
+++ b/cgit.h
@@ -189,6 +189,7 @@ struct cgit_config {
 	char *cache_root;
 	char *clone_prefix;
 	char *clone_url;
+	char *config_ref;
 	char *css;
 	char *favicon;
 	char *footer;
diff --git a/scan-tree.c b/scan-tree.c
index 6a2f65a..b616005 100644
--- a/scan-tree.c
+++ b/scan-tree.c
@@ -127,6 +127,14 @@ static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
 		git_config_from_file(gitconfig_config, path->buf, NULL);
 		strbuf_setlen(path, pathlen);
+	if (ctx.cfg.config_ref) {
+		struct object_id oid;
+		if (!get_oid(ctx.cfg.config_ref, &oid))
+			git_config_from_blob_oid(gitconfig_config,
+						 ctx.cfg.config_ref, &oid,
+						 NULL);
+	}
 	if (ctx.cfg.remove_suffix) {
 		size_t urllen;

More information about the CGit mailing list