List for cgit developers and users
 help / color / mirror / Atom feed
From: john at keeping.me.uk (John Keeping)
Subject: Bug: cgit shows empty pages, when viewing Tag-Only-Repo
Date: Sat, 16 Jun 2018 18:07:33 +0100	[thread overview]
Message-ID: <20180616170733.GI1922@john.keeping.me.uk> (raw)
In-Reply-To: <e96ae085b8a3d68104877a20843bc4b7c5c0d9b4.camel@pengutronix.de>

On Fri, May 04, 2018 at 08:20:10AM +0200, Bj?rn L?ssig wrote:
>  I use repositories for holding some tags.
> Unfortunately cgit shows only
> 
>   <red>Repository seems to be empty</red>
> 
> I looked into the code and saw the problem, but i have not the insight
> to fix this.
> 
> one (small) example for the Problem is:
> 
> https://git.pengutronix.de/cgit/ukl/distrokit/refs/
> 
> git ls-remote https://git.pengutronix.de/git/ukl/distrokit/
> shows a handful of refs.

I had a related patch hanging around which improves the behaviour when
the default branch doesn't exist, and it is easy to expand this to pick
a default ref when there are no branches.

I'm not sure if I sent this to the list in the past; certainly there are
arguments as to why this behaviour isn't desirable.

The requirement for a default ref is baked in throughout the CGit code
base and I don't think changing that is worthwhile, but providing we can
pick some ref as the default, it doesn't necessarily have to be a
branch.  So this patch allows any ref to be the default (albeit with a
strong preference for branches if any exist).

-- >8 --
Subject: [PATCH] cgit: improve default branch selection

If the named default branch does not exist (for example because none is
specified in the config and "master" is not used in the repositry), then
we currently select the first branch in whatever order Git returns them
to us.

Instead, let's use the newest branch (by commit date), since this is
likely to be the most interesting branch in the repository.  This does
make default branch selection more expensive, but people who care should
specify a default branch in their repository configuration.

Further, if a repository has no branches but does have tags, let's pick
the newest tag as the default head [1].  This is a separate pass because
we want to prefer branches if there are any.

[1] In fact, we allow any ref at this point because we want to avoid
    falsely claiming that the repository is empty when it isn't.

Signed-off-by: John Keeping <john at keeping.me.uk>
---
 cgit.c | 46 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/cgit.c b/cgit.c
index bd9cb3f..43b8c96 100644
--- a/cgit.c
+++ b/cgit.c
@@ -430,7 +430,6 @@ static void prepare_context(void)
 
 struct refmatch {
 	char *req_ref;
-	char *first_ref;
 	int match;
 };
 
@@ -442,34 +441,59 @@ static int find_current_ref(const char *refname, const struct object_id *oid,
 	info = (struct refmatch *)cb_data;
 	if (!strcmp(refname, info->req_ref))
 		info->match = 1;
-	if (!info->first_ref)
-		info->first_ref = xstrdup(refname);
 	return info->match;
 }
 
-static void free_refmatch_inner(struct refmatch *info)
+struct newest_ref {
+	char *ref;
+	unsigned long date;
+};
+
+static int find_newest_ref(const char *refname, const struct object_id *oid,
+			   int flags, void *cb_data)
 {
-	if (info->first_ref)
-		free(info->first_ref);
+	struct newest_ref *newest = cb_data;
+	struct object *object;
+	unsigned long date;
+
+	object = parse_object(oid);
+	if (object->type == OBJ_COMMIT) {
+		date = ((struct commit *)object)->date;
+		if (date > newest->date) {
+			free(newest->ref);
+			newest->ref = xstrdup(refname);
+			newest->date = date;
+		}
+	}
+	return 0;
 }
 
 static char *find_default_branch(struct cgit_repo *repo)
 {
 	struct refmatch info;
+	struct newest_ref newest = { NULL };
 	char *ref;
 
 	info.req_ref = repo->defbranch;
-	info.first_ref = NULL;
 	info.match = 0;
 	for_each_branch_ref(find_current_ref, &info);
-	if (info.match)
+	if (info.match) {
 		ref = info.req_ref;
-	else
-		ref = info.first_ref;
+	} else {
+		/*
+		 * If the default branch isn't found, pick the most recently
+		 * updated branch, and if there are no branches, check if
+		 * this is a tag-only repo and pick any ref we can.
+		 */
+		for_each_branch_ref(find_newest_ref, &newest);
+		if (!newest.ref)
+			for_each_ref(find_newest_ref, &newest);
+		ref = newest.ref;
+	}
 	if (ref)
 		ref = xstrdup(ref);
-	free_refmatch_inner(&info);
 
+	free(newest.ref);
 	return ref;
 }
 
-- 
2.17.1



      reply	other threads:[~2018-06-16 17:07 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-04  6:20 
2018-06-16 17:07 ` john [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180616170733.GI1922@john.keeping.me.uk \
    --to=cgit@lists.zx2c4.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).