Git development
 help / color / mirror / Atom feed
* [PATCH] gitweb: fix uninitialized variable warning.
From: Martin Waitz @ 2006-09-16 21:09 UTC (permalink / raw)
  To: git

Perl spit out a varning when "blob" or "blob_plain" actions were
used without a $hash parameter.

Signed-off-by: Martin Waitz <tali@admingilde.org>
---
 gitweb/gitweb.perl |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 2789657..ee561c6 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -2380,11 +2380,7 @@ sub git_heads {
 }
 
 sub git_blob_plain {
-	# blobs defined by non-textual hash id's can be cached
 	my $expires;
-	if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
-		$expires = "+1d";
-	}
 
 	if (!defined $hash) {
 		if (defined $file_name) {
@@ -2394,7 +2390,11 @@ sub git_blob_plain {
 		} else {
 			die_error(undef, "No file name defined");
 		}
+	} elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) {
+		# blobs defined by non-textual hash id's can be cached
+		$expires = "+1d";
 	}
+
 	my $type = shift;
 	open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
 		or die_error(undef, "Couldn't cat $file_name, $hash");
@@ -2422,11 +2422,7 @@ sub git_blob_plain {
 }
 
 sub git_blob {
-	# blobs defined by non-textual hash id's can be cached
 	my $expires;
-	if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
-		$expires = "+1d";
-	}
 
 	if (!defined $hash) {
 		if (defined $file_name) {
@@ -2436,7 +2432,11 @@ sub git_blob {
 		} else {
 			die_error(undef, "No file name defined");
 		}
+	} elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) {
+		# blobs defined by non-textual hash id's can be cached
+		$expires = "+1d";
 	}
+
 	my $have_blame = gitweb_check_feature('blame');
 	open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
 		or die_error(undef, "Couldn't cat $file_name, $hash");
-- 
1.4.2.gb8b6b

-- 
Martin Waitz

^ permalink raw reply related

* [PATCH] gitweb: use correct mime type even if filename has multiple dots.
From: Martin Waitz @ 2006-09-16 21:09 UTC (permalink / raw)
  To: git

Match the last part of the filename agains the extention from the
mime database instead of insisting that it starts at the first dot.

