Merge branch 'jc/maint-rebase-am' into maint

* jc/maint-rebase-am:
  rebase: do not munge commit log message

Conflicts:

	git-am.sh
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index dc36c66..9c81b72 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -11,28 +11,37 @@
 
 DESCRIPTION
 -----------
-Remove files from the working tree and from the index.  The
-files have to be identical to the tip of the branch, and no
-updates to its contents must have been placed in the staging
-area (aka index).  When --cached is given, the staged content has to
-match either the tip of the branch *or* the file on disk.
+Remove files from the index, or from the working tree and the index.
+`git rm` will not remove a file from just your working directory.
+(There is no option to remove a file only from the work tree
+and yet keep it in the index; use `/bin/rm` if you want to do that.)
+The files being removed have to be identical to the tip of the branch,
+and no updates to their contents can be staged in the index,
+though that default behavior can be overridden with the `-f` option.
+When '--cached' is given, the staged content has to
+match either the tip of the branch or the file on disk,
+allowing the file to be removed from just the index.
 
 
 OPTIONS
 -------
 <file>...::
 	Files to remove.  Fileglobs (e.g. `*.c`) can be given to
-	remove all matching files.  Also a leading directory name
-	(e.g. `dir` to add `dir/file1` and `dir/file2`) can be
-	given to remove all files in the directory, recursively,
-	but this requires `-r` option to be given for safety.
+	remove all matching files.  If you want git to expand
+	file glob characters, you may need to shell-escape them.
+	A leading directory name
+	(e.g. `dir` to remove `dir/file1` and `dir/file2`) can be
+	given to remove all files in the directory, and recursively
+	all sub-directories,
+	but this requires the `-r` option to be explicitly given.
 
 -f::
 	Override the up-to-date check.
 
 -n, \--dry-run::
-        Don't actually remove the file(s), just show if they exist in
-        the index.
+	Don't actually remove any file(s).  Instead, just show
+	if they exist in the index and would otherwise be removed
+	by the command.
 
 -r::
         Allow recursive removal when a leading directory name is
@@ -44,9 +53,9 @@
 	for command-line options).
 
 \--cached::
-	This option can be used to tell the command to remove
-	the paths only from the index, leaving working tree
-	files.
+	Use this option to unstage and remove paths only from the index.
+	Working tree files, whether modified or not, will be
+	left alone.
 
 \--ignore-unmatch::
 	Exit with a zero status even if no files matched.
@@ -59,11 +68,15 @@
 DISCUSSION
 ----------
 
-The list of <file> given to the command can be exact pathnames,
-file glob patterns, or leading directory name.  The command
-removes only the paths that is known to git.  Giving the name of
+The <file> list given to the command can be exact pathnames,
+file glob patterns, or leading directory names.  The command
+removes only the paths that are known to git.  Giving the name of
 a file that you have not told git about does not remove that file.
 
+File globbing matches across directory boundaries.  Thus, given
+two directories `d` and `d2`, there is a difference between
+using `git rm \'d\*\'` and `git rm \'d/\*\'`, as the former will
+also remove all of directory `d2`.
 
 EXAMPLES
 --------
@@ -72,11 +85,10 @@
 	`Documentation` directory and any of its subdirectories.
 +
 Note that the asterisk `\*` is quoted from the shell in this
-example; this lets the command include the files from
-subdirectories of `Documentation/` directory.
+example; this lets git, and not the shell, expand the pathnames
+of files and subdirectories under the `Documentation/` directory.
 
 git-rm -f git-*.sh::
-	Remove all git-*.sh scripts that are in the index.
 	Because this example lets the shell expand the asterisk
 	(i.e. you are listing the files explicitly), it
 	does not remove `subdir/git-foo.sh`.
diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt
index 8eadc20..b7d09c1 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 <rutger@nospam.com>
-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 @@
 
 - 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 @@
 
 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 @@
 
    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 @@
 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 @@
 
 To check whether all is OK, do:
 
-   curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/
+   curl --netrc --location -v http://<username>@<servername>/my-new-repo.git/HEAD
 
-...this should give a directory listing in HTML of /var/www/my-new-repo.git .
-
+...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 @@
 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 @@
 
   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 <Johannes.Schindelin@gmx.de>
   Rutger Nijlunsing <git@wingding.demon.nl>
+  Matthieu Moy <Matthieu.Moy@imag.fr>
diff --git a/builtin-remote.c b/builtin-remote.c
index d77f10a..8fe31db 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -88,18 +88,22 @@
 	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/git-am.sh b/git-am.sh
index 5a7695e..75886a8 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -338,7 +338,7 @@
 			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"
 		fi
 		;;
@@ -392,7 +392,6 @@
 			;;
 		esac
 	esac
-	FIRSTLINE=$(head -1 "$dotest/final-commit")
 
 	resume=
 	if test "$interactive" = t
@@ -413,7 +412,6 @@
 		[aA]*) action=yes interactive= ;;
 		[nN]*) action=skip ;;
 		[eE]*) git_editor "$dotest/final-commit"
-		       FIRSTLINE=$(head -1 "$dotest/final-commit")
 		       action=again ;;
 		[vV]*) action=again
 		       LESS=-S ${PAGER:-less} "$dotest/patch" ;;
@@ -423,6 +421,7 @@
 	else
 	    action=yes
 	fi
+	FIRSTLINE=$(head -1 "$dotest/final-commit")
 
 	if test $action = skip
 	then
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 73d098a..746153f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -5171,14 +5171,26 @@
 	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/remote.c b/remote.c
index 369dc33..06ad156 100644
--- a/remote.c
+++ b/remote.c
@@ -409,7 +409,7 @@
 	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 @@
 	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 7e9ae79..a38774b 100644
--- a/remote.h
+++ b/remote.h
@@ -67,6 +67,7 @@
  */
 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 0a7fea8..af2d077 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -253,4 +253,10 @@
 
 '
 
+test_expect_success 'reject adding remote with an invalid name' '
+
+	! git remote add some:url desired-name
+
+'
+
 test_done
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 796cd7d..061a259 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -483,6 +483,22 @@
 	'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