aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2016-06-25 22:29:24 +0100
committerRichard Maw <richard.maw@gmail.com>2016-07-13 20:09:37 +0100
commite407fe721380dddca7527611342d5aef49c28f33 (patch)
tree7ca63b76b7ae0845704af4d4e9e77ea85d478465
parentSet GIT_NAMESPACE when repo.namespace is provided (diff)
downloadcgit-e407fe721380dddca7527611342d5aef49c28f33.tar.xz
cgit-e407fe721380dddca7527611342d5aef49c28f33.zip
Look up refs in namespace with cgit_get_sha1
This causes all ref resolving to look for the requested branch inside the current namespace. Previously any form of git revision would be accepted, but ref resolving isn't namespace aware and it would be infeasible to replicate all its behaviour, so we stick to providing the most common cases of a sha1, an absolute ref, or a partial ref. Signed-off-by: Richard Maw <richard.maw@gmail.com>
-rw-r--r--shared.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/shared.c b/shared.c
index d82c07b..81a5cd8 100644
--- a/shared.c
+++ b/shared.c
@@ -602,7 +602,52 @@ char *get_mimetype_for_filename(const char *filename)
return NULL;
}
+static int namespaced_dwim_ref_get_sha1(const char *name, unsigned char *sha1)
+{
+ /* The standard git name disambiguation order is:
+ $name
+ refs/$name
+ refs/tags/$name
+ refs/heads/$name
+ refs/remotes/$name (not sure why)
+ refs/remotes/$name/HEAD
+ we don't care about remotes, so we can skip those,
+ and we can't specify a prefix for dwm_ref,
+ so we have to do this ourselves */
+ static const char *namespaced_ref_patterns[] = {
+ "%s%s",
+ "%srefs/%s",
+ "%srefs/tags/%s",
+ "%srefs/heads/%s",
+ NULL,
+ };
+ const char **p;
+
+ for (p = namespaced_ref_patterns; *p; p++) {
+ char *fullref = NULL;
+ const char *r;
+ fullref = mkpathdup(*p, get_git_namespace(), name);
+ r = resolve_ref_unsafe(fullref, RESOLVE_REF_READING, sha1, NULL);
+ free(fullref);
+ if (r)
+ return 0;
+ }
+ return 1;
+}
+
int cgit_get_sha1(const char *name, unsigned char *sha1)
{
- return get_sha1(name, sha1);
+ if (ctx.repo->namespace) {
+ /* If we have a namespace, we can get either a sha1,
+ or a possibly abbreviated ref.
+ Advanced ref forms are not supported at this time
+ as this would require reimplementing all of ref parsing.
+ If get_sha1_with_context grows support for a namespaced flag
+ then this code may go away. */
+ if (get_sha1_hex(name, sha1) == 0)
+ return 0;
+ return namespaced_dwim_ref_get_sha1(name, sha1);
+ } else {
+ return get_sha1(name, sha1);
+ }
}