From 29df2385d09611219c53d07f453794d6146e73a3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 18 Apr 2008 16:11:40 -0700 Subject: [PATCH 1/4] am: POSIX portability fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit POSIX allows echo without flag to interpret specials such as \n, and we tried to make things portable by using printf instead where it matters. Recently added code to "git am" had unprotected "echo", which was caught by t4014 and RĂ©mi Vanicat. This should fix it. Signed-off-by: Junio C Hamano --- git-am.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-am.sh b/git-am.sh index 6be33d9ddb..851f85eb55 100755 --- a/git-am.sh +++ b/git-am.sh @@ -302,7 +302,7 @@ do SUBJECT="$(sed -n '/^Subject/ s/Subject: //p' "$dotest/info")" case "$keep_subject" in -k) SUBJECT="[PATCH] $SUBJECT" ;; esac - (echo "$SUBJECT" ; echo ; cat "$dotest/msg") | + (printf '%s\n\n' "$SUBJECT"; cat "$dotest/msg") | git stripspace > "$dotest/msg-clean" ;; esac From 24b6177e0261efba063c0b83ae0cdc5993945da9 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Sun, 13 Apr 2008 11:56:54 +0200 Subject: [PATCH 2/4] git-remote: reject adding remotes with invalid names This can happen if the arguments to git-remote add is switched by the user, and git would only show an error if fetching was also requested. Fix it by using the refspec parsing engine to check if the requested name can be parsed as a remote before add it. Also cleanup so that the "remote..url" config name buffer is only initialized once. Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- builtin-remote.c | 10 +++++++--- remote.c | 21 ++++++++++++++++++--- remote.h | 1 + t/t5505-remote.sh | 6 ++++++ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/builtin-remote.c b/builtin-remote.c index d77f10a0ea..8fe31dbd9a 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -88,18 +88,22 @@ static int add(int argc, const char **argv) strbuf_init(&buf, 0); strbuf_init(&buf2, 0); + strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name); + if (!valid_fetch_refspec(buf2.buf)) + die("'%s' is not a valid remote name", name); + strbuf_addf(&buf, "remote.%s.url", name); if (git_config_set(buf.buf, url)) return 1; + strbuf_reset(&buf); + strbuf_addf(&buf, "remote.%s.fetch", name); + if (track.nr == 0) path_list_append("*", &track); for (i = 0; i < track.nr; i++) { struct path_list_item *item = track.items + i; - strbuf_reset(&buf); - strbuf_addf(&buf, "remote.%s.fetch", name); - strbuf_reset(&buf2); if (mirror) strbuf_addf(&buf2, "refs/%s:refs/%s", diff --git a/remote.c b/remote.c index 369dc3398c..06ad15627a 100644 --- a/remote.c +++ b/remote.c @@ -409,7 +409,7 @@ static void read_config(void) alias_all_urls(); } -static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch) +static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify) { int i; int st; @@ -519,17 +519,32 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp return rs; invalid: + if (verify) { + free(rs); + return NULL; + } die("Invalid refspec '%s'", refspec[i]); } +int valid_fetch_refspec(const char *fetch_refspec_str) +{ + const char *fetch_refspec[] = { fetch_refspec_str }; + struct refspec *refspec; + + refspec = parse_refspec_internal(1, fetch_refspec, 1, 1); + if (refspec) + free(refspec); + return !!refspec; +} + struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec) { - return parse_refspec_internal(nr_refspec, refspec, 1); + return parse_refspec_internal(nr_refspec, refspec, 1, 0); } struct refspec *parse_push_refspec(int nr_refspec, const char **refspec) { - return parse_refspec_internal(nr_refspec, refspec, 0); + return parse_refspec_internal(nr_refspec, refspec, 0, 0); } static int valid_remote_nick(const char *name) diff --git a/remote.h b/remote.h index 7e9ae792dc..a38774bbdc 100644 --- a/remote.h +++ b/remote.h @@ -67,6 +67,7 @@ void free_refs(struct ref *ref); */ void ref_remove_duplicates(struct ref *ref_map); +int valid_fetch_refspec(const char *refspec); struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec); struct refspec *parse_push_refspec(int nr_refspec, const char **refspec); diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 0a7fea865d..af2d077792 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -253,4 +253,10 @@ test_expect_success '"remote show" does not show symbolic refs' ' ' +test_expect_success 'reject adding remote with an invalid name' ' + + ! git remote add some:url desired-name + +' + test_done From f01f81505a401f774855ae07dd1be01efde0cfbd Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Sun, 13 Apr 2008 15:38:21 +0200 Subject: [PATCH 3/4] Document that WebDAV doesn't need git on the server, and works over SSL I managed to set up a Git repository on a preconfigured WebDAV server, and using HTTPS, without installing Git on it or changing the server configuration. This works through a proxy too. This patch reflects this (it previously stated that Git was _necessary_ on the server, which isn't true). Also give a few hints to troubleshoting. Signed-off-by: Matthieu Moy Signed-off-by: Junio C Hamano --- .../howto/setup-git-server-over-http.txt | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt index 8eadc20494..b7d09c1ec6 100644 --- a/Documentation/howto/setup-git-server-over-http.txt +++ b/Documentation/howto/setup-git-server-over-http.txt @@ -1,5 +1,5 @@ From: Rutger Nijlunsing -Subject: Setting up a git repository which can be pushed into and pulled from over HTTP. +Subject: Setting up a git repository which can be pushed into and pulled from over HTTP(S). Date: Thu, 10 Aug 2006 22:00:26 +0200 Since Apache is one of those packages people like to compile @@ -40,9 +40,13 @@ What's needed: - have permissions to chown a directory -- have git installed at the server _and_ client +- have git installed on the client, and -In effect, this probably means you're going to be root. +- either have git installed on the server or have a webdav client on + the client. + +In effect, this means you're going to be root, or that you're using a +preconfigured WebDAV server. Step 1: setup a bare GIT repository @@ -50,9 +54,9 @@ Step 1: setup a bare GIT repository At the time of writing, git-http-push cannot remotely create a GIT repository. So we have to do that at the server side with git. Another -option would be to generate an empty repository at the client and copy -it to the server with WebDAV. But then you're probably the first to -try that out :) +option is to generate an empty bare repository at the client and copy +it to the server with a WebDAV client (which is the only option if Git +is not installed on the server). Create the directory under the DocumentRoot of the directories served by Apache. As an example we take /usr/local/apache2, but try "grep @@ -169,7 +173,9 @@ On Debian: Most tests should pass. -A command line tool to test WebDAV is cadaver. +A command line tool to test WebDAV is cadaver. If you prefer GUIs, for +example, konqueror can open WebDAV URLs as "webdav://..." or +"webdavs://...". If you're into Windows, from XP onwards Internet Explorer supports WebDAV. For this, do Internet Explorer -> Open Location -> @@ -179,8 +185,9 @@ http:///my-new-repo.git [x] Open as webfolder -> login . Step 3: setup the client ------------------------ -Make sure that you have HTTP support, i.e. your git was built with curl. -The easiest way to check is to look for the executable 'git-http-push'. +Make sure that you have HTTP support, i.e. your git was built with +curl (version more recent than 7.10). The command 'git http-push' with +no argument should display a usage message. Then, add the following to your $HOME/.netrc (you can do without, but will be asked to input your password a _lot_ of times): @@ -197,10 +204,10 @@ instead of the server name. To check whether all is OK, do: - curl --netrc --location -v http://@/my-new-repo.git/ - -...this should give a directory listing in HTML of /var/www/my-new-repo.git . + curl --netrc --location -v http://@/my-new-repo.git/HEAD +...this should give something like 'ref: refs/heads/master', which is +the content of the file HEAD on the server. Now, add the remote in your existing repository which contains the project you want to export: @@ -225,6 +232,15 @@ want to export) to repository called 'upload', which we previously defined with git-config. +Using a proxy: +-------------- + +If you have to access the WebDAV server from behind an HTTP(S) proxy, +set the variable 'all_proxy' to 'http://proxy-host.com:port', or +'http://login-on-proxy:passwd-on-proxy@proxy-host.com:port'. See 'man +curl' for details. + + Troubleshooting: ---------------- @@ -248,9 +264,14 @@ Reading /usr/local/apache2/logs/error_log is often helpful. On Debian: Read /var/log/apache2/error.log instead. +If you access HTTPS locations, git may fail verifying the SSL +certificate (this is return code 60). Setting http.sslVerify=false can +help diagnosing the problem, but removes security checks. + Debian References: http://www.debian-administration.org/articles/285 Authors Johannes Schindelin Rutger Nijlunsing + Matthieu Moy From 5634cf24766f8700804ca55f5e8567c88538a5b0 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 13 Apr 2008 14:12:15 +0200 Subject: [PATCH 4/4] gitweb: Fix 'history' view for deleted files with history When asked for history of a file which is not present in given branch ("HEAD", i.e. current branch, or given by transient $hash_hase ('hb') parameter), but is present deeper in the history (meaning that "git rev-list --full-history $hash_base -- $file_name" is not empty), and there is no $hash ('h') parameter set for a file, gitweb would spew multiple of "Use of uninitialized value" warnings, and some links would be missing. This commit fixes this bug. This bug occurs in the rare cases when "git log -- " is empty and "git log --full-history -- " is not, or to be more exact in the cases when full-history starts later than given branch. It can happen if you are using handcrafted gitwb URL, or if you follow generic 'history' link or bookmark for a file which got deleted. Gitweb tried to get file type ('tree', or 'blob', or even 'commit') from the commit we start searching from (where the file was not present), and not among found commits. This was the cause of "Use of uninitialized value" warnings. This commit also add tests for such situation to t9500 test. While we are it, return HTTP error if there is _no_ history; it means that file or directory was not found (for given branch). Also error out if type of item could not be found: it should not happen now, but better be sure. Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 18 +++++++++++++++--- t/t9500-gitweb-standalone-no-errors.sh | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 73d098a433..746153ffe8 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -5171,14 +5171,26 @@ sub git_history { my $refs = git_get_references(); my $limit = sprintf("--max-count=%i", (100 * ($page+1))); + my @commitlist = parse_commits($hash_base, 101, (100 * $page), + $file_name, "--full-history"); + if (!@commitlist) { + die_error('404 Not Found', "No such file or directory on given branch"); + } + if (!defined $hash && defined $file_name) { - $hash = git_get_hash_by_path($hash_base, $file_name); + # some commits could have deleted file in question, + # and not have it in tree, but one of them has to have it + for (my $i = 0; $i <= @commitlist; $i++) { + $hash = git_get_hash_by_path($commitlist[$i]{'id'}, $file_name); + last if defined $hash; + } } if (defined $hash) { $ftype = git_get_type($hash); } - - my @commitlist = parse_commits($hash_base, 101, (100 * $page), $file_name, "--full-history"); + if (!defined $ftype) { + die_error(undef, "Unknown type of object"); + } my $paging_nav = ''; if ($page > 0) { diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 796cd7dba0..061a2596d3 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -483,6 +483,22 @@ test_expect_success \ 'gitweb_run "p=.git;a=history;f=file"' test_debug 'cat gitweb.log' +test_expect_success \ + 'logs: history (implicit HEAD, non-existent file)' \ + 'gitweb_run "p=.git;a=history;f=non-existent"' +test_debug 'cat gitweb.log' + +test_expect_success \ + 'logs: history (implicit HEAD, deleted file)' \ + 'git checkout master && + echo "to be deleted" > deleted_file && + git add deleted_file && + git commit -m "Add file to be deleted" && + git rm deleted_file && + git commit -m "Delete file" && + gitweb_run "p=.git;a=history;f=deleted_file"' +test_debug 'cat gitweb.log' + # ---------------------------------------------------------------------- # feed generation