Signed-off-by: Martin Waitz <tali@admingilde.org>
---
 gitweb/gitweb.perl |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ee561c6..7501251 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1106,7 +1106,6 @@ sub mimetype_guess_file {
 	my $mimemap = shift;
 	-r $mimemap or return undef;
 
-	my %mimemap;
 	open(MIME, $mimemap) or return undef;
 	while (<MIME>) {
 		next if m/^#/; # skip comments
@@ -1114,14 +1113,16 @@ sub mimetype_guess_file {
 		if (defined $exts) {
 			my @exts = split(/\s+/, $exts);
 			foreach my $ext (@exts) {
-				$mimemap{$ext} = $mime;
+				if ($filename =~ /\.$ext$/) {
+					close(MIME);
+					return $mime;
+				}
 			}
 		}
 	}
 	close(MIME);
 
-	$filename =~ /\.(.*?)$/;
-	return $mimemap{$1};
+	return undef;
 }
 
 sub mimetype_guess {
-- 
1.4.2.gb8b6b

-- 
Martin Waitz

^ permalink raw reply related

* [PATCH] gitweb: option 'strict export'
From: Matthias Lederhofer @ 2006-09-16 21:43 UTC (permalink / raw)
  To: git
In-Reply-To: <20060916192750.GA27008@moooo.ath.cx>

With this option enabled gitweb will only give access to repositories
which are also shown on the overview page.
---
Matthias Lederhofer <matled@gmx.net> wrote:
> Perhaps there should be another option which allows only those
> repositories to be shown which are in $projects_list.
Here it is.  This option is probably the one more likely to be used.
It disallows access to repositories (using ?p=path/to/repository) that
are not on the projects-list-page.
---
 Makefile           |    2 ++
 gitweb/gitweb.perl |   12 +++++++++++-
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 63df24c..0e17d4c 100644
--- a/Makefile
+++ b/Makefile
@@ -133,6 +133,7 @@ GITWEB_CSS = gitweb.css
 GITWEB_LOGO = git-logo.png
 GITWEB_FAVICON = git-favicon.png
 GITWEB_EXPORT_OK =
+GITWEB_STRICT_EXPORT =
 
 export prefix bindir gitexecdir template_dir GIT_PYTHON_DIR
 
@@ -639,6 +640,7 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
 	    -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
 	    -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
 	    -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \
+	    -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \
 	    $< >$@+
 	chmod +x $@+
 	mv $@+ $@
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 3944d13..976f7ec 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -57,6 +57,9 @@ our $projects_list = "++GITWEB_LIST++";
 # show repository only if this file exists
 our $export_ok = "++GITWEB_EXPORT_OK++";
 
+# only allow viewing of repositories also shown on the overview page
+our $strict_export = "++GITWEB_STRICT_EXPORT++";
+
 # list of git base URLs used for URL to where fetch project from,
 # i.e. full URL is "$git_base_url/$project"
 our @git_base_url_list = ("++GITWEB_BASE_URL++");
@@ -189,7 +192,8 @@ if (defined $project) {
 	}
 	if (!(-d "$projectroot/$project") ||
 	    !(-e "$projectroot/$project/HEAD") ||
-	    ($export_ok && !(-e "$projectroot/$project/$export_ok"))) {
+	    ($export_ok && !(-e "$projectroot/$project/$export_ok")) ||
+	    ($strict_export && !project_in_list($project))) {
 		undef $project;
 		die_error(undef, "No such project");
 	}
@@ -384,6 +388,12 @@ sub untabify {
 	return $line;
 }
 
+sub project_in_list {
+	my $project = shift;
+	my @list = git_get_projects_list();
+	return(@list && scalar(grep { $_->{'path'} eq $project } @list) != 0);
+}
+
 ## ----------------------------------------------------------------------
 ## HTML aware string manipulation
 
-- 
1.4.2.g0ea2

^ permalink raw reply related

* Re: [PATCH] gitweb: use correct mime type even if filename has multiple dots.
From: Jakub Narebski @ 2006-09-16 21:44 UTC (permalink / raw)
  To: git
In-Reply-To: <20060916210933.GX17042@admingilde.org>

Martin Waitz wrote:

> Match the last part of the filename agains the extention from the
> mime database instead of insisting that it starts at the first dot.
[...]
> -     $filename =~ /\.(.*?)$/;
> -     return $mimemap{$1};

Actually, that is non-greedy match, so the above code insist that 
extension starts at the _last_ dot.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] gitweb: more support for PATH_INFO based URLs
From: Jakub Narebski @ 2006-09-16 21:46 UTC (permalink / raw)
  To: git
In-Reply-To: <20060916210832.GV17042@admingilde.org>

Martin Waitz wrote:

> Now three types of path based URLs are supported:
>         gitweb.cgi/project.git
>         gitweb.cgi/project.git/branch
>         gitweb.cgi/project.git/branch/filename
> 
> The first one (show project summary) was already supported for a long time
> now.  The other two are new: they show the shortlog of a branch or
> the plain file contents of some file contained in the repository.
> 
> This is especially useful to support project web pages for small
> projects: just create an html branch and then use an URL like
> gitweb.cgi/project.git/html/index.html.

Very nice.

Acked-by: Jakub Narebski <jnareb@gmail.com>

(if it matters)
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* [PATCH/current master] gitweb: do not use 'No such directory' error message
From: Matthias Lederhofer @ 2006-09-16 22:30 UTC (permalink / raw)
  To: git
In-Reply-To: <20060916192750.GA27008@moooo.ath.cx>

undef $project; to prevent a file named description to be read.
---
Sorry, I patched an old version.  Here is the patch for the current
master/next.
---
 gitweb/gitweb.perl |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a81c8d4..07ea1ea 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -203,13 +203,10 @@ if (defined $project) {
 	$project = undef unless $project;
 }
 if (defined $project) {
-	if (!validate_input($project)) {
-		die_error(undef, "Invalid project parameter");
-	}
-	if (!(-d "$projectroot/$project")) {
-		die_error(undef, "No such directory");
-	}
-	if (!(-e "$projectroot/$project/HEAD")) {
+	if (!validate_input($project) ||
+	    !(-d "$projectroot/$project") ||
+	    !(-e "$projectroot/$project/HEAD")) {
+		undef $project;
 		die_error(undef, "No such project");
 	}
 	$git_dir = "$projectroot/$project";
-- 
1.4.2.g0ea2

^ permalink raw reply related

* [PATCH] gitweb: export options
From: Matthias Lederhofer @ 2006-09-16 22:31 UTC (permalink / raw)
  To: git
In-Reply-To: <20060916223027.GA32679@moooo.ath.cx>

$export_ok: If this variable evaluates to true it is checked
if a file with this name exists in the repository.  If it
does not exist the repository cannot be viewed from gitweb.
(Similar to git-daemon-export-ok for git-daemon).

$strict_export: If this variable evaluates to true only
repositories listed on the project-list-page of gitweb can
be accessed.
---
 Makefile           |    4 ++++
 gitweb/gitweb.perl |   23 ++++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 7b3114f..b9938ac 100644
--- a/Makefile
+++ b/Makefile
@@ -126,6 +126,8 @@ GITWEB_CONFIG = gitweb_config.perl
 GITWEB_HOME_LINK_STR = projects
 GITWEB_SITENAME =
 GITWEB_PROJECTROOT = /pub/git
+GITWEB_EXPORT_OK =
+GITWEB_STRICT_EXPORT =
 GITWEB_BASE_URL =
 GITWEB_LIST =
 GITWEB_HOMETEXT = indextext.html
@@ -631,6 +633,8 @@ gitweb/gitweb.cgi: gitweb/gitweb.perl
 	    -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
 	    -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
 	    -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
+	    -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \
+	    -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \
 	    -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \
 	    -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \
 	    -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 07ea1ea..2a63c17 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -54,6 +54,13 @@ our $favicon = "++GITWEB_FAVICON++";
 # source of projects list
 our $projects_list = "++GITWEB_LIST++";
 
+# show repository only if this file exists
+# (only effective if this variable evaluates to true)
+our $export_ok = "++GITWEB_EXPORT_OK++";
+
+# only allow viewing of repositories also shown on the overview page
+our $strict_export = "++GITWEB_STRICT_EXPORT++";
+
 # list of git base URLs used for URL to where fetch project from,
 # i.e. full URL is "$git_base_url/$project"
 our @git_base_url_list = ("++GITWEB_BASE_URL++");
@@ -205,7 +212,9 @@ if (defined $project) {
 if (defined $project) {
 	if (!validate_input($project) ||
 	    !(-d "$projectroot/$project") ||
-	    !(-e "$projectroot/$project/HEAD")) {
+	    !(-e "$projectroot/$project/HEAD") ||
+	    ($export_ok && !(-e "$projectroot/$project/$export_ok")) ||
+	    ($strict_export && !project_in_list($project))) {
 		undef $project;
 		die_error(undef, "No such project");
 	}
@@ -402,6 +411,12 @@ sub untabify {
 	return $line;
 }
 
+sub project_in_list {
+	my $project = shift;
+	my @list = git_get_projects_list();
+	return @list && scalar(grep { $_->{'path'} eq $project } @list);
+}
+
 ## ----------------------------------------------------------------------
 ## HTML aware string manipulation
 
@@ -714,7 +729,8 @@ sub git_get_projects_list {
 
 				my $subdir = substr($File::Find::name, $pfxlen + 1);
 				# we check related file in $projectroot
-				if (-e "$projectroot/$subdir/HEAD") {
+				if (-e "$projectroot/$subdir/HEAD" && (!$export_ok ||
+				    -e "$projectroot/$subdir/$export_ok")) {
 					push @list, { path => $subdir };
 					$File::Find::prune = 1;
 				}
@@ -735,7 +751,8 @@ sub git_get_projects_list {
 			if (!defined $path) {
 				next;
 			}
-			if (-e "$projectroot/$path/HEAD") {
+			if (-e "$projectroot/$path/HEAD" && (!$export_ok ||
+			    -e "$projectroot/$path/$export_ok")) {
 				my $pr = {
 					path => $path,
 					owner => decode("utf8", $owner, Encode::FB_DEFAULT),
-- 
1.4.2.g0ea2

^ permalink raw reply related

* [PATCH] Add virtualization support to git-daemon
From: Jon Loeliger @ 2006-09-16 22:38 UTC (permalink / raw)
  To: git


Signed-off-by: Jon Loeliger

---

Junio,

Here is a rebase of my patches to support virtual hosts
in git-daemon.  This rebase accounts for the changes in
handling the table of daemon services recently introduced.

I use an inetd invocation like this example:

    git  stream  tcp  nowait  nobody  /usr/bin/git-daemon git-daemon --inetd
        --verbose --syslog
        --export-all --interpolated-path=/pub/%H/%D
	/pub/software /software
	/pub/www.example.com/software
	/pub/www.example.org/software
	/pub

Still room for improvements, of course.

Thanks,
jdl


 Makefile      |    4 ++
 daemon.c      |  100 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 interpolate.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++
 interpolate.h |   13 +++++++
 4 files changed, 189 insertions(+), 11 deletions(-)

diff --git a/Makefile b/Makefile
index 7b3114f..673ba2d 100644
--- a/Makefile
+++ b/Makefile
@@ -244,7 +244,9 @@ DIFF_OBJS = \
 
 LIB_OBJS = \
 	blob.o commit.o connect.o csum-file.o cache-tree.o base85.o \
-	date.o diff-delta.o entry.o exec_cmd.o ident.o lockfile.o \
+	date.o diff-delta.o entry.o exec_cmd.o ident.o \
+	interpolate.o \
+	lockfile.o \
 	object.o pack-check.o patch-delta.o path.o pkt-line.o \
 	quote.o read-cache.o refs.o run-command.o dir.o object-refs.o \
 	server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
diff --git a/daemon.c b/daemon.c
index b14d808..7822545 100644
--- a/daemon.c
+++ b/daemon.c
@@ -12,6 +12,7 @@ #include <grp.h>
 #include "pkt-line.h"
 #include "cache.h"
 #include "exec_cmd.h"
+#include "interpolate.h"
 
 static int log_syslog;
 static int verbose;
@@ -21,6 +22,7 @@ static const char daemon_usage[] =
 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
 "           [--base-path=path] [--user-path | --user-path=path]\n"
+"           [--interpolated-path=path]\n"
 "           [--reuseaddr] [--detach] [--pid-file=file]\n"
 "           [--[enable|disable|allow-override|forbid-override]=service]\n"
 "           [--user=user [[--group=group]] [directory...]";
@@ -34,6 +36,10 @@ static int export_all_trees;
 
 /* Take all paths relative to this one if non-NULL */
 static char *base_path;
+static char *interpolated_path;
+
+/* Flag indicating client sent extra args. */
+static int saw_extended_args;
 
 /* If defined, ~user notation is allowed and the string is inserted
  * after ~user/.  E.g. a request to git://host/~alice/frotz would
@@ -45,6 +51,23 @@ static const char *user_path;
 static unsigned int timeout;
 static unsigned int init_timeout;
 
+/*
+ * Static table for now.  Ugh.
+ * Feel free to make dynamic as needed.
+ */
+#define INTERP_SLOT_HOST	(0)
+#define INTERP_SLOT_DIR		(1)
+#define INTERP_SLOT_PERCENT	(2)
+
+struct interp interp_table[] = {
+	{ "%H", 0},
+	{ "%D", 0},
+	{ "%%", "%"},
+};
+
+#define N_INTERPS	(sizeof(interp_table) / sizeof(struct interp))
+
+
 static void logreport(int priority, const char *err, va_list params)
 {
 	/* We should do a single write so that it is atomic and output
@@ -152,10 +175,14 @@ static int avoid_alias(char *p)
 	}
 }
 
-static char *path_ok(char *dir)
+static char *path_ok(struct interp *itable)
 {
 	static char rpath[PATH_MAX];
+	static char interp_path[PATH_MAX];
 	char *path;
+	char *dir;
+
+	dir = itable[INTERP_SLOT_DIR].value;
 
 	if (avoid_alias(dir)) {
 		logerror("'%s': aliased", dir);
@@ -184,16 +211,34 @@ static char *path_ok(char *dir)
 			dir = rpath;
 		}
 	}
+	else if (interpolated_path && saw_extended_args) {
+		if (*dir != '/') {
+			/* Allow only absolute */
+			logerror("'%s': Non-absolute path denied (interpolated-path active)", dir);
+			return NULL;
+		}
+
+		loginfo("Before interpolation '%s'", dir);
+		loginfo("Interp slot 0 (%s,%s)",
+			interp_table[0].name, interp_table[0].value);
+		loginfo("Interp slot 1 (%s,%s)",
+			interp_table[1].name, interp_table[1].value);
+		interpolate(interp_path, PATH_MAX, interpolated_path,
+			    interp_table, N_INTERPS);
+		loginfo("After interpolation '%s'", interp_path);
+		dir = interp_path;
+	}
 	else if (base_path) {
 		if (*dir != '/') {
 			/* Allow only absolute */
 			logerror("'%s': Non-absolute path denied (base-path active)", dir);
 			return NULL;
 		}
-		else {
-			snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
-			dir = rpath;
-		}
+		snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
+		loginfo("dir was %s", dir);
+		loginfo("base_path is %s", base_path);
+		loginfo("rpath now %s", rpath);
+		dir = rpath;
 	}
 
 	path = enter_repo(dir, strict_paths);
@@ -257,12 +302,14 @@ static int git_daemon_config(const char 
 	return 0;
 }
 
-static int run_service(char *dir, struct daemon_service *service)
+static int run_service(struct interp *itable, struct daemon_service *service)
 {
 	const char *path;
 	int enabled = service->enabled;
 
-	loginfo("Request %s for '%s'", service->name, dir);
+	loginfo("Request %s for '%s'",
+		service->name,
+		itable[INTERP_SLOT_DIR].value);
 
 	if (!enabled && !service->overridable) {
 		logerror("'%s': service not enabled.", service->name);
@@ -270,7 +317,7 @@ static int run_service(char *dir, struct
 		return -1;
 	}
 
-	if (!(path = path_ok(dir)))
+	if (!(path = path_ok(itable)))
 		return -1;
 
 	/*
@@ -351,6 +398,29 @@ static void make_service_overridable(con
 	die("No such service %s", name);
 }
 
+void parse_extra_args(char *extra_args, int buflen)
+{
+	char *val;
+	int vallen;
+	char *end = extra_args + buflen;
+
+	while (extra_args < end && *extra_args) {
+		saw_extended_args = 1;
+		loginfo("Extended arg %s", extra_args);
+		if (strncasecmp("host=", extra_args, 5) == 0) {
+			val = extra_args + 5;
+			vallen = strlen(val) + 1;
+			if (*val) {
+				char *save = xmalloc(vallen);
+				interp_table[INTERP_SLOT_HOST].value = save;
+				strlcpy(save, val, vallen);
+			}
+			/* On to the next one */
+			extra_args = val + vallen;
+		}
+	}
+}
+
 static int execute(struct sockaddr *addr)
 {
 	static char line[1000];
@@ -391,13 +461,19 @@ #endif
 	if (len && line[len-1] == '\n')
 		line[--len] = 0;
 
+	if (len != pktlen) {
+	    parse_extra_args(line + len + 1, pktlen - len - 1);
+	}
+
 	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
 		struct daemon_service *s = &(daemon_service[i]);
 		int namelen = strlen(s->name);
 		if (!strncmp("git-", line, 4) &&
 		    !strncmp(s->name, line + 4, namelen) &&
-		    line[namelen + 4] == ' ')
-			return run_service(line + namelen + 5, s);
+		    line[namelen + 4] == ' ') {
+			interp_table[INTERP_SLOT_DIR].value = line+namelen+5;
+			return run_service(interp_table, s);
+		}
 	}
 
 	logerror("Protocol error: '%s'", line);
@@ -860,6 +936,10 @@ int main(int argc, char **argv)
 			base_path = arg+12;
 			continue;
 		}
+		if (!strncmp(arg, "--interpolated-path=", 20)) {
+			interpolated_path = arg+20;
+			continue;
+		}
 		if (!strcmp(arg, "--reuseaddr")) {
 			reuseaddr = 1;
 			continue;
diff --git a/interpolate.c b/interpolate.c
new file mode 100644
index 0000000..30fa7a1
--- /dev/null
+++ b/interpolate.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2006 Jon Loeliger
+ */
+
+#include <string.h>
+
+#include "interpolate.h"
+
+
+/*
+ * Convert a NUL-terminated string in buffer orig
+ * into the supplied buffer, result, whose length is reslen,
+ * performing substitutions on %-named sub-strings from
+ * the table, interps, with ninterps entries.
+ *
+ * Example interps:
+ *    {
+ *        { "%H", "example.org"},
+ *        { "%port", "123"},
+ *        { "%%", "%"},
+ *    }
+ *
+ * Returns 1 on a successful substitution pass that fits in result,
+ * Returns 0 on a failed or overflowing substitution pass.
+ */
+
+int
+interpolate(char *result, int reslen,
+	    char *orig,
+	    struct interp *interps, int ninterps)
+{
+	char *src = orig;
+	char *dest = result;
+	int newlen = 0;
+	char *name, *value;
+	int namelen, valuelen;
+	int i;
+	char c;
+
+	bzero(result, reslen);
+
+	while ((c = *src) && newlen < reslen - 1) {
+		if (c == '%') {
+			/* Try to match an interpolation string. */
+			for (i = 0; i < ninterps; i++) {
+				name = interps[i].name;
+				namelen = strlen(name);
+				if (strncmp(src, name, namelen) == 0) {
+					break;
+				}
+			}
+
+			/* Check for valid interpolation. */
+			if (i < ninterps) {
+				value = interps[i].value;
+				valuelen = strlen(value);
+
+				if (newlen + valuelen < reslen - 1) {
+					/* Substitute. */
+					strncpy(dest, value, valuelen);
+					newlen += valuelen;
+					dest += valuelen;
+					src += namelen;
+				} else {
+					/* Something's not fitting. */
+					return 0;
+				}
+
+			} else {
+				/* Skip bogus interpolation. */
+				*dest++ = *src++;
+				newlen++;
+			}
+
+		} else {
+			/* Straight copy one non-interpolation character. */
+			*dest++ = *src++;
+			newlen++;
+		}
+	}
+
+	return newlen < reslen - 1;
+}
diff --git a/interpolate.h b/interpolate.h
new file mode 100644
index 0000000..241af7c
--- /dev/null
+++ b/interpolate.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2006 Jon Loeliger
+ */
+
+struct interp {
+	char *name;
+	char *value;
+};
+
+extern int interpolate(char *result, int reslen,
+		       char *orig,
+		       struct interp *interps, int ninterps);
+

^ permalink raw reply related

* Re: nightly tarballs of git
From: Dave Jones @ 2006-09-17  0:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3baradkb.fsf@assigned-by-dhcp.cox.net>

On Sat, Sep 16, 2006 at 11:09:24AM -0700, Junio C Hamano wrote:
 > Dave Jones <davej@redhat.com> writes:
 > 
 > > This went well, right up until you checked something in :-)
 > >
 > > Generating pack...
 > > Done counting 155 objects.
 > > Result has 126 objects.
 > > Deltifying 126 objects.
 > >    0% (1/126) done
 > > ...
 > > Unpacking 126 objects
 > > Total 126, written 126 (delta 93), reused 0 (delta 0)
 > > * refs/heads/origin: fast forward to branch 'master' of git://git.kernel.org/pub/scm/git/git
 > >   from 38529e28a4f465ad5d5f2fa249ca17da680bac5f to fc2b2be031f44aef0106cf7f872b750cd90b2253
 > > * refs/heads/pu: does not fast forward to branch 'pu' of git://git.kernel.org/pub/scm/git/git;
 > >   not updating.
 > > Something wicked happend.
 > 
 > You care only about 'master' in that repository anyway, so I
 > would suggest removing other lines from remotes/origin and have
 > only these two lines:
 > 
 > 	URL:  git://git.kernel.org/pub/scm/git/git
 >         Pull: refs/heads/master:refs/heads/origin

Thanks, I updated the repo, and kicked the snapshot script, and
it seems to be doing the right thing again.

	Dave

^ permalink raw reply

* [PATCH] gitweb:  Make git_get_refs_list do work of git_get_references
From: Jakub Narebski @ 2006-09-17  0:26 UTC (permalink / raw)
  To: git

Make git_get_refs_list do also work of git_get_references, to avoid
calling git-peek-remote twice. It now returns either list of refs as
before in scalar context, or references hash and list of refs in list
context. Change meaning of git_get_refs_list meaning: it is now type,
and not a full path, e.g. we now use git_get_refs_list("heads")
instead of former git_get_refs_list("refs/heads").

Additionally modify git_summary to use only one call to
git_get_refs_list instead of one call to git_get_references and two to
git_get_refs_list.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This was supposed to make gitweb performance better, by 
(in the case of git_summary) replacing three calls to git-peek-remote
(or one reading info/refs and two calls to git-peek-remote) by only 
one such a call. ApacheBench shows that after changes summary and tags 
views are slower, while heads remains the same.

  3520.593 +/- 29.2 ms after vs 3086.579 +/- 85.0 ms before (summary)
  3137.274 +/- 26.4 ms after vs 2504.025 +/- 46.1 ms before (tags)

I suspect benchmarks somewhat, but still...

 gitweb/gitweb.perl |   57 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 7908793..d5ce675 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1077,7 +1077,8 @@ ## .....................................
 ## parse to array of hashes functions
 
 sub git_get_refs_list {
-	my $ref_dir = shift;
+	my $type = shift || "";
+	my %refs;
 	my @reflist;
 
 	my @refs;
@@ -1085,14 +1086,21 @@ sub git_get_refs_list {
 		or return;
 	while (my $line = <$fd>) {
 		chomp $line;
-		if ($line =~ m/^([0-9a-fA-F]{40})\t$ref_dir\/?([^\^]+)$/) {
-			push @refs, { hash => $1, name => $2 };
-		} elsif ($line =~ m/^[0-9a-fA-F]{40}\t$ref_dir\/?(.*)\^\{\}$/ &&
-		         $1 eq $refs[-1]{'name'}) {
-			# most likely a tag is followed by its peeled
-			# (deref) one, and when that happens we know the
-			# previous one was of type 'tag'.
-			$refs[-1]{'type'} = "tag";
+		if ($line =~ m/^([0-9a-fA-F]{40})\trefs\/($type\/?([^\^]+))(\^\{\})?$/) {
+			if (defined $refs{$1}) {
+				push @{$refs{$1}}, $2;
+			} else {
+				$refs{$1} = [ $2 ];
+			}
+
+			if (! $4) { # unpeeled, direct reference
+				push @refs, { hash => $1, name => $3 }; # without type
+			} elsif ($1 eq $refs[-1]{'name'}) {
+				# most likely a tag is followed by its peeled
+				# (deref) one, and when that happens we know the
+				# previous one was of type 'tag'.
+				$refs[-1]{'type'} = "tag";
+			}
 		}
 	}
 	close $fd;
@@ -1108,7 +1116,7 @@ sub git_get_refs_list {
 	}
 	# sort refs by age
 	@reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist;
-	return \@reflist;
+	return wantarray ? (\%refs, \@reflist) : \@reflist;
 }
 
 ## ----------------------------------------------------------------------
@@ -2072,14 +2080,14 @@ sub git_tags_body {
 
 sub git_heads_body {
 	# uses global variable $project
-	my ($taglist, $head, $from, $to, $extra) = @_;
+	my ($headlist, $head, $from, $to, $extra) = @_;
 	$from = 0 unless defined $from;
-	$to = $#{$taglist} if (!defined $to || $#{$taglist} < $to);
+	$to = $#{$headlist} if (!defined $to || $#{$headlist} < $to);
 
 	print "<table class=\"heads\" cellspacing=\"0\">\n";
 	my $alternate = 0;
 	for (my $i = $from; $i <= $to; $i++) {
-		my $entry = $taglist->[$i];
+		my $entry = $headlist->[$i];
 		my %tag = %$entry;
 		my $curr = $tag{'id'} eq $head;
 		if ($alternate) {
@@ -2249,7 +2257,8 @@ sub git_summary {
 
 	my $owner = git_get_project_owner($project);
 
-	my $refs = git_get_references();
+	my ($refs, $reflist) = git_get_refs_list();
+
 	git_header_html();
 	git_print_page_nav('summary','', $head);
 
@@ -2279,17 +2288,17 @@ sub git_summary {
 	git_shortlog_body(\@revlist, 0, 15, $refs,
 	                  $cgi->a({-href => href(action=>"shortlog")}, "..."));
 
-	my $taglist = git_get_refs_list("refs/tags");
-	if (defined @$taglist) {
+	my @taglist = map { s!^tags/!! } grep { m!^tags/! } @$reflist;
+	if (@taglist) {
 		git_print_header_div('tags');
-		git_tags_body($taglist, 0, 15,
+		git_tags_body(\@taglist, 0, 15,
 		              $cgi->a({-href => href(action=>"tags")}, "..."));
 	}
 
-	my $headlist = git_get_refs_list("refs/heads");
-	if (defined @$headlist) {
+	my @headlist = map { s!^heads/!! } grep { m!^heads/! } @$reflist;
+	if (@headlist) {
 		git_print_header_div('heads');
-		git_heads_body($headlist, $head, 0, 15,
+		git_heads_body(\@headlist, $head, 0, 15,
 		               $cgi->a({-href => href(action=>"heads")}, "..."));
 	}
 
@@ -2500,7 +2509,7 @@ sub git_tags {
 	git_print_page_nav('','', $head,undef,$head);
 	git_print_header_div('summary', $project);
 
-	my $taglist = git_get_refs_list("refs/tags");
+	my $taglist = git_get_refs_list("tags");
 	if (defined @$taglist) {
 		git_tags_body($taglist);
 	}
@@ -2513,9 +2522,9 @@ sub git_heads {
 	git_print_page_nav('','', $head,undef,$head);
 	git_print_header_div('summary', $project);
 
-	my $taglist = git_get_refs_list("refs/heads");
-	if (defined @$taglist) {
-		git_heads_body($taglist, $head);
+	my $headlist = git_get_refs_list("heads");
+	if (defined @$headlist) {
+		git_heads_body($headlist, $head);
 	}
 	git_footer_html();
 }
-- 
1.4.2.1

^ permalink raw reply related

* [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references
From: Jakub Narebski @ 2006-09-17  0:37 UTC (permalink / raw)
  To: git
In-Reply-To: <200609170226.39330.jnareb@gmail.com>

Instead of trying to read info/refs file, which might not be present
(we did fallback to git-ls-remote), always use git-peek-remote in
git_get_references.

It is preparation for git_get_refs_info to also return references
info. We cannot use info/refs for git_get_refs_info as the information
contained therein is usually stale.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This patch should be before the one it is reply to, i.e.
  gitweb:  Make git_get_refs_list do work of git_get_references

 gitweb/gitweb.perl |   10 ++--------
 1 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a81c8d4..8c3c13d 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -786,16 +786,10 @@ sub git_get_project_owner {
 sub git_get_references {
 	my $type = shift || "";
 	my %refs;
-	my $fd;
 	# 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c	refs/tags/v2.6.11
 	# c39ae07f393806ccf406ef966e9a15afc43cc36a	refs/tags/v2.6.11^{}
-	if (-f "$projectroot/$project/info/refs") {
-		open $fd, "$projectroot/$project/info/refs"
-			or return;
-	} else {
-		open $fd, "-|", git_cmd(), "ls-remote", "."
-			or return;
-	}
+	open my $fd, "-|", $GIT, "peek-remote", "$projectroot/$project/"
+		or return;
 
 	while (my $line = <$fd>) {
 		chomp $line;
-- 
1.4.2.1

^ permalink raw reply related

* Setting up Password protected repositories?
From: Jon Loeliger @ 2006-09-17  0:52 UTC (permalink / raw)
  To: git

So at the risk of asking a dead-stupid question for which
I should likely be soundly beaten for even asking...

How does one set up a git repository on a public site
but password/ssh protected it so that only a few trusted
people can access and update it?

Clearly, we should be using ssh+git: here somehow, right?
git-daemon has to know where to server out the files from,
but how do we get it to enforce a ssh-based access?  It's
easy to prevent http: from serving out the repository --
just place it outside of the webroot directory structure.

I can already enforce pushes to be password protected,
but the protection on pulls and clones eludes me.  I'd
also like to NOT grant login shell access on the repository
server machine, so I'm envisioning placing pubic keys from
trusted people somewhere too...

I feel like I am being blindly stupid here.

Any help for the weary?

Thanks,
jdl

^ permalink raw reply

* Re: [PATCH] gitweb:  Make git_get_refs_list do work of git_get_references
From: Junio C Hamano @ 2006-09-17  1:22 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <200609170226.39330.jnareb@gmail.com>

Jakub Narebski <jnareb@gmail.com> writes:

> Make git_get_refs_list do also work of git_get_references, to avoid
> calling git-peek-remote twice. It now returns either list of refs as
> before in scalar context, or references hash and list of refs in list
> context.

I do not think we want to have too many functions that return
different things depending on contexts.  Forcing callers to
remember what the function does in which context is bad.  You
seem to like writing:

	my $value = that_function(@args)

but I'd
rather see all callers to say:

	my ($value) = that_function(@args);

even when they expect just one value from the function.  One
less thing to remember, and one less source of surprises.

Especially for this particular case, you are not even avoiding
extra computation when you are only returning list, so I do not
think making the return value depend on the calling context is
buying you much.

^ permalink raw reply

* Re: Setting up Password protected repositories?
From: Junio C Hamano @ 2006-09-17  1:24 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: git
In-Reply-To: <E1GOktx-0005JY-ER@jdl.com>

Jon Loeliger <jdl@jdl.com> writes:

> git-daemon has to know where to server out the files from,
> but how do we get it to enforce a ssh-based access?  It's
> easy to prevent http: from serving out the repository --
> just place it outside of the webroot directory structure.

It all depends on how you start git-daemon, but the last
parameters to git-daemon are path whitelist so presumably
placing the private repository outside of it should be enough.

Or am I missing something deeper?

^ permalink raw reply

* git-repack: Outof memory
From: Dongsheng Song @ 2006-09-17  1:31 UTC (permalink / raw)
  To: git

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all:


I'm import from subversion. The problem appears to be git-repack phase using too many memory:

$ git-repack -a -f -d --window=64 --depth=64
Generating pack...
Done counting 123497 objects.
Deltifying 123497 objects.
  24% (29677/123497) done

$ top

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 3572 www-data  18   0 2591m 1.9g  528 R   13 94.8  81:48.98 git-pack-object


$ free
             total       used       free     shared    buffers     cached
Mem:       2076308    2029824      46484          0       2760       6800
- -/+ buffers/cache:    2020264      56044
Swap:      1028152     684032     344120


How to compute memory usage of git-repack ?

Thanks and regards,

Dongsheng

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFDKVh90pbDJCgbHoRAlweAJ45DhTXI+bb+nb2Y+JlbIBoFusK8wCgk0U2
XcUc9K/chYiUYq3ZLychzcU=
=NzXf
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: [PATCH] gitweb:  Make git_get_refs_list do work of  git_get_references
From: Randal L. Schwartz @ 2006-09-17  1:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jakub Narebski, git
In-Reply-To: <7vodtf8eym.fsf@assigned-by-dhcp.cox.net>

>>>>> "Junio" == Junio C Hamano <junkio@cox.net> writes:

Junio> Jakub Narebski <jnareb@gmail.com> writes:
>> Make git_get_refs_list do also work of git_get_references, to avoid
>> calling git-peek-remote twice. It now returns either list of refs as
>> before in scalar context, or references hash and list of refs in list
>> context.

Junio> I do not think we want to have too many functions that return
Junio> different things depending on contexts.  Forcing callers to
Junio> remember what the function does in which context is bad.

That's even an inaccurate description, so an expert in Perl (I've
known a few) would just scratch his head.

You cannot ever ever return a list in a scalar context.  Ever.  Never ever.

You can return an array ref that *contains* a list of references, sure.
Perhaps that's what you mean, as in:

  return [$ref1, $ref2, $ref3, $ref4]; # scalar return

But to be sloppy about the terminology confuses me.  For example,
I can't tell from your description if you mean the list-value return is:

  return \%some_hash, $ref1, $ref2, $ref3, $ref4; # list return: N items

Or, reverse engineering your sloppiness on the other description, you
*MIGHT* mean:

  return \%some_hash, [$ref1, $ref2, $ref3, $ref4]; # list return: 2 items

Perl5 does *no* implicit referencing/dereferencing (just like C).  So yes,
being precise with your language is necessary.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

^ permalink raw reply

* Re: Setting up Password protected repositories?
From: Jon Loeliger @ 2006-09-17  2:07 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7virjn8eua.fsf@assigned-by-dhcp.cox.net>

So, like, the other day Junio C Hamano mumbled:
> 
> It all depends on how you start git-daemon, but the last
> parameters to git-daemon are path whitelist so presumably
> placing the private repository outside of it should be enough.
> 
> Or am I missing something deeper?

I want git-daemon to serve up the repository.
I just want to have it served to people who can
supply a password or have an ssh key in place.

jdl

^ permalink raw reply

* Re: [PATCH] gitweb:  Make git_get_refs_list do work of  git_get_references
From: Junio C Hamano @ 2006-09-17  2:12 UTC (permalink / raw)
  To: Randal L. Schwartz; +Cc: Jakub Narebski, git
In-Reply-To: <864pv7tgmx.fsf@blue.stonehenge.com>

merlyn@stonehenge.com (Randal L. Schwartz) writes:

>>>>>> "Junio" == Junio C Hamano <junkio@cox.net> writes:
>
> Junio> Jakub Narebski <jnareb@gmail.com> writes:
>>> Make git_get_refs_list do also work of git_get_references, to avoid
>>> calling git-peek-remote twice. It now returns either list of refs as
>>> before in scalar context, or references hash and list of refs in list
>>> context.
>
> Junio> I do not think we want to have too many functions that return
> Junio> different things depending on contexts.  Forcing callers to
> Junio> remember what the function does in which context is bad.
>
> That's even an inaccurate description, so an expert in Perl (I've
> known a few) would just scratch his head.
>
> You cannot ever ever return a list in a scalar context.  Ever.  Never ever.

That much I think I know.

The code I was complaining about tries to do something like
this:

	sub that_sub {
        	...
                return wantarray ? (\@bar, \%foo) : \@bar;
	}

and it is not done for optimization purposes (i.e. "if the
caller only wants one and we are returning \@bar then we do not
have to compute \%foo which is a big win" is not why it does
this wantarray business).

So the callers when interested in the sequence of things in 'bar'
typically say:

	my $the_list = that_sub(...);
        for (@$the_list) {
        	...
	}

while other callers say:

	my ($the_hash, $the_list) = that_sub(...);
	... use %$the_hash and @$the_list as see fit ...

And I was saying that getting rid of the "return wantwarray ? :"
business and write the first class of callers like this

	my ($the_list) = that_sub(...);
        for (@$the_list) {
        	...
	}

would be much less confusing.

^ permalink raw reply

* Re: [PATCH] gitweb:  Make git_get_refs_list do work of   git_get_references
From: Randal L. Schwartz @ 2006-09-17  2:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jakub Narebski, git
In-Reply-To: <7vejub8cms.fsf@assigned-by-dhcp.cox.net>

>>>>> "Junio" == Junio C Hamano <junkio@cox.net> writes:

Junio> That much I think I know.

I think you know too.  I even know now that you think you know. :)

The comment was more for Jakub, I believe.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

^ permalink raw reply

* Re: Setting up Password protected repositories?
From: Junio C Hamano @ 2006-09-17  2:18 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: git
In-Reply-To: <E1GOm3h-0005jq-5u@jdl.com>

Jon Loeliger <jdl@jdl.com> writes:

> So, like, the other day Junio C Hamano mumbled:
>> 
>> It all depends on how you start git-daemon, but the last
>> parameters to git-daemon are path whitelist so presumably
>> placing the private repository outside of it should be enough.
>> 
>> Or am I missing something deeper?
>
> I want git-daemon to serve up the repository.
> I just want to have it served to people who can
> supply a password or have an ssh key in place.

Sorry, git-daemon was written as anonymous download service from
the beginning and there is no provision for something like that
in place (as you probably have noticed when you hacked on it
recently ;-)).

Letting them ssh-in, and if you do not trust them giving them
git-shell as their login shell, might be an option.  I do not
think of anything else offhand that is already available.

^ permalink raw reply

* Re: Setting up Password protected repositories?
From: Shawn Pearce @ 2006-09-17  2:20 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: Junio C Hamano, git
In-Reply-To: <E1GOm3h-0005jq-5u@jdl.com>

Jon Loeliger <jdl@jdl.com> wrote:
> So, like, the other day Junio C Hamano mumbled:
> > 
> > It all depends on how you start git-daemon, but the last
> > parameters to git-daemon are path whitelist so presumably
> > placing the private repository outside of it should be enough.
> > 
> > Or am I missing something deeper?
> 
> I want git-daemon to serve up the repository.
> I just want to have it served to people who can
> supply a password or have an ssh key in place.

Don't use git-daemon.

Instead create UNIX accounts for the people who need access and if
you don't want them to actually be able to login set their shell
to be `git-sh`.  This is a special shell-like thing that only lets
the user push or fetch to any repository they have access to.

The URL is a 'git+ssh' style URL and they will use SSH to connect.

Access is controlled by standard UNIX user/group read/write access
and ACLs if your OS/filesystem support them.  You can also control
pushing with an update hook.

-- 
Shawn.

^ permalink raw reply

* Re: git-repack: Outof memory
From: Shawn Pearce @ 2006-09-17  2:25 UTC (permalink / raw)
  To: Dongsheng Song; +Cc: git
In-Reply-To: <450CA561.9030602@gmail.com>

Dongsheng Song <dongsheng.song@gmail.com> wrote:
> I'm import from subversion. The problem appears to be git-repack phase using too many memory:
> 
> $ git-repack -a -f -d --window=64 --depth=64
> Generating pack...
> Done counting 123497 objects.
> Deltifying 123497 objects.
>   24% (29677/123497) done
> 
> $ top
> 
>   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
>  3572 www-data  18   0 2591m 1.9g  528 R   13 94.8  81:48.98 git-pack-object

*ouch* You are probably running out of address space if you are on
a 32 bit architecture.  A 2.5 GiB virtual address space is pretty
close to the maximum allowed on most OSes.

The code that I'm sitting on but haven't yet completed rebasing
onto current Git would probably help here.

Do you have any existing .pack files in .git/objects/pack?  How big
are they and their corresponding .idx files?

git-repack will need to mmap every .pack and .idx in
.git/objects/pack, plus it needs working memory for each object
(123,497 of 'em) but as I recall its pretty frugal on its per-object
allocation.  It can easily work with as many as 2 million objects on
a 32 bit system, assuming the .pack and .idx files aren't too large.
 
-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] gitweb:  Make git_get_refs_list do work of  git_get_references
From: Junio C Hamano @ 2006-09-17  2:29 UTC (permalink / raw)
  To: Randal L. Schwartz; +Cc: Jakub Narebski, git
In-Reply-To: <7vejub8cms.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> writes:

> The code I was complaining about tries to do something like
> this:
>
> 	sub that_sub {
>         	...
>                 return wantarray ? (\@bar, \%foo) : \@bar;
> 	}
>
> and it is not done for optimization purposes (i.e. "if the
> caller only wants one and we are returning \@bar then we do not
> have to compute \%foo which is a big win" is not why it does
> this wantarray business).

Note.  I did not mean to imply conditional return should be done
for performance reasons.

And I do not think the way this conditional return is done
serves better DWIMmery, which was my primary complaint.  So I
should probably have said "It's not for better DWIM, it is not
even for better performance, and I do not see a point".

^ permalink raw reply

* [PATCH 1/2] Add [-s|--hash] option to Linus' show-ref.
From: Christian Couder @ 2006-09-17  4:20 UTC (permalink / raw)
  To: Junio Hamano; +Cc: git

With this option only the sha1 hash of the ref should
be printed.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 builtin-show-ref.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 161b236..577d934 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -3,9 +3,10 @@ #include "refs.h"
 #include "object.h"
 #include "tag.h"
 
-static const char show_ref_usage[] = "git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--deref] [--tags] [--heads] [--] [pattern*]";
+static const char show_ref_usage[] = "git show-ref [-q|--quiet] [--verify] [-h|--head] [-d|--deref] [-s|--hash] [--tags] [--heads] [--] [pattern*]";
 
-static int deref_tags = 0, show_head = 0, tags_only = 0, heads_only = 0, found_match = 0, verify = 0, quiet = 0;
+static int deref_tags = 0, show_head = 0, tags_only = 0, heads_only = 0,
+	found_match = 0, verify = 0, quiet = 0, hash_only = 0;
 static const char **pattern;
 
 static int show_ref(const char *refname, const unsigned char *sha1)
@@ -50,7 +51,10 @@ match:
 	}
 	if (quiet)
 		return 0;
-	printf("%s %s\n", sha1_to_hex(sha1), refname);
+	if (hash_only)
+		printf("%s\n", sha1_to_hex(sha1));
+	else
+		printf("%s %s\n", sha1_to_hex(sha1), refname);
 	if (deref_tags && obj->type == OBJ_TAG) {
 		obj = deref_tag(obj, refname, 0);
 		printf("%s %s^{}\n", sha1_to_hex(obj->sha1), refname);
@@ -86,6 +90,10 @@ int cmd_show_ref(int argc, const char **
 			deref_tags = 1;
 			continue;
 		}
+		if (!strcmp(arg, "-s") || !strcmp(arg, "--hash")) {
+			hash_only = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--verify")) {
 			verify = 1;
 			continue;
-- 
1.4.2.1.gea00f-dirty

^ permalink raw reply related

* [PATCH 2/2] Use Linus' show ref in "git-branch.sh".
From: Christian Couder @ 2006-09-17  4:32 UTC (permalink / raw)
  To: Junio Hamano; +Cc: git
In-Reply-To: <20060917062024.c476e07d.chriscool@tuxfamily.org>

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 git-branch.sh |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-branch.sh b/git-branch.sh
index e0501ec..2600e9c 100755
--- a/git-branch.sh
+++ b/git-branch.sh
@@ -21,7 +21,7 @@ delete_branch () {
 	,,)
 	    die "What branch are you on anyway?" ;;
 	esac
-	branch=$(cat "$GIT_DIR/refs/heads/$branch_name") &&
+	branch=$(git-show-ref --verify --hash -- "refs/heads/$branch_name") &&
 	    branch=$(git-rev-parse --verify "$branch^0") ||
 		die "Seriously, what branch are you talking about?"
 	case "$option" in
@@ -112,7 +112,7 @@ rev=$(git-rev-parse --verify "$head") ||
 git-check-ref-format "heads/$branchname" ||
 	die "we do not like '$branchname' as a branch name."
 
-if [ -e "$GIT_DIR/refs/heads/$branchname" ]
+if git-show-ref --verify --quiet -- "refs/heads/$branchname"
 then
 	if test '' = "$force"
 	then
-- 
1.4.2.1.gea00f-dirty

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox