Merge branch 'jp/send-email-cc'

* jp/send-email-cc:
  git-send-email --cc-cmd
diff --git a/Documentation/RelNotes-1.5.3.txt b/Documentation/RelNotes-1.5.3.txt
index 9c36e8b..51ff53b 100644
--- a/Documentation/RelNotes-1.5.3.txt
+++ b/Documentation/RelNotes-1.5.3.txt
@@ -28,7 +28,7 @@
 * For people who need to import from Perforce, a front-end for
   fast-import is in contrib/fast-import/.
 
-* Comes with git-gui 0.8.0.
+* Comes with git-gui 0.8.2.
 
 * Comes with updated gitk.
 
@@ -130,6 +130,9 @@
 
   - "git init -q" makes the command quieter.
 
+  - "git -p command" now has a cousin of opposite sex, "git --no-pager
+    command".
+
 * Updated behavior of existing commands.
 
   - "gitweb" can offer multiple snapshot formats.
@@ -172,6 +175,15 @@
   - "git log" learned --log-size to show the number of bytes in
     the log message part of the output to help qgit.
 
+  - "git log --name-status" does not require you to give "-r" anymore.
+    As a general rule, Porcelain commands should recurse when showing
+    diff.
+
+  - "git format-patch --root A" can be used to format everything
+    since the beginning up to A.  This was supported with
+    "git format-patch --root A A" for a long time, but was not
+    properly documented.
+
   - "git svn dcommit" retains local merge information.
 
   - "git svnimport" allows an empty string to be specified as the
@@ -301,8 +313,8 @@
     when switching branches that have differences in only a
     handful paths.
 
-  - "git commit paths..." has also been optimized.
-
+  - "git add paths..." and "git commit paths..." has also been
+    heavily optimized.
 
 Fixes since v1.5.2
 ------------------
@@ -315,8 +327,26 @@
   - "gitweb" had trouble handling non UTF-8 text with older
     Encode.pm Perl module.
 
+  - "git-write-tree" had a bad interaction with racy-git avoidance and
+    gitattributes mechanisms.
+
+  - "git --bare command" overrode existing GIT_DIR setting and always
+    made it treat the current working directory as GIT_DIR.
+
+  - "git ls-files --error-unmatch" does not complain if you give the
+    same path pattern twice by mistake.
+
+  - "git init" autodetected core.filemode but not core.symlinks, which
+    made a new directory created automatically by "git clone" cumbersome
+    to use on filesystems that require these configurations to be set.
+
+  - "git log" family of commands behaved differently when run as "git
+    log" (no pathspec) and as "git log --" (again, no pathspec).  This
+    inconsistency was introduced somewhere in v1.3.0 series but now has
+    been corrected.
+
 --
 exec >/var/tmp/1
-O=v1.5.3-rc4
+O=v1.5.3-rc7-15-ga65f200
 echo O=`git describe refs/heads/master`
 git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 01354c2..61635bf 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -31,7 +31,8 @@
 	  corrupt whitespaces.
 	- provide additional information (which is unsuitable for
 	  the commit message) between the "---" and the diffstat
-	- send the patch to the list _and_ the maintainer
+	- send the patch to the list (git@vger.kernel.org) and the
+	  maintainer (gitster@pobox.com).
 	- if you change, add, or remove a command line option or
 	  make some other user interface change, the associated
 	  documentation should be updated as well.
diff --git a/Documentation/config.txt b/Documentation/config.txt
index de9e72b..866e053 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -192,7 +192,7 @@
 	variable and the '--work-tree' command line option.
 
 core.logAllRefUpdates::
-	Updates to a ref <ref> is logged to the file
+	Enable the reflog. Updates to a ref <ref> is logged to the file
 	"$GIT_DIR/logs/<ref>", by appending the new and old
 	SHA1, the date/time and the reason of the update, but
 	only when the file exists.  If this configuration
@@ -283,7 +283,7 @@
 
 core.editor::
 	Commands such as `commit` and `tag` that lets you edit
-	messages by lauching an editor uses the value of this
+	messages by launching an editor uses the value of this
 	variable when it is set, and the environment variable
 	`GIT_EDITOR` is not set.  The order of preference is
 	`GIT_EDITOR` environment, `core.editor`, `VISUAL` and
@@ -301,12 +301,12 @@
 	hide existing git commands are ignored. Arguments are split by
 	spaces, the usual shell quoting and escaping is supported.
 	quote pair and a backslash can be used to quote them.
-
-	If the alias expansion is prefixed with an exclamation point,
-	it will be treated as a shell command.  For example, defining
-	"alias.new = !gitk --all --not ORIG_HEAD", the invocation
-	"git new" is equivalent to running the shell command
-	"gitk --all --not ORIG_HEAD".
++
+If the alias expansion is prefixed with an exclamation point,
+it will be treated as a shell command.  For example, defining
+"alias.new = !gitk --all --not ORIG_HEAD", the invocation
+"git new" is equivalent to running the shell command
+"gitk --all --not ORIG_HEAD".
 
 apply.whitespace::
 	Tells `git-apply` how to handle whitespaces, in the same way
@@ -396,6 +396,16 @@
 commit.template::
 	Specify a file to use as the template for new commit messages.
 
+diff.autorefreshindex::
+	When using `git diff` to compare with work tree
+	files, do not consider stat-only change as changed.
+	Instead, silently run `git update-index --refresh` to
+	update the cached stat information for paths whose
+	contents in the work tree match the contents in the
+	index.  This option defaults to true.  Note that this
+	affects only `git diff` Porcelain, and not lower level
+	`diff` commands, such as `git diff-files`.
+
 diff.renameLimit::
 	The number of files to consider when performing the copy/rename
 	detection; equivalent to the git diff option '-l'.
@@ -465,11 +475,11 @@
 	be encountered again.  See gitlink:git-rerere[1].
 
 gitcvs.enabled::
-	Whether the cvs server interface is enabled for this repository.
+	Whether the CVS server interface is enabled for this repository.
 	See gitlink:git-cvsserver[1].
 
 gitcvs.logfile::
-	Path to a log file where the cvs server interface well... logs
+	Path to a log file where the CVS server interface well... logs
 	various stuff. See gitlink:git-cvsserver[1].
 
 gitcvs.allbinary::
@@ -500,10 +510,10 @@
 	'gitcvs.dbuser' supports variable substitution (see
 	gitlink:git-cvsserver[1] for details).
 
-All gitcvs variables except for 'gitcvs.allbinary' can also specifed
-as 'gitcvs.<access_method>.<varname>' (where 'access_method' is one
-of "ext" and "pserver") to make them apply only for the given access
-method.
+All gitcvs variables except for 'gitcvs.allbinary' can also be
+specified as 'gitcvs.<access_method>.<varname>' (where 'access_method'
+is one of "ext" and "pserver") to make them apply only for the given
+access method.
 
 http.sslVerify::
 	Whether to verify the SSL certificate when fetching or pushing
@@ -615,7 +625,7 @@
 	not set,  defaults to -1.
 
 pack.deltaCacheSize::
-	The maxium memory in bytes used for caching deltas in
+	The maximum memory in bytes used for caching deltas in
 	gitlink:git-pack-objects[1].
 	A value of 0 means no limit. Defaults to 0.
 
@@ -675,15 +685,11 @@
 	See gitlink:git-show-branch[1].
 
 tar.umask::
-	By default, gitlink:git-tar-tree[1] sets file and directories modes
-	to 0666 or 0777. While this is both useful and acceptable for projects
-	such as the Linux Kernel, it might be excessive for other projects.
-	With this variable, it becomes possible to tell
-	gitlink:git-tar-tree[1] to apply a specific umask to the modes above.
-	The special value "user" indicates that the user's current umask will
-	be used. This should be enough for most projects, as it will lead to
-	the same permissions as gitlink:git-checkout[1] would use. The default
-	value remains 0, which means world read-write.
+	This variable can be used to restrict the permission bits of
+	tar archive entries.  The default is 0002, which turns off the
+	world write bit.  The special value "user" indicates that the
+	archiving user's umask will be used instead.  See umask(2) and
+	gitlink:git-archive[1].
 
 user.email::
 	Your email address to be recorded in any newly created commits.
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 3383aca..2fe7355 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -7,7 +7,9 @@
 
 SYNOPSIS
 --------
-'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <file>...
+[verse]
+'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh]
+          [--] <filepattern>...
 
 DESCRIPTION
 -----------
@@ -31,9 +33,9 @@
 The 'git add' command will not add ignored files by default.  If any
 ignored files were explicitly specified on the command line, 'git add'
 will fail with a list of ignored files.  Ignored files reached by
-directory recursion or filename globbing will be silently ignored.
-The 'add' command can be used to add ignored files with the `-f`
-(force) option.
+directory recursion or filename globbing performed by Git (quote your
+globs before the shell) will be silently ignored.  The 'add' command can
+be used to add ignored files with the `-f` (force) option.
 
 Please see gitlink:git-commit[1] for alternative ways to add content to a
 commit.
@@ -41,7 +43,7 @@
 
 OPTIONS
 -------
-<file>...::
+<filepattern>...::
 	Files to add content from.  Fileglobs (e.g. `*.c`) can
 	be given to add all matching files.  Also a
 	leading directory name (e.g. `dir` to add `dir/file1`
diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt
index 4da07c1..f2080eb 100644
--- a/Documentation/git-archive.txt
+++ b/Documentation/git-archive.txt
@@ -72,16 +72,13 @@
 
 CONFIGURATION
 -------------
-By default, file and directories modes are set to 0666 or 0777 in tar
-archives.  It is possible to change this by setting the "umask" variable
-in the repository configuration as follows :
 
-[tar]
-        umask = 002	;# group friendly
-
-The special umask value "user" indicates that the user's current umask
-will be used instead. The default value remains 0, which means world
-readable/writable files and directories.
+tar.umask::
+	This variable can be used to restrict the permission bits of
+	tar archive entries.  The default is 0002, which turns off the
+	world write bit.  The special value "user" indicates that the
+	archiving user's umask will be used instead.  See umask(2) for
+	details.
 
 EXAMPLES
 --------
diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt
index 818b720..734928b 100644
--- a/Documentation/git-checkout.txt
+++ b/Documentation/git-checkout.txt
@@ -35,7 +35,7 @@
 OPTIONS
 -------
 -q::
-	Quiet, supress feedback messages.
+	Quiet, suppress feedback messages.
 
 -f::
 	Proceed even if the index or the working tree differs
diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt
index 5870c2c..a2537e1 100644
--- a/Documentation/git-commit-tree.txt
+++ b/Documentation/git-commit-tree.txt
@@ -51,9 +51,9 @@
 - author name, email and date
 - committer name and email and the commit time.
 
-If not provided, "git-commit-tree" uses your name, hostname and domain to
-provide author and committer info. This can be overridden by
-either `.git/config` file, or using the following environment variables.
+While parent object ids are provided on the command line, author and
+committer information is taken from the following environment variables,
+if set:
 
 	GIT_AUTHOR_NAME
 	GIT_AUTHOR_EMAIL
@@ -65,12 +65,9 @@
 
 (nb "<", ">" and "\n"s are stripped)
 
-In `.git/config` file, the following items are used for GIT_AUTHOR_NAME and
-GIT_AUTHOR_EMAIL:
-
-	[user]
-		name = "Your Name"
-		email = "your@email.address.xz"
+In case (some of) these environment variables are not set, the information
+is taken from the configuration items user.name and user.email, or, if not
+present, system user name and fully qualified hostname.
 
 A commit comment is read from stdin. If a changelog
 entry is not provided via "<" redirection, "git-commit-tree" will just wait
diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index c3dffff..5b794f4 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -139,7 +139,7 @@
 FILES
 -----
 
-If not set explicitely with '--file', there are three files where
+If not set explicitly with '--file', there are three files where
 git-config will search for configuration options:
 
 .git/config::
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index 6c423e3..4c8d1e6 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -59,7 +59,7 @@
 	Useful for patch series and the like.
 
 -u::
-	Update affected files from cvs repository before attempting export.
+	Update affected files from CVS repository before attempting export.
 
 -v::
 	Verbose.
diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt
index 60d0bcf..258a62f 100644
--- a/Documentation/git-cvsserver.txt
+++ b/Documentation/git-cvsserver.txt
@@ -102,7 +102,7 @@
 in the PATH. If you have clients that do not accept the CVS_SERVER
 environment variable, you can rename git-cvsserver to cvs.
 
-Note: Newer cvs versions (>= 1.12.11) also support specifying
+Note: Newer CVS versions (>= 1.12.11) also support specifying
 CVS_SERVER directly in CVSROOT like
 
 ------
diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index f902161..99e47c9 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -124,7 +124,8 @@
 	Detach from the shell. Implies --syslog.
 
 --pid-file=file::
-	Save the process id in 'file'.
+	Save the process id in 'file'.  Ignored when the daemon
+	is run under `--inetd`.
 
 --user=user, --group=group::
 	Change daemon's uid and gid before entering the service loop.
@@ -157,6 +158,13 @@
 SERVICES
 --------
 
+These services can be globally enabled/disabled using the
+command line options of this command.  If a finer-grained
+control is desired (e.g. to allow `git-archive` to be run
+against only in a few selected repositories the daemon serves),
+the per-repository configuration file can be used to enable or
+disable them.
+
 upload-pack::
 	This serves `git-fetch-pack` and `git-peek-remote`
 	clients.  It is enabled by default, but a repository can
@@ -164,7 +172,19 @@
 	item to `false`.
 
 upload-archive::
-	This serves `git-archive --remote`.
+	This serves `git-archive --remote`.  It is disabled by
+	default, but a repository can enable it by setting
+	`daemon.uploadarchive` configuration item to `true`.
+
+receive-pack::
+	This serves `git-send-pack` clients, allowing anonymous
+	push.  It is disabled by default, as there is _no_
+	authentication in the protocol (in other words, anybody
+	can push anything into the repository, including removal
+	of refs).  This is solely meant for a closed LAN setting
+	where everybody is friendly.  This service can be
+	enabled by `daemon.receivepack` configuration item to
+	`true`.
 
 EXAMPLES
 --------
@@ -228,6 +248,18 @@
 Repositories can still be accessed by hostname though, assuming
 they correspond to these IP addresses.
 
+selectively enable/disable services per repository::
+	To enable `git-archive --remote` and disable `git-fetch` against
+	a repository, have the following in the configuration file in the
+	repository (that is the file 'config' next to 'HEAD', 'refs' and
+	'objects').
++
+----------------------------------------------------------------
+	[daemon]
+		uploadpack = false
+		uploadarchive = true
+----------------------------------------------------------------
+
 
 Author
 ------
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index b36e705..db2eb46 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -22,10 +22,10 @@
 	words, the differences are what you _could_ tell git to
 	further add to the index but you still haven't.  You can
 	stage these changes by using gitlink:git-add[1].
-
-	If exactly two paths are given, and at least one is untracked,
-	compare the two files / directories. This behavior can be
-	forced by --no-index.
++
+If exactly two paths are given, and at least one is untracked,
+compare the two files / directories. This behavior can be
+forced by --no-index.
 
 'git-diff' [--options] --cached [<commit>] [--] [<path>...]::
 
@@ -44,16 +44,34 @@
 
 'git-diff' [--options] <commit> <commit> [--] [<path>...]::
 
-	This form is to view the changes between two <commit>,
-	for example, tips of two branches.
+	This is to view the changes between two arbitrary
+	<commit>.
+
+'git-diff' [--options] <commit>..<commit> [--] [<path>...]::
+
+	This is synonymous to the previous form.  If <commit> on
+	one side is omitted, it will have the same effect as
+	using HEAD instead.
+
+'git-diff' [--options] <commit>\...<commit> [--] [<path>...]::
+
+	This form is to view the changes on the branch containing
+	and up to the second <commit>, starting at a common ancestor
+	of both <commit>.  "git-diff A\...B" is equivalent to
+	"git-diff $(git-merge-base A B) B".  You can omit any one
+	of <commit>, which has the same effect as using HEAD instead.
 
 Just in case if you are doing something exotic, it should be
-noted that all of the <commit> in the above description can be
-any <tree-ish>.
+noted that all of the <commit> in the above description, except
+for the last two forms that use ".." notations, can be any
+<tree-ish>.
 
 For a more complete list of ways to spell <commit>, see
 "SPECIFYING REVISIONS" section in gitlink:git-rev-parse[1].
-
+However, "diff" is about comparing two _endpoints_, not ranges,
+and the range notations ("<commit>..<commit>" and
+"<commit>\...<commit>") do not mean a range as defined in the
+"SPECIFYING RANGES" section in gitlink:git-rev-parse[1].
 
 OPTIONS
 -------
@@ -97,6 +115,18 @@
 file "test".
 <3> Compare the version before the last commit and the last commit.
 
+Comparing branches::
++
+------------
+$ git diff topic master    <1>
+$ git diff topic..master   <2>
+$ git diff topic...master  <3>
+------------
++
+<1> Changes between the tips of the topic and the master branches.
+<2> Same as above.
+<3> Changes that occured on the master branch since when the topic
+branch was started off it.
 
 Limiting the diff output::
 +
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 30ee98d..d511967 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -176,6 +176,15 @@
 spaces in their name, or early termination of fast-import when it encounters
 unexpected input.
 
+Stream Comments
+~~~~~~~~~~~~~~~
+To aid in debugging frontends fast-import ignores any line that
+begins with `#` (ASCII pound/hash) up to and including the line
+ending `LF`.  A comment line may contain any sequence of bytes
+that does not contain an LF and therefore may be used to include
+any detailed debugging information that might be specific to the
+frontend and useful when inspecting a fast-import data stream.
+
 Date Formats
 ~~~~~~~~~~~~
 The following date formats are supported.  A frontend should select
@@ -232,7 +241,7 @@
 +
 Frontends should prefer the `raw` format if the source material
 already uses UNIX-epoch format, can be coaxed to give dates in that
-format, or its format is easiliy convertible to it, as there is no
+format, or its format is easily convertible to it, as there is no
 ambiguity in parsing.
 
 `now`::
@@ -289,6 +298,11 @@
 	This command is optional and is not needed to perform
 	an import.
 
+`progress`::
+	Causes fast-import to echo the entire line to its own
+	standard output.  This command is optional and is not needed
+	to perform an import.
+
 `commit`
 ~~~~~~~~
 Create or update a branch with a new commit, recording one logical
@@ -303,7 +317,7 @@
 	('from' SP <committish> LF)?
 	('merge' SP <committish> LF)?
 	(filemodify | filedelete | filecopy | filerename | filedeleteall)*
-	LF
+	LF?
 ....
 
 where `<ref>` is the name of the branch to make the commit on.
@@ -329,11 +343,13 @@
 and `filedeleteall` commands
 may be included to update the contents of the branch prior to
 creating the commit.  These commands may be supplied in any order.
-However it is recommended that a `filedeleteall` command preceed
+However it is recommended that a `filedeleteall` command precede
 all `filemodify`, `filecopy` and `filerename` commands in the same
 commit, as `filedeleteall`
 wipes the branch clean (see below).
 
+The `LF` after the command is optional (it used to be required).
+
 `author`
 ^^^^^^^^
 An `author` command may optionally appear, if the author information
@@ -386,7 +402,7 @@
 +
 The reason fast-import uses `:` to denote a mark reference is this character
 is not legal in a Git branch name.  The leading `:` makes it easy
-to distingush between the mark 42 (`:42`) and the branch 42 (`42`
+to distinguish between the mark 42 (`:42`) and the branch 42 (`42`
 or `refs/heads/42`), or an abbreviated SHA-1 which happened to
 consist only of base-10 digits.
 +
@@ -471,7 +487,7 @@
 If an `LF` or double quote must be encoded into `<path>` shell-style
 quoting should be used, e.g. `"path/with\n and \" in it"`.
 
-The value of `<path>` must be in canoncial form. That is it must not:
+The value of `<path>` must be in canonical form. That is it must not:
 
 * contain an empty directory component (e.g. `foo//bar` is invalid),
 * end with a directory separator (e.g. `foo/` is invalid),
@@ -645,12 +661,14 @@
 ....
 	'reset' SP <ref> LF
 	('from' SP <committish> LF)?
-	LF
+	LF?
 ....
 
 For a detailed description of `<ref>` and `<committish>` see above
 under `commit` and `from`.
 
+The `LF` after the command is optional (it used to be required).
+
 The `reset` command can also be used to create lightweight
 (non-annotated) tags.  For example:
 
@@ -689,29 +707,40 @@
 exact byte count format, as it is more robust and performs better.
 The delimited format is intended primarily for testing fast-import.
 
+Comment lines appearing within the `<raw>` part of `data` commands
+are always taken to be part of the body of the data and are therefore
+never ignored by fast-import.  This makes it safe to import any
+file/message content whose lines might start with `#`.
+
 Exact byte count format::
 	The frontend must specify the number of bytes of data.
 +
 ....
 	'data' SP <count> LF
-	<raw> LF
+	<raw> LF?
 ....
 +
 where `<count>` is the exact number of bytes appearing within
 `<raw>`.  The value of `<count>` is expressed as an ASCII decimal
 integer.  The `LF` on either side of `<raw>` is not
 included in `<count>` and will not be included in the imported data.
++
+The `LF` after `<raw>` is optional (it used to be required) but
+recommended.  Always including it makes debugging a fast-import
+stream easier as the next command always starts in column 0
+of the next line, even if `<raw>` did not end with an `LF`.
 
 Delimited format::
 	A delimiter string is used to mark the end of the data.
 	fast-import will compute the length by searching for the delimiter.
-	This format is primarly useful for testing and is not
+	This format is primarily useful for testing and is not
 	recommended for real data.
 +
 ....
 	'data' SP '<<' <delim> LF
 	<raw> LF
 	<delim> LF
+	LF?
 ....
 +
 where `<delim>` is the chosen delimiter string.  The string `<delim>`
@@ -720,6 +749,8 @@
 immediately trailing `<raw>` is part of `<raw>`.  This is one of
 the limitations of the delimited format, it is impossible to supply
 a data chunk which does not have an LF as its last byte.
++
+The `LF` after `<delim> LF` is optional (it used to be required).
 
 `checkpoint`
 ~~~~~~~~~~~~
@@ -728,7 +759,7 @@
 
 ....
 	'checkpoint' LF
-	LF
+	LF?
 ....
 
 Note that fast-import automatically switches packfiles when the current
@@ -747,6 +778,32 @@
 repository can be loaded into Git through fast-import in about 3 hours,
 explicit checkpointing may not be necessary.
 
+The `LF` after the command is optional (it used to be required).
+
+`progress`
+~~~~~~~~~~
+Causes fast-import to print the entire `progress` line unmodified to
+its standard output channel (file descriptor 1) when the command is
+processed from the input stream.  The command otherwise has no impact
+on the current import, or on any of fast-import's internal state.
+
+....
+	'progress' SP <any> LF
+	LF?
+....
+
+The `<any>` part of the command may contain any sequence of bytes
+that does not contain `LF`.  The `LF` after the command is optional.
+Callers may wish to process the output through a tool such as sed to
+remove the leading part of the line, for example:
+
+====
+	frontend | git-fast-import | sed 's/^progress //'
+====
+
+Placing a `progress` command immediately after a `checkpoint` will
+inform the reader when the `checkpoint` has been completed and it
+can safely access the refs that fast-import updated.
 
 Tips and Tricks
 ---------------
@@ -816,7 +873,7 @@
 Import Now, Repack Later
 ~~~~~~~~~~~~~~~~~~~~~~~~
 As soon as fast-import completes the Git repository is completely valid
-and ready for use.  Typicallly this takes only a very short time,
+and ready for use.  Typically this takes only a very short time,
 even for considerably large projects (100,000+ commits).
 
 However repacking the repository is necessary to improve data
@@ -840,6 +897,15 @@
 You only need to expend the effort once, and everyone using your
 project will benefit from the smaller repository.
 
+Include Some Progress Messages
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Every once in a while have your frontend emit a `progress` message
+to fast-import.  The contents of the messages are entirely free-form,
+so one suggestion would be to output the current month and year
+each time the current commit date moves into the next month.
+Your users will feel better knowing how much of the data stream
+has been processed.
+
 
 Packfile Optimization
 ---------------------
@@ -876,8 +942,8 @@
 ------------------
 There are a number of factors which affect how much memory fast-import
 requires to perform an import.  Like critical sections of core
-Git, fast-import uses its own memory allocators to ammortize any overheads
-associated with malloc.  In practice fast-import tends to ammoritize any
+Git, fast-import uses its own memory allocators to amortize any overheads
+associated with malloc.  In practice fast-import tends to amortize any
 malloc overheads to 0, due to its use of large block allocations.
 
 per object
@@ -934,7 +1000,7 @@
 ~~~~~~~~~~~~~~~
 Trees (aka directories) use just 12 bytes of memory on top of the
 memory required for their entries (see ``per active file'' below).
-The cost of a tree is virtually 0, as its overhead ammortizes out
+The cost of a tree is virtually 0, as its overhead amortizes out
 over the individual file entries.
 
 per active file entry
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index 915258f..29bb8ce 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -12,23 +12,24 @@
 	[--index-filter <command>] [--parent-filter <command>]
 	[--msg-filter <command>] [--commit-filter <command>]
 	[--tag-name-filter <command>] [--subdirectory-filter <directory>]
-	[-d <directory>] [-f | --force] [<rev-list options>...]
+	[--original <namespace>] [-d <directory>] [-f | --force]
+	[<rev-list options>...]
 
 DESCRIPTION
 -----------
-Lets you rewrite git revision history by creating a new branch from
-your current branch, applying custom filters on each revision.
+Lets you rewrite git revision history by rewriting the branches mentioned
+in the <rev-list options>, applying custom filters on each revision.
 Those filters can modify each tree (e.g. removing a file or running
 a perl rewrite on all files) or information about each commit.
 Otherwise, all information (including original commit times or merge
 information) will be preserved.
 
-The command takes the new branch name as a mandatory argument and
-the filters as optional arguments.  If you specify no filters, the
-commits will be recommitted without any changes, which would normally
-have no effect.  Nevertheless, this may be useful in the future for
-compensating for some git bugs or such, therefore such a usage is
-permitted.
+The command will only rewrite the _positive_ refs mentioned in the
+command line (i.e. if you pass 'a..b', only 'b' will be rewritten).
+If you specify no filters, the commits will be recommitted without any
+changes, which would normally have no effect.  Nevertheless, this may be
+useful in the future for compensating for some git bugs or such,
+therefore such a usage is permitted.
 
 *WARNING*! The rewritten history will have different object names for all
 the objects and will not converge with the original branch.  You will not
@@ -42,8 +43,8 @@
 'refs/original/'.
 
 Note that since this operation is extensively I/O expensive, it might
-be a good idea to redirect the temporary directory off-disk, e.g. on
-tmpfs.  Reportedly the speedup is very noticeable.
+be a good idea to redirect the temporary directory off-disk with the
+'-d' option, e.g. on tmpfs.  Reportedly the speedup is very noticeable.
 
 
 Filters
@@ -111,6 +112,11 @@
 As a special extension, the commit filter may emit multiple
 commit ids; in that case, ancestors of the original commit will
 have all of them as parents.
++
+You can use the 'map' convenience function in this filter, and other
+convenience functions, too.  For example, calling 'skip_commit "$@"'
+will leave out the current commit (but not its changes! If you want
+that, use gitlink:git-rebase[1] instead).
 
 --tag-name-filter <command>::
 	This is the filter for rewriting tag names. When passed,
@@ -120,7 +126,7 @@
 	tag name is expected on standard output.
 +
 The original tags are not deleted, but can be overwritten;
-use "--tag-name-filter=cat" to simply update the tags.  In this
+use "--tag-name-filter cat" to simply update the tags.  In this
 case, be very careful and make sure you have the old tags
 backed up in case the conversion has run afoul.
 +
@@ -134,6 +140,10 @@
 	The result will contain that directory (and only that) as its
 	project root.
 
+--original <namespace>::
+	Use this option to set the namespace where the original commits
+	will be stored. The default value is 'refs/original'.
+
 -d <directory>::
 	Use this option to set the path to the temporary directory used for
 	rewriting.  When applying a tree filter, the command needs to
@@ -181,8 +191,8 @@
 git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' HEAD
 -------------------------------------------------------------------
 
-(if the parent string is empty - therefore we are dealing with the
-initial commit - add graftcommit as a parent).  Note that this assumes
+(if the parent string is empty - which happens when we are dealing with
+the initial commit - add graftcommit as a parent).  Note that this assumes
 history with a single root (that is, no merge without common ancestors
 happened).  If this is not the case, use:
 
@@ -204,34 +214,50 @@
 git filter-branch --commit-filter '
 	if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ];
 	then
-		shift;
-		while [ -n "$1" ];
-		do
-			shift;
-			echo "$1";
-			shift;
-		done;
+		skip_commit "$@";
 	else
 		git commit-tree "$@";
 	fi' HEAD
 ------------------------------------------------------------------------------
 
+Note that the changes introduced by the commits, and not reverted by
+subsequent commits, will still be in the rewritten branch. If you want
+to throw out _changes_ together with the commits, you should use the
+interactive mode of gitlink:git-rebase[1].
+
+The function 'skip_commits' is defined as follows:
+
+--------------------------
+skip_commit()
+{
+	shift;
+	while [ -n "$1" ];
+	do
+		shift;
+		map "$1";
+		shift;
+	done;
+}
+--------------------------
+
 The shift magic first throws away the tree id and then the -p
 parameters.  Note that this handles merges properly! In case Darl
 committed a merge between P1 and P2, it will be propagated properly
 and all children of the merge will become merge commits with P1,P2
 as their parents instead of the merge commit.
 
+
 To restrict rewriting to only part of the history, specify a revision
 range in addition to the new branch name.  The new branch name will
 point to the top-most revision that a 'git rev-list' of this range
 will print.
 
-Note that the changes introduced by the commits, and not reverted by
-subsequent commits, will still be in the rewritten branch. If you want
+*NOTE* the changes introduced by the commits, and which are not reverted
+by subsequent commits, will still be in the rewritten branch. If you want
 to throw out _changes_ together with the commits, you should use the
 interactive mode of gitlink:git-rebase[1].
 
+
 Consider this history:
 
 ------------------
diff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt
index 6affc5b..7088ed4 100644
--- a/Documentation/git-fmt-merge-msg.txt
+++ b/Documentation/git-fmt-merge-msg.txt
@@ -10,7 +10,7 @@
 --------
 [verse]
 git-fmt-merge-msg [--summary | --no-summary] <$GIT_DIR/FETCH_HEAD
-git-fmt-merge-msg [--summary | --no-summray] -F <file>
+git-fmt-merge-msg [--summary | --no-summary] -F <file>
 
 DESCRIPTION
 -----------
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index 6cbcf93..c9857a2 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -16,21 +16,35 @@
                    [--in-reply-to=Message-Id] [--suffix=.<sfx>]
                    [--ignore-if-in-upstream]
                    [--subject-prefix=Subject-Prefix]
-                   <since>[..<until>]
+		   [ <since> | <revision range> ]
 
 DESCRIPTION
 -----------
 
-Prepare each commit between <since> and <until> with its patch in
+Prepare each commit with its patch in
 one file per commit, formatted to resemble UNIX mailbox format.
-If ..<until> is not specified, the head of the current working
-tree is implied.  For a more complete list of ways to spell
-<since> and <until>, see "SPECIFYING REVISIONS" section in
-gitlink:git-rev-parse[1].
-
 The output of this command is convenient for e-mail submission or
 for use with gitlink:git-am[1].
 
+There are two ways to specify which commits to operate on.
+
+1. A single commit, <since>, specifies that the commits leading
+   to the tip of the current branch that are not in the history
+   that leads to the <since> to be output.
+
+2. Generic <revision range> expression (see "SPECIFYING
+   REVISIONS" section in gitlink:git-rev-parse[1]) means the
+   commits in the specified range.
+
+A single commit, when interpreted as a <revision range>
+expression, means "everything that leads to that commit", but
+if you write 'git format-patch <commit>', the previous rule
+applies to that command line and you do not get "everything
+since the beginning of the time".  If you want to format
+everything since project inception to one commit, say "git
+format-patch \--root <commit>" to make it clear that it is the
+latter case.
+
 By default, each output file is numbered sequentially from 1, and uses the
 first line of the commit message (massaged for pathname safety) as
 the filename. With the --numbered-files option, the output file names
@@ -118,7 +132,7 @@
 
 --suffix=.<sfx>::
 	Instead of using `.patch` as the suffix for generated
-	filenames, use specifed suffix.  A common alternative is
+	filenames, use specified suffix.  A common alternative is
 	`--suffix=.txt`.
 +
 Note that you would need to include the leading dot `.` if you
@@ -153,6 +167,10 @@
 	not in the origin branch.  For each commit a separate file
 	is created in the current directory.
 
+git-format-patch \--root origin::
+	Extract all commits which that leads to 'origin' since the
+	inception of the project.
+
 git-format-patch -M -B origin::
 	The same as the previous one.  Additionally, it detects
 	and handles renames and complete rewrites intelligently to
diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt
index bd613b2..13252a1 100644
--- a/Documentation/git-gui.txt
+++ b/Documentation/git-gui.txt
@@ -89,7 +89,7 @@
 Other
 -----
 git-gui is actually maintained as an independent project, but stable
-versions are distributed as part of the Git suite for the convience
+versions are distributed as part of the Git suite for the convenience
 of end users.
 
 A git-gui development repository can be obtained from:
diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt
index 45e4845..389c6ed 100644
--- a/Documentation/git-http-fetch.txt
+++ b/Documentation/git-http-fetch.txt
@@ -34,7 +34,7 @@
         the local end after the transfer is complete.
 
 --stdin::
-	Instead of a commit id on the commandline (which is not expected in this
+	Instead of a commit id on the command line (which is not expected in this
 	case), 'git-http-fetch' expects lines on stdin in the format
 
 		<commit-id>['\t'<filename-as-in--w>]
diff --git a/Documentation/git-local-fetch.txt b/Documentation/git-local-fetch.txt
index 141b767..e830dee 100644
--- a/Documentation/git-local-fetch.txt
+++ b/Documentation/git-local-fetch.txt
@@ -44,7 +44,7 @@
         the local end after the transfer is complete.
 
 --stdin::
-	Instead of a commit id on the commandline (which is not expected in this
+	Instead of a commit id on the command line (which is not expected in this
 	case), 'git-local-fetch' expects lines on stdin in the format
 
 		<commit-id>['\t'<filename-as-in--w>]
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index 5a90f65..5ec547c 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -49,6 +49,7 @@
 -g, \--walk-reflogs::
 	Show commits as they were recorded in the reflog. The log contains
 	a record about how the tip of a reference was changed.
+	Cannot be combined with --reverse.
 	See also gitlink:git-reflog[1].
 
 --decorate::
@@ -95,7 +96,7 @@
 	The "--" is necessary to avoid confusion with the *branch* named
 	'gitk'
 
-git log -r --name-status release..test::
+git log --name-status release..test::
 
 	Show the commits that are in the "test" branch but not yet
 	in the "release" branch, along with the list of paths
diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.txt
index 91eede1..306e1a4 100644
--- a/Documentation/git-name-rev.txt
+++ b/Documentation/git-name-rev.txt
@@ -37,7 +37,7 @@
 --name-only::
 	Instead of printing both the SHA-1 and the name, print only
 	the name.  If given with --tags the usual tag prefix of
-	"tags/" is also ommitted from the name, matching the output
+	"tags/" is also omitted from the name, matching the output
 	of gitlink::git-describe[1] more closely.  This option
 	cannot be combined with --stdin.
 
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index a1b6dce..61b1810 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -8,7 +8,7 @@
 SYNOPSIS
 --------
 [verse]
-'git-rebase' [-i | --interactive] [-v | --verbose] [--merge] [-C<n>]
+'git-rebase' [-i | --interactive] [-v | --verbose] [-m | --merge] [-C<n>]
 	[-p | --preserve-merges] [--onto <newbase>] <upstream> [<branch>]
 'git-rebase' --continue | --skip | --abort
 
@@ -188,7 +188,7 @@
 --skip::
 	Restart the rebasing process by skipping the current patch.
 
---merge::
+-m, \--merge::
 	Use merging strategies to rebase.  When the recursive (default) merge
 	strategy is used, this allows rebase to be aware of renames on the
 	upstream side.
@@ -211,7 +211,8 @@
 
 -i, \--interactive::
 	Make a list of the commits which are about to be rebased.  Let the
-	user edit that list before rebasing.
+	user edit that list before rebasing.  This mode can also be used to
+	split commits (see SPLITTING COMMITS below).
 
 -p, \--preserve-merges::
 	Instead of ignoring merges, try to recreate them.  This option
@@ -325,6 +326,42 @@
 $ git rebase -i -p --onto Q O
 -----------------------------
 
+
+SPLITTING COMMITS
+-----------------
+
+In interactive mode, you can mark commits with the action "edit".  However,
+this does not necessarily mean that 'git rebase' expects the result of this
+edit to be exactly one commit.  Indeed, you can undo the commit, or you can
+add other commits.  This can be used to split a commit into two:
+
+- Start an interactive rebase with 'git rebase -i <commit>^', where
+  <commit> is the commit you want to split.  In fact, any commit range
+  will do, as long as it contains that commit.
+
+- Mark the commit you want to split with the action "edit".
+
+- When it comes to editing that commit, execute 'git reset HEAD^'.  The
+  effect is that the HEAD is rewound by one, and the index follows suit.
+  However, the working tree stays the same.
+
+- Now add the changes to the index that you want to have in the first
+  commit.  You can use gitlink:git-add[1] (possibly interactively) and/or
+  gitlink:git-gui[1] to do that.
+
+- Commit the now-current index with whatever commit message is appropriate
+  now.
+
+- Repeat the last two steps until your working tree is clean.
+
+- Continue the rebase with 'git rebase --continue'.
+
+If you are not absolutely sure that the intermediate revisions are
+consistent (they compile, pass the testsuite, etc.) you should use
+gitlink:git-stash[1] to stash away the not-yet-committed changes
+after each commit, test, and amend the commit if fixes are necessary.
+
+
 Authors
 ------
 Written by Junio C Hamano <junkio@cox.net> and
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 4ef1840..2633d94 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -78,7 +78,7 @@
 updating the named ref.  Otherwise it should exit with zero.
 
 Successful execution (a zero exit status) of this hook does not
-ensure the ref will actully be updated, it is only a prerequisite.
+ensure the ref will actually be updated, it is only a prerequisite.
 As such it is not a good idea to send notices (e.g. email) from
 this hook.  Consider using the post-receive hook instead.
 
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index 89bc9c5..5180f68 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -30,9 +30,10 @@
 tip, are removed from the reflog.  This is typically not used
 directly by the end users -- instead, see gitlink:git-gc[1].
 
-The subcommand "show" (which is also the default, in the absense of any
+The subcommand "show" (which is also the default, in the absence of any
 subcommands) will take all the normal log options, and show the log of
-the current branch. It is basically an alias for 'git log -g --abbrev-commit
+`HEAD`, which will cover all recent actions, including branch switches.
+It is basically an alias for 'git log -g --abbrev-commit
 --pretty=oneline', see gitlink:git-log[1].
 
 
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 5283ef8..12e2079 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -14,7 +14,7 @@
 -----------
 
 This script is used to combine all objects that do not currently
-reside in a "pack", into a pack.  It can also be used to re-organise
+reside in a "pack", into a pack.  It can also be used to re-organize
 existing packs into a single, more efficient pack.
 
 A pack is a collection of objects, individually compressed, with
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 1c19781..7cd0e89 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -113,7 +113,7 @@
 `--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
 format, often found in E-mail messages.
 +
-`--date=short` shows only date but not time, in `YYYY-MM-DD` fomat.
+`--date=short` shows only date but not time, in `YYYY-MM-DD` format.
 +
 `--date=default` shows timestamps in the original timezone
 (either committer's or author's).
@@ -299,6 +299,8 @@
 instead.  Under '\--pretty=oneline', the commit message is
 prefixed with this information on the same line.
 
+Cannot be combined with '\--reverse'.
+
 --merge::
 
 	After a failed merge, show refs that touch files having a
@@ -373,6 +375,7 @@
 --reverse::
 
 	Output the commits in reverse order.
+	Cannot be combined with '\--walk-reflogs'.
 
 Object Traversal
 ~~~~~~~~~~~~~~~~
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 4b4d229..4758c33 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -215,7 +215,10 @@
 * A colon, optionally followed by a stage number (0 to 3) and a
   colon, followed by a path; this names a blob object in the
   index at the given path.  Missing stage number (and the colon
-  that follows it) names an stage 0 entry.
+  that follows it) names an stage 0 entry. During a merge, stage
+  1 is the common ancestor, stage 2 is the target branch's version
+  (typically the current branch), and stage 3 is the version from
+  the branch being merged.
 
 Here is an illustration, by Jon Loeliger.  Both node B and C are
 a commit parents of commit node A.  Parent commits are ordered
diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt
index a63a3ad..16bfd7b 100644
--- a/Documentation/git-send-email.txt
+++ b/Documentation/git-send-email.txt
@@ -68,7 +68,7 @@
 --signed-off-by-cc, --no-signed-off-by-cc::
         If this is set, add emails found in Signed-off-by: or Cc: lines to the
         cc list.
-        Default is the value of 'sendemail.signedoffbycc' configuration value;
+        Default is the value of 'sendemail.signedoffcc' configuration value;
         if that is unspecified, default to --signed-off-by-cc.
 
 --quiet::
@@ -94,7 +94,7 @@
         If this is set, do not add the From: address to the cc: list, if it
         shows up in a From: line.
         Default is the value of 'sendemail.suppressfrom' configuration value;
-        if that is unspecified, default to --no-supress-from.
+        if that is unspecified, default to --no-suppress-from.
 
 --thread, --no-thread::
 	If this is set, the In-Reply-To header will be set on each email sent.
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 816340b..be2e34e 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -44,10 +44,15 @@
 --tags=<tags_subdir>;;
 -b<branches_subdir>;;
 --branches=<branches_subdir>;;
+-s;;
+--stdlayout;;
 	These are optional command-line options for init.  Each of
 	these flags can point to a relative repository path
 	(--tags=project/tags') or a full url
-	(--tags=https://foo.org/project/tags)
+	(--tags=https://foo.org/project/tags). The option --stdlayout is
+	a shorthand way of setting trunk,tags,branches as the relative paths,
+	which is the Subversion default. If any of the other options are given
+	as well, they take precedence.
 --no-metadata;;
 	Set the 'noMetadata' option in the [svn-remote] config.
 --use-svm-props;;
@@ -94,7 +99,7 @@
 
 This works similarly to 'svn update' or 'git-pull' except that
 it preserves linear history with 'git-rebase' instead of
-'git-merge' for ease of dcommit-ing with git-svn.
+'git-merge' for ease of dcommiting with git-svn.
 
 This accepts all options that 'git-svn fetch' and 'git-rebase'
 accepts.  However '--fetch-all' only fetches from the current
@@ -479,6 +484,38 @@
 history of the directory that it is tracking, however (much like
 how 'svn log' works).
 
+CAVEATS
+-------
+
+For the sake of simplicity and interoperating with a less-capable system
+(SVN), it is recommended that all git-svn users clone, fetch and dcommit
+directly from the SVN server, and avoid all git-clone/pull/merge/push
+operations between git repositories and branches.  The recommended
+method of exchanging code between git branches and users is
+git-format-patch and git-am, or just dcommiting to the SVN repository.
+
+Running 'git-merge' or 'git-pull' is NOT recommended on a branch you
+plan to dcommit from.  Subversion does not represent merges in any
+reasonable or useful fashion; so users using Subversion cannot see any
+merges you've made.  Furthermore, if you merge or pull from a git branch
+that is a mirror of an SVN branch, dcommit may commit to the wrong
+branch.
+
+'git-clone' does not clone branches under the refs/remotes/ hierarchy or
+any git-svn metadata, or config.  So repositories created and managed with
+using git-svn should use rsync(1) for cloning, if cloning is to be done
+at all.
+
+Since 'dcommit' uses rebase internally, any git branches you git-push to
+before dcommit on will require forcing an overwrite of the existing ref
+on the remote repository.  This is generally considered bad practice,
+see the git-push(1) documentation for details.
+
+Do not use the --amend option of git-commit(1) on a change you've
+already dcommitted.  It is considered bad practice to --amend commits
+you've already pushed to a remote repository for other users, and
+dcommit with SVN is analogous to that.
+
 BUGS
 ----
 
@@ -512,9 +549,9 @@
 ------------------------------------------------------------------------
 
 Keep in mind that the '*' (asterisk) wildcard of the local ref
-(left of the ':') *must* be the farthest right path component;
+(right of the ':') *must* be the farthest right path component;
 however the remote wildcard may be anywhere as long as it's own
-independent path componet (surrounded by '/' or EOL).   This
+independent path component (surrounded by '/' or EOL).   This
 type of configuration is not automatically created by 'init' and
 should be manually entered with a text-editor or using
 gitlink:git-config[1]
diff --git a/Documentation/git-svnimport.txt b/Documentation/git-svnimport.txt
index e97d15e..71aad8b 100644
--- a/Documentation/git-svnimport.txt
+++ b/Documentation/git-svnimport.txt
@@ -68,6 +68,9 @@
 	Prepend 'rX: ' to commit messages, where X is the imported
 	subversion revision.
 
+-u::
+	Replace underscores in tag names with periods.
+
 -I <ignorefile_name>::
 	Import the svn:ignore directory property to files with this
 	name in each directory. (The Subversion and GIT ignore
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 119117f..990ae4f 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -34,13 +34,6 @@
 committer identity for the current user is used to find the
 GnuPG key for signing.
 
-`-d <tag>` deletes the tag.
-
-`-v <tag>` verifies the gpg signature of the tag.
-
-`-l <pattern>` lists tags with names that match the given pattern
-(or all if no pattern is given).
-
 OPTIONS
 -------
 -a::
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
index 2d01d96..434607b 100644
--- a/Documentation/git-tar-tree.txt
+++ b/Documentation/git-tar-tree.txt
@@ -42,16 +42,13 @@
 
 CONFIGURATION
 -------------
-By default, file and directories modes are set to 0666 or 0777. It is
-possible to change this by setting the "umask" variable in the
-repository configuration as follows :
 
-[tar]
-        umask = 002	;# group friendly
-
-The special umask value "user" indicates that the user's current umask
-will be used instead.  The default value is 002, which means group
-readable/writable files and directories.
+tar.umask::
+	This variable can be used to restrict the permission bits of
+	tar archive entries.  The default is 0002, which turns off the
+	world write bit.  The special value "user" indicates that the
+	archiving user's umask will be used instead.  See umask(2) for
+	details.
 
 EXAMPLES
 --------
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 8017997..ceca892 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -9,7 +9,8 @@
 SYNOPSIS
 --------
 [verse]
-'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
+'git' [--version] [--exec-path[=GIT_EXEC_PATH]]
+    [-p|--paginate|--no-pager]
     [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
     [--help] COMMAND [ARGS]
 
@@ -103,6 +104,9 @@
 -p|--paginate::
 	Pipe all output into 'less' (or if set, $PAGER).
 
+--no-pager::
+	Do not pipe git output into a pager.
+
 --git-dir=<path>::
 	Set the path to the repository. This can also be controlled by
 	setting the GIT_DIR environment variable.
@@ -116,7 +120,10 @@
 	variable.
 
 --bare::
-	Same as --git-dir=`pwd`.
+	Treat the repository as a bare repository.  If GIT_DIR
+	environment is not set, it is set to the current working
+	directory.
+
 
 FURTHER DOCUMENTATION
 ---------------------
@@ -469,7 +476,7 @@
 Authors
 -------
 * git's founding father is Linus Torvalds <torvalds@osdl.org>.
-* The current git nurse is Junio C Hamano <junkio@cox.net>.
+* The current git nurse is Junio C Hamano <gitster@pobox.com>.
 * The git potty was written by Andres Ericsson <ae@op5.se>.
 * General upbringing is handled by the git-list <git@vger.kernel.org>.
 
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 8b90a5b..46f9d59 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -285,7 +285,7 @@
 Note.  A single level of backslashes are eaten by the
 configuration file parser, so you would need to double the
 backslashes; the pattern above picks a line that begins with a
-backslash, and zero or more occurences of `sub` followed by
+backslash, and zero or more occurrences of `sub` followed by
 `section` followed by open brace, to the end of line.
 
 There are a few built-in patterns to make this easier, and `tex`
@@ -394,7 +394,7 @@
 the attributes given to path `t/abc` are computed as follows:
 
 1. By examining `t/.gitattributes` (which is in the same
-   diretory as the path in question), git finds that the first
+   directory as the path in question), git finds that the first
    line matches.  `merge` attribute is set.  It also finds that
    the second line matches, and attributes `foo` and `bar`
    are unset.
@@ -410,7 +410,7 @@
    a match, and `foo` is set, `bar` is reverted to unspecified
    state, and `baz` is unset.
 
-As the result, the attributes assignement to `t/abc` becomes:
+As the result, the attributes assignment to `t/abc` becomes:
 
 ----------------------------------------------------------------
 foo	set to true
diff --git a/Documentation/hooks.txt b/Documentation/hooks.txt
index 6836477..c39edc5 100644
--- a/Documentation/hooks.txt
+++ b/Documentation/hooks.txt
@@ -176,7 +176,7 @@
 This hook does not affect the outcome of `git-receive-pack`, as it
 is called after the real work is done.
 
-This supersedes the <<post-update,'post-update'>> hook in that it get's
+This supersedes the <<post-update,'post-update'>> hook in that it gets
 both old and new values of all the refs in addition to their
 names.
 
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index bd9fbee..fff1068 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -339,7 +339,7 @@
 -------------------------------------
 
 Note that git pull always merges into the current branch,
-regardless of what else is given on the commandline.
+regardless of what else is given on the command line.
 
 Later, Bob can update his repo with Alice's latest changes using
 
diff --git a/Documentation/urls.txt b/Documentation/urls.txt
index b38145f..e67f914 100644
--- a/Documentation/urls.txt
+++ b/Documentation/urls.txt
@@ -10,6 +10,7 @@
 - https://host.xz/path/to/repo.git/
 - git://host.xz/path/to/repo.git/
 - git://host.xz/~user/path/to/repo.git/
+- ssh://{startsb}user@{endsb}host.xz{startsb}:port{endsb}/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz/~user/path/to/repo.git/
 - ssh://{startsb}user@{endsb}host.xz/~/path/to/repo.git
@@ -18,7 +19,8 @@
 SSH is the default transport protocol over the network.  You can
 optionally specify which user to log-in as, and an alternate,
 scp-like syntax is also supported.  Both syntaxes support
-username expansion, as does the native git protocol. The following
+username expansion, as does the native git protocol, but
+only the former supports port specification. The following
 three are identical to the last three above, respectively:
 
 ===============================================================
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index f89952a..35298e6 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -4,7 +4,7 @@
 
 Git is a fast distributed revision control system.
 
-This manual is designed to be readable by someone with basic unix
+This manual is designed to be readable by someone with basic UNIX
 command-line skills, but no previous knowledge of git.
 
 <<repositories-and-branches>> and <<exploring-git-history>> explain how
@@ -42,10 +42,9 @@
 It will be useful to have a git repository to experiment with as you
 read this manual.
 
-The best way to get one is by using the gitlink:git-clone[1] command
-to download a copy of an existing repository for a project that you
-are interested in.  If you don't already have a project in mind, here
-are some interesting examples:
+The best way to get one is by using the gitlink:git-clone[1] command to
+download a copy of an existing repository.  If you don't already have a
+project in mind, here are some interesting examples:
 
 ------------------------------------------------
 	# git itself (approx. 10MB download):
@@ -63,21 +62,18 @@
 together with a special top-level directory named ".git", which
 contains all the information about the history of the project.
 
-In most of the following, examples will be taken from one of the two
-repositories above.
-
 [[how-to-check-out]]
 How to check out a different version of a project
 -------------------------------------------------
 
-Git is best thought of as a tool for storing the history of a
-collection of files.  It stores the history as a compressed
-collection of interrelated snapshots (versions) of the project's
-contents.
+Git is best thought of as a tool for storing the history of a collection
+of files.  It stores the history as a compressed collection of
+interrelated snapshots of the project's contents.  In git each such
+version is called a <<def_commit,commit>>.
 
 A single git repository may contain multiple branches.  It keeps track
 of them by keeping a list of <<def_head,heads>> which reference the
-latest version on each branch; the gitlink:git-branch[1] command shows
+latest commit on each branch; the gitlink:git-branch[1] command shows
 you the list of branch heads:
 
 ------------------------------------------------
@@ -149,32 +145,27 @@
 
 ------------------------------------------------
 $ git show
-commit 2b5f6dcce5bf94b9b119e9ed8d537098ec61c3d2
-Author: Jamal Hadi Salim <hadi@cyberus.ca>
-Date:   Sat Dec 2 22:22:25 2006 -0800
+commit 17cf781661e6d38f737f15f53ab552f1e95960d7
+Author: Linus Torvalds <torvalds@ppc970.osdl.org.(none)>
+Date:   Tue Apr 19 14:11:06 2005 -0700
 
-    [XFRM]: Fix aevent structuring to be more complete.
+    Remove duplicate getenv(DB_ENVIRONMENT) call
 
-    aevents can not uniquely identify an SA. We break the ABI with this
-    patch, but consensus is that since it is not yet utilized by any
-    (known) application then it is fine (better do it now than later).
+    Noted by Tony Luck.
 
-    Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
-    Signed-off-by: David S. Miller <davem@davemloft.net>
-
-diff --git a/Documentation/networking/xfrm_sync.txt b/Documentation/networking/xfrm_sync.txt
-index 8be626f..d7aac9d 100644
---- a/Documentation/networking/xfrm_sync.txt
-+++ b/Documentation/networking/xfrm_sync.txt
-@@ -47,10 +47,13 @@ aevent_id structure looks like:
-
-    struct xfrm_aevent_id {
-              struct xfrm_usersa_id           sa_id;
-+             xfrm_address_t                  saddr;
-              __u32                           flags;
-+             __u32                           reqid;
-    };
-...
+diff --git a/init-db.c b/init-db.c
+index 65898fa..b002dc6 100644
+--- a/init-db.c
++++ b/init-db.c
+@@ -7,7 +7,7 @@
+ 
+ int main(int argc, char **argv)
+ {
+-	char *sha1_dir = getenv(DB_ENVIRONMENT), *path;
++	char *sha1_dir, *path;
+ 	int len, i;
+ 
+ 	if (mkdir(".git", 0755) < 0) {
 ------------------------------------------------
 
 As you can see, a commit shows who made the latest change, what they
@@ -217,7 +208,7 @@
 
 In the following, we say that commit X is "reachable" from commit Y
 if commit X is an ancestor of commit Y.  Equivalently, you could say
-that Y is a descendent of X, or that there is a chain of parents
+that Y is a descendant of X, or that there is a chain of parents
 leading from commit Y to commit X.
 
 [[history-diagrams]]
@@ -923,14 +914,14 @@
 
 [[Finding-comments-with-given-content]]
 Finding commits referencing a file with given content
------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Somebody hands you a copy of a file, and asks which commits modified a
 file such that it contained the given content either before or after the
 commit.  You can find out with this:
 
 -------------------------------------------------
-$  git log --raw -r --abbrev=40 --pretty=oneline -- filename |
+$  git log --raw --abbrev=40 --pretty=oneline -- filename |
 	grep -B 1 `git hash-object filename`
 -------------------------------------------------
 
@@ -1105,20 +1096,14 @@
 is just a matter of 'not' calling "`git add`" on them. But it quickly becomes
 annoying to have these untracked files lying around; e.g. they make
 "`git add .`" and "`git commit -a`" practically useless, and they keep
-showing up in the output of "`git status`", etc.
+showing up in the output of "`git status`".
 
-Git therefore provides "exclude patterns" for telling git which files to
-actively ignore. Exclude patterns are thoroughly explained in the
-gitlink:gitignore[5] manual page, but the heart of the concept is simply
-a list of files which git should ignore. Entries in the list may contain
-globs to specify multiple files, or may be prefixed by "`!`" to
-explicitly include (un-ignore) a previously excluded (ignored) file
-(i.e. later exclude patterns override earlier ones).  The following
-example should illustrate such patterns:
+You can tell git to ignore certain files by creating a file called .gitignore
+in the top level of your working directory, with contents such as:
 
 -------------------------------------------------
 # Lines starting with '#' are considered comments.
-# Ignore foo.txt.
+# Ignore any file named foo.txt.
 foo.txt
 # Ignore (generated) html files,
 *.html
@@ -1128,41 +1113,20 @@
 *.[oa]
 -------------------------------------------------
 
-The next question is where to put these exclude patterns so that git can
-find them. Git looks for exclude patterns in the following files:
+See gitlink:gitignore[5] for a detailed explanation of the syntax.  You can
+also place .gitignore files in other directories in your working tree, and they
+will apply to those directories and their subdirectories.  The `.gitignore`
+files can be added to your repository like any other files (just run `git add
+.gitignore` and `git commit`, as usual), which is convenient when the exclude
+patterns (such as patterns matching build output files) would also make sense
+for other users who clone your repository.
 
-`.gitignore` files in your working tree:::
-	   You may store multiple `.gitignore` files at various locations in your
-	   working tree. Each `.gitignore` file is applied to the directory where
-	   it's located, including its subdirectories. Furthermore, the
-	   `.gitignore` files can be tracked like any other files in your working
-	   tree; just do a "`git add .gitignore`" and commit. `.gitignore` is
-	   therefore the right place to put exclude patterns that are meant to
-	   be shared between all project participants, such as build output files
-	   (e.g. `\*.o`), etc.
-`.git/info/exclude` in your repo:::
-	   Exclude patterns in this file are applied to the working tree as a
-	   whole. Since the file is not located in your working tree, it does
-	   not follow push/pull/clone like `.gitignore` can do. This is therefore
-	   the place to put exclude patterns that are local to your copy of the
-	   repo (i.e. 'not' shared between project participants), such as
-	   temporary backup files made by your editor (e.g. `\*~`), etc.
-The file specified by the `core.excludesfile` config directive:::
-	   By setting the `core.excludesfile` config directive you can tell git
-	   where to find more exclude patterns (see gitlink:git-config[1] for
-	   more information on configuration options). This config directive
-	   can be set in the per-repo `.git/config` file, in which case the
-	   exclude patterns will apply to that repo only. Alternatively, you
-	   can set the directive in the global `~/.gitconfig` file to apply
-	   the exclude pattern to all your git repos. As with the above
-	   `.git/info/exclude` (and, indeed, with git config directives in
-	   general), this directive does not follow push/pull/clone, but remain
-	   local to your repo(s).
-
-[NOTE]
-In addition to the above alternatives, there are git commands that can take
-exclude patterns directly on the command line. See gitlink:git-ls-files[1]
-for an example of this.
+If you wish the exclude patterns to affect only certain repositories
+(instead of every repository for a given project), you may instead put
+them in a file in your repository named .git/info/exclude, or in any file
+specified by the `core.excludesfile` configuration variable.  Some git
+commands can also take exclude patterns directly on the command line.
+See gitlink:gitignore[5] for the details.
 
 [[how-to-merge]]
 How to merge
@@ -1796,11 +1760,12 @@
 Public git repositories
 -----------------------
 
-Another way to submit changes to a project is to tell the maintainer of
-that project to pull the changes from your repository using git-pull[1].
-In the section "<<getting-updates-with-git-pull, Getting updates with
-git pull>>" we described this as a way to get updates from the "main"
-repository, but it works just as well in the other direction.
+Another way to submit changes to a project is to tell the maintainer
+of that project to pull the changes from your repository using
+gitlink:git-pull[1].  In the section "<<getting-updates-with-git-pull,
+Getting updates with git pull>>" we described this as a way to get
+updates from the "main" repository, but it works just as well in the
+other direction.
 
 If you and the maintainer both have accounts on the same machine, then
 you can just pull changes from each other's repositories directly;
@@ -1911,7 +1876,7 @@
 link:hooks.html[Hooks used by git].)
 
 Advertise the url of proj.git.  Anybody else should then be able to
-clone or pull from that url, for example with a commandline like:
+clone or pull from that url, for example with a command line like:
 
 -------------------------------------------------
 $ git clone http://yourserver.com/~you/proj.git
@@ -2057,7 +2022,8 @@
 Linus's tree will be stored in the remote branch named origin/master,
 and can be updated using gitlink:git-fetch[1]; you can track other
 public trees using gitlink:git-remote[1] to set up a "remote" and
-git-fetch[1] to keep them up-to-date; see <<repositories-and-branches>>.
+gitlink:git-fetch[1] to keep them up-to-date; see
+<<repositories-and-branches>>.
 
 Now create the branches in which you are going to work; these start out
 at the current tip of origin/master branch, and should be set up (using
@@ -2512,9 +2478,9 @@
 And browse through the list of patches in the mywork branch using gitk,
 applying them (possibly in a different order) to mywork-new using
 cherry-pick, and possibly modifying them as you go using commit --amend.
-The git-gui[1] command may also help as it allows you to individually
-select diff hunks for inclusion in the index (by right-clicking on the
-diff hunk and choosing "Stage Hunk for Commit").
+The gitlink:git-gui[1] command may also help as it allows you to
+individually select diff hunks for inclusion in the index (by
+right-clicking on the diff hunk and choosing "Stage Hunk for Commit").
 
 Another technique is to use git-format-patch to create a series of
 patches, then reset the state to before the patches:
@@ -2531,7 +2497,7 @@
 Other tools
 -----------
 
-There are numerous other tools, such as stgit, which exist for the
+There are numerous other tools, such as StGIT, which exist for the
 purpose of maintaining a patch series.  These are outside of the scope of
 this manual.
 
@@ -3961,8 +3927,8 @@
 
 The basic requirements:
 	- It must be readable in order, from beginning to end, by
-	  someone intelligent with a basic grasp of the unix
-	  commandline, but without any special knowledge of git.  If
+	  someone intelligent with a basic grasp of the UNIX
+	  command line, but without any special knowledge of git.  If
 	  necessary, any other prerequisites should be specifically
 	  mentioned as they arise.
 	- Whenever possible, section headings should clearly describe
diff --git a/Makefile b/Makefile
index 4eb4637..51af531 100644
--- a/Makefile
+++ b/Makefile
@@ -969,6 +969,8 @@
 
 test-delta$X: diff-delta.o patch-delta.o
 
+.PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS))
+
 test-%$X: test-%.o $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
 
diff --git a/builtin-add.c b/builtin-add.c
index 3dd4ded..105a9f0 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -14,7 +14,7 @@
 #include "revision.h"
 
 static const char builtin_add_usage[] =
-"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--] <filepattern>...";
+"git-add [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] [--] <filepattern>...";
 
 static int take_worktree_changes;
 static const char *excludes_file;
@@ -155,7 +155,7 @@
 
 static struct lock_file lock_file;
 
-static const char ignore_warning[] =
+static const char ignore_error[] =
 "The following paths are ignored by one of your .gitignore files:\n";
 
 int cmd_add(int argc, const char **argv, const char *prefix)
@@ -250,12 +250,12 @@
 		die("index file corrupt");
 
 	if (dir.ignored_nr) {
-		fprintf(stderr, ignore_warning);
+		fprintf(stderr, ignore_error);
 		for (i = 0; i < dir.ignored_nr; i++) {
 			fprintf(stderr, "%s\n", dir.ignored[i]->name);
 		}
 		fprintf(stderr, "Use -f if you really want to add them.\n");
-		exit(1);
+		die("no files added");
 	}
 
 	for (i = 0; i < dir.nr; i++)
diff --git a/builtin-blame.c b/builtin-blame.c
index 0519339..dc88a95 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -98,6 +98,10 @@
 		num_read_blob++;
 		file->ptr = read_sha1_file(o->blob_sha1, &type,
 					   (unsigned long *)(&(file->size)));
+		if (!file->ptr)
+			die("Cannot read blob %s for path %s",
+			    sha1_to_hex(o->blob_sha1),
+			    o->path);
 		o->file = *file;
 	}
 	else
@@ -1384,6 +1388,9 @@
 		unsigned long size;
 		commit->buffer =
 			read_sha1_file(commit->object.sha1, &type, &size);
+		if (!commit->buffer)
+			die("Cannot read commit %s",
+			    sha1_to_hex(commit->object.sha1));
 	}
 	ret->author = author_buf;
 	get_ac_line(commit->buffer, "\nauthor ",
@@ -2382,6 +2389,10 @@
 
 		sb.final_buf = read_sha1_file(o->blob_sha1, &type,
 					      &sb.final_buf_size);
+		if (!sb.final_buf)
+			die("Cannot read blob %s for path %s",
+			    sha1_to_hex(o->blob_sha1),
+			    path);
 	}
 	num_read_blob++;
 	lno = prepare_lines(&sb);
diff --git a/builtin-diff.c b/builtin-diff.c
index 6ed7b68..f77352b 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -188,6 +188,30 @@
 	add_pending_object(revs, obj, "HEAD");
 }
 
+static void refresh_index_quietly(void)
+{
+	struct lock_file *lock_file;
+	int fd;
+
+	lock_file = xcalloc(1, sizeof(struct lock_file));
+	fd = hold_locked_index(lock_file, 0);
+	if (fd < 0)
+		return;
+	discard_cache();
+	read_cache();
+	refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
+	if (active_cache_changed) {
+		if (write_cache(fd, active_cache, active_nr) ||
+		    close(fd) ||
+		    commit_locked_index(lock_file))
+			; /*
+			   * silently ignore it -- we haven't mucked
+			   * with the real index.
+			   */
+	}
+	rollback_lock_file(lock_file);
+}
+
 int cmd_diff(int argc, const char **argv, const char *prefix)
 {
 	int i;
@@ -222,7 +246,7 @@
 	prefix = setup_git_directory_gently(&nongit);
 	git_config(git_diff_ui_config);
 	init_revisions(&rev, prefix);
-	rev.diffopt.skip_stat_unmatch = 1;
+	rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;
 
 	if (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))
 		argc = 0;
@@ -346,11 +370,7 @@
 	if (rev.diffopt.exit_with_status)
 		result = rev.diffopt.has_changes;
 
-	if ((rev.diffopt.output_format & DIFF_FORMAT_PATCH)
-	    && (1 < rev.diffopt.skip_stat_unmatch))
-		printf("Warning: %d path%s touched but unmodified. "
-		       "Consider running git-status.\n",
-		       rev.diffopt.skip_stat_unmatch - 1,
-		       rev.diffopt.skip_stat_unmatch == 2 ? "" : "s");
+	if (1 < rev.diffopt.skip_stat_unmatch)
+		refresh_index_quietly();
 	return result;
 }
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 0d9b1e0..763fa55 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -264,9 +264,62 @@
 		if (work_tree != git_work_tree_cfg)
 			git_config_set("core.worktree", work_tree);
 	}
+
+	/* Check if symlink is supported in the work tree */
+	if (!reinit) {
+		path[len] = 0;
+		strcpy(path + len, "tXXXXXX");
+		if (!close(xmkstemp(path)) &&
+		    !unlink(path) &&
+		    !symlink("testing", path) &&
+		    !lstat(path, &st1) &&
+		    S_ISLNK(st1.st_mode))
+			unlink(path); /* good */
+		else
+			git_config_set("core.symlinks", "false");
+	}
+
 	return reinit;
 }
 
+static void guess_repository_type(const char *git_dir)
+{
+	char cwd[PATH_MAX];
+	const char *slash;
+
+	if (0 <= is_bare_repository_cfg)
+		return;
+	if (!git_dir)
+		return;
+
+	/*
+	 * "GIT_DIR=. git init" is always bare.
+	 * "GIT_DIR=`pwd` git init" too.
+	 */
+	if (!strcmp(".", git_dir))
+		goto force_bare;
+	if (!getcwd(cwd, sizeof(cwd)))
+		die("cannot tell cwd");
+	if (!strcmp(git_dir, cwd))
+		goto force_bare;
+	/*
+	 * "GIT_DIR=.git or GIT_DIR=something/.git is usually not.
+	 */
+	if (!strcmp(git_dir, ".git"))
+		return;
+	slash = strrchr(git_dir, '/');
+	if (slash && !strcmp(slash, "/.git"))
+		return;
+
+	/*
+	 * Otherwise it is often bare.  At this point
+	 * we are just guessing.
+	 */
+ force_bare:
+	is_bare_repository_cfg = 1;
+	return;
+}
+
 static const char init_db_usage[] =
 "git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
 
@@ -299,11 +352,28 @@
 			usage(init_db_usage);
 	}
 
-	git_work_tree_cfg = xcalloc(PATH_MAX, 1);
-	if (!getcwd(git_work_tree_cfg, PATH_MAX))
-		die ("Cannot access current working directory.");
-	if (access(get_git_work_tree(), X_OK))
-		die ("Cannot access work tree '%s'", get_git_work_tree());
+	/*
+	 * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
+	 * without --bare.  Catch the error early.
+	 */
+	git_dir = getenv(GIT_DIR_ENVIRONMENT);
+	if ((!git_dir || is_bare_repository_cfg == 1)
+	    && getenv(GIT_WORK_TREE_ENVIRONMENT))
+		die("%s (or --work-tree=<directory>) not allowed without "
+		    "specifying %s (or --git-dir=<directory>)",
+		    GIT_WORK_TREE_ENVIRONMENT,
+		    GIT_DIR_ENVIRONMENT);
+
+	guess_repository_type(git_dir);
+
+	if (is_bare_repository_cfg <= 0) {
+		git_work_tree_cfg = xcalloc(PATH_MAX, 1);
+		if (!getcwd(git_work_tree_cfg, PATH_MAX))
+			die ("Cannot access current working directory.");
+		if (access(get_git_work_tree(), X_OK))
+			die ("Cannot access work tree '%s'",
+			     get_git_work_tree());
+	}
 
 	/*
 	 * Set up the default .git directory contents
diff --git a/builtin-log.c b/builtin-log.c
index 13bae31..fa81c25 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -55,6 +55,7 @@
 	rev->abbrev = DEFAULT_ABBREV;
 	rev->commit_format = CMIT_FMT_DEFAULT;
 	rev->verbose_header = 1;
+	rev->diffopt.recursive = 1;
 	rev->show_root_diff = default_show_root;
 	rev->subject_prefix = fmt_patch_subject_prefix;
 	argc = setup_revisions(argc, argv, rev, "HEAD");
@@ -116,7 +117,6 @@
 	git_config(git_log_config);
 	init_revisions(&rev, prefix);
 	rev.diff = 1;
-	rev.diffopt.recursive = 1;
 	rev.simplify_history = 0;
 	cmd_log_init(argc, argv, prefix, &rev);
 	if (!rev.diffopt.output_format)
@@ -165,7 +165,6 @@
 	git_config(git_log_config);
 	init_revisions(&rev, prefix);
 	rev.diff = 1;
-	rev.diffopt.recursive = 1;
 	rev.combine_merges = 1;
 	rev.dense_combined_merges = 1;
 	rev.always_show_header = 1;
@@ -586,12 +585,19 @@
 	}
 
 	if (rev.pending.nr == 1) {
-		if (rev.max_count < 0) {
+		if (rev.max_count < 0 && !rev.show_root_diff) {
+			/*
+			 * This is traditional behaviour of "git format-patch
+			 * origin" that prepares what the origin side still
+			 * does not have.
+			 */
 			rev.pending.objects[0].item->flags |= UNINTERESTING;
 			add_head(&rev);
 		}
-		/* Otherwise, it is "format-patch -22 HEAD", and
-		 * get_revision() would return only the specified count.
+		/*
+		 * Otherwise, it is "format-patch -22 HEAD", and/or
+		 * "format-patch --root HEAD".  The user wants
+		 * get_revision() to do the usual traversal.
 		 */
 	}
 
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index d36181a..cce17b5 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -511,8 +511,28 @@
 		 */
 		int num, errors = 0;
 		for (num = 0; pathspec[num]; num++) {
+			int other, found_dup;
+
 			if (ps_matched[num])
 				continue;
+			/*
+			 * The caller might have fed identical pathspec
+			 * twice.  Do not barf on such a mistake.
+			 */
+			for (found_dup = other = 0;
+			     !found_dup && pathspec[other];
+			     other++) {
+				if (other == num || !ps_matched[other])
+					continue;
+				if (!strcmp(pathspec[other], pathspec[num]))
+					/*
+					 * Ok, we have a match already.
+					 */
+					found_dup = 1;
+			}
+			if (found_dup)
+				continue;
+
 			error("pathspec '%s' did not match any file(s) known to git.",
 			      pathspec[num] + prefix_offset);
 			errors++;
diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
index b558754..d7cb11d 100644
--- a/builtin-mailinfo.c
+++ b/builtin-mailinfo.c
@@ -287,12 +287,12 @@
 	}
 }
 
-static void decode_header(char *it);
+static void decode_header(char *it, unsigned itsize);
 static char *header[MAX_HDR_PARSED] = {
 	"From","Subject","Date",
 };
 
-static int check_header(char *line, char **hdr_data, int overwrite)
+static int check_header(char *line, unsigned linesize, char **hdr_data, int overwrite)
 {
 	int i;
 
@@ -305,7 +305,7 @@
 			/* Unwrap inline B and Q encoding, and optionally
 			 * normalize the meta information to utf8.
 			 */
-			decode_header(line + len + 2);
+			decode_header(line + len + 2, linesize - len - 2);
 			hdr_data[i] = xmalloc(1000 * sizeof(char));
 			if (! handle_header(line, hdr_data[i], len + 2)) {
 				return 1;
@@ -316,14 +316,14 @@
 	/* Content stuff */
 	if (!strncasecmp(line, "Content-Type", 12) &&
 		line[12] == ':' && isspace(line[12 + 1])) {
-		decode_header(line + 12 + 2);
+		decode_header(line + 12 + 2, linesize - 12 - 2);
 		if (! handle_content_type(line)) {
 			return 1;
 		}
 	}
 	if (!strncasecmp(line, "Content-Transfer-Encoding", 25) &&
 		line[25] == ':' && isspace(line[25 + 1])) {
-		decode_header(line + 25 + 2);
+		decode_header(line + 25 + 2, linesize - 25 - 2);
 		if (! handle_content_transfer_encoding(line)) {
 			return 1;
 		}
@@ -432,10 +432,15 @@
 	return 1;
 }
 
-static int decode_q_segment(char *in, char *ot, char *ep, int rfc2047)
+static int decode_q_segment(char *in, char *ot, unsigned otsize, char *ep, int rfc2047)
 {
+	char *otend = ot + otsize;
 	int c;
 	while ((c = *in++) != 0 && (in <= ep)) {
+		if (ot == otend) {
+			*--ot = '\0';
+			return -1;
+		}
 		if (c == '=') {
 			int d = *in++;
 			if (d == '\n' || !d)
@@ -451,12 +456,17 @@
 	return 0;
 }
 
-static int decode_b_segment(char *in, char *ot, char *ep)
+static int decode_b_segment(char *in, char *ot, unsigned otsize, char *ep)
 {
 	/* Decode in..ep, possibly in-place to ot */
 	int c, pos = 0, acc = 0;
+	char *otend = ot + otsize;
 
 	while ((c = *in++) != 0 && (in <= ep)) {
+		if (ot == otend) {
+			*--ot = '\0';
+			return -1;
+		}
 		if (c == '+')
 			c = 62;
 		else if (c == '/')
@@ -518,7 +528,7 @@
 	return "latin1";
 }
 
-static void convert_to_utf8(char *line, const char *charset)
+static void convert_to_utf8(char *line, unsigned linesize, const char *charset)
 {
 	char *out;
 
@@ -534,11 +544,11 @@
 	if (!out)
 		die("cannot convert from %s to %s\n",
 		    charset, metainfo_charset);
-	strcpy(line, out);
+	strlcpy(line, out, linesize);
 	free(out);
 }
 
-static int decode_header_bq(char *it)
+static int decode_header_bq(char *it, unsigned itsize)
 {
 	char *in, *out, *ep, *cp, *sp;
 	char outbuf[1000];
@@ -578,56 +588,60 @@
 		default:
 			return rfc2047; /* no munging */
 		case 'b':
-			sz = decode_b_segment(cp + 3, piecebuf, ep);
+			sz = decode_b_segment(cp + 3, piecebuf, sizeof(piecebuf), ep);
 			break;
 		case 'q':
-			sz = decode_q_segment(cp + 3, piecebuf, ep, 1);
+			sz = decode_q_segment(cp + 3, piecebuf, sizeof(piecebuf), ep, 1);
 			break;
 		}
 		if (sz < 0)
 			return rfc2047;
 		if (metainfo_charset)
-			convert_to_utf8(piecebuf, charset_q);
+			convert_to_utf8(piecebuf, sizeof(piecebuf), charset_q);
+
+		sz = strlen(piecebuf);
+		if (outbuf + sizeof(outbuf) <= out + sz)
+			return rfc2047; /* no munging */
 		strcpy(out, piecebuf);
-		out += strlen(out);
+		out += sz;
 		in = ep + 2;
 	}
 	strcpy(out, in);
-	strcpy(it, outbuf);
+	strlcpy(it, outbuf, itsize);
 	return rfc2047;
 }
 
-static void decode_header(char *it)
+static void decode_header(char *it, unsigned itsize)
 {
 
-	if (decode_header_bq(it))
+	if (decode_header_bq(it, itsize))
 		return;
 	/* otherwise "it" is a straight copy of the input.
 	 * This can be binary guck but there is no charset specified.
 	 */
 	if (metainfo_charset)
-		convert_to_utf8(it, "");
+		convert_to_utf8(it, itsize, "");
 }
 
-static void decode_transfer_encoding(char *line)
+static void decode_transfer_encoding(char *line, unsigned linesize)
 {
 	char *ep;
 
 	switch (transfer_encoding) {
 	case TE_QP:
 		ep = line + strlen(line);
-		decode_q_segment(line, line, ep, 0);
+		decode_q_segment(line, line, linesize, ep, 0);
 		break;
 	case TE_BASE64:
 		ep = line + strlen(line);
-		decode_b_segment(line, line, ep);
+		decode_b_segment(line, line, linesize, ep);
 		break;
 	case TE_DONTCARE:
 		break;
 	}
 }
 
-static int handle_filter(char *line);
+static int handle_filter(char *line, unsigned linesize);
 
 static int find_boundary(void)
 {
@@ -655,7 +669,7 @@
 					"can't recover\n");
 			exit(1);
 		}
-		handle_filter(newline);
+		handle_filter(newline, sizeof(newline));
 
 		/* skip to the next boundary */
 		if (!find_boundary())
@@ -670,7 +684,7 @@
 
 	/* slurp in this section's info */
 	while (read_one_header_line(line, sizeof(line), fin))
-		check_header(line, p_hdr_data, 0);
+		check_header(line, sizeof(line), p_hdr_data, 0);
 
 	/* eat the blank line after section info */
 	return (fgets(line, sizeof(line), fin) != NULL);
@@ -709,9 +723,10 @@
 }
 
 
-static int handle_commit_msg(char *line)
+static int handle_commit_msg(char *line, unsigned linesize)
 {
 	static int still_looking = 1;
+	char *endline = line + linesize;
 
 	if (!cmitmsg)
 		return 0;
@@ -726,13 +741,13 @@
 			if (!*cp)
 				return 0;
 		}
-		if ((still_looking = check_header(cp, s_hdr_data, 0)) != 0)
+		if ((still_looking = check_header(cp, endline - cp, s_hdr_data, 0)) != 0)
 			return 0;
 	}
 
 	/* normalize the log message to UTF-8. */
 	if (metainfo_charset)
-		convert_to_utf8(line, charset);
+		convert_to_utf8(line, endline - line, charset);
 
 	if (patchbreak(line)) {
 		fclose(cmitmsg);
@@ -751,7 +766,7 @@
 	return 0;
 }
 
-static int handle_filter(char *line)
+static int handle_filter(char *line, unsigned linesize)
 {
 	static int filter = 0;
 
@@ -760,7 +775,7 @@
 	 */
 	switch (filter) {
 	case 0:
-		if (!handle_commit_msg(line))
+		if (!handle_commit_msg(line, linesize))
 			break;
 		filter++;
 	case 1:
@@ -792,14 +807,14 @@
 			/* flush any leftover */
 			if ((transfer_encoding == TE_BASE64)  &&
 			    (np != newline)) {
-				handle_filter(newline);
+				handle_filter(newline, sizeof(newline));
 			}
 			if (!handle_boundary())
 				return;
 		}
 
 		/* Unwrap transfer encoding */
-		decode_transfer_encoding(line);
+		decode_transfer_encoding(line, sizeof(line));
 
 		switch (transfer_encoding) {
 		case TE_BASE64:
@@ -808,7 +823,7 @@
 
 			/* binary data most likely doesn't have newlines */
 			if (message_type != TYPE_TEXT) {
-				rc = handle_filter(line);
+				rc = handle_filter(line, sizeof(newline));
 				break;
 			}
 
@@ -825,7 +840,7 @@
 					/* should be sitting on a new line */
 					*(++np) = 0;
 					op++;
-					rc = handle_filter(newline);
+					rc = handle_filter(newline, sizeof(newline));
 					np = newline;
 				}
 			} while (*op != 0);
@@ -835,7 +850,7 @@
 			break;
 		}
 		default:
-			rc = handle_filter(line);
+			rc = handle_filter(line, sizeof(newline));
 		}
 		if (rc)
 			/* nothing left to filter */
@@ -922,7 +937,7 @@
 
 	/* process the email header */
 	while (read_one_header_line(line, sizeof(line), fin))
-		check_header(line, p_hdr_data, 1);
+		check_header(line, sizeof(line), p_hdr_data, 1);
 
 	handle_body();
 	handle_info();
diff --git a/builtin-name-rev.c b/builtin-name-rev.c
index 61eba34..03083e9 100644
--- a/builtin-name-rev.c
+++ b/builtin-name-rev.c
@@ -11,14 +11,17 @@
 
 typedef struct rev_name {
 	const char *tip_name;
-	int merge_traversals;
 	int generation;
+	int distance;
 } rev_name;
 
 static long cutoff = LONG_MAX;
 
+/* How many generations are maximally preferred over _one_ merge traversal? */
+#define MERGE_TRAVERSAL_WEIGHT 65535
+
 static void name_rev(struct commit *commit,
-		const char *tip_name, int merge_traversals, int generation,
+		const char *tip_name, int generation, int distance,
 		int deref)
 {
 	struct rev_name *name = (struct rev_name *)commit->util;
@@ -45,13 +48,11 @@
 		name = xmalloc(sizeof(rev_name));
 		commit->util = name;
 		goto copy_data;
-	} else if (name->merge_traversals > merge_traversals ||
-			(name->merge_traversals == merge_traversals &&
-			 name->generation > generation)) {
+	} else if (name->distance > distance) {
 copy_data:
 		name->tip_name = tip_name;
-		name->merge_traversals = merge_traversals;
 		name->generation = generation;
+		name->distance = distance;
 	} else
 		return;
 
@@ -74,11 +75,11 @@
 				sprintf(new_name, "%.*s^%d", len, tip_name,
 						parent_number);
 
-			name_rev(parents->item, new_name,
-				merge_traversals + 1 , 0, 0);
+			name_rev(parents->item, new_name, 0,
+				distance + MERGE_TRAVERSAL_WEIGHT, 0);
 		} else {
-			name_rev(parents->item, tip_name, merge_traversals,
-				generation + 1, 0);
+			name_rev(parents->item, tip_name, generation + 1,
+				distance + 1, 0);
 		}
 	}
 }
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 24926db..12509fa 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -979,6 +979,8 @@
 	int cmp;
 
 	while (tree_entry(tree,&entry)) {
+		if (S_ISGITLINK(entry.mode))
+			continue;
 		cmp = tree_entry_len(entry.path, entry.sha1) != cmplen ? 1 :
 		      memcmp(name, entry.path, cmplen);
 		if (cmp > 0)
@@ -1354,6 +1356,9 @@
 	/* Load data if not already done */
 	if (!trg->data) {
 		trg->data = read_sha1_file(trg_entry->idx.sha1, &type, &sz);
+		if (!trg->data)
+			die("object %s cannot be read",
+			    sha1_to_hex(trg_entry->idx.sha1));
 		if (sz != trg_size)
 			die("object %s inconsistent object length (%lu vs %lu)",
 			    sha1_to_hex(trg_entry->idx.sha1), sz, trg_size);
@@ -1361,6 +1366,9 @@
 	}
 	if (!src->data) {
 		src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz);
+		if (!src->data)
+			die("object %s cannot be read",
+			    sha1_to_hex(src_entry->idx.sha1));
 		if (sz != src_size)
 			die("object %s inconsistent object length (%lu vs %lu)",
 			    sha1_to_hex(src_entry->idx.sha1), sz, src_size);
@@ -1381,20 +1389,24 @@
 	if (!delta_buf)
 		return 0;
 
-	if (trg_entry->delta_data) {
+	if (trg_entry->delta) {
 		/* Prefer only shallower same-sized deltas. */
 		if (delta_size == trg_entry->delta_size &&
 		    src->depth + 1 >= trg->depth) {
 			free(delta_buf);
 			return 0;
 		}
+	}
+
+	trg_entry->delta = src_entry;
+	trg_entry->delta_size = delta_size;
+	trg->depth = src->depth + 1;
+
+	if (trg_entry->delta_data) {
 		delta_cache_size -= trg_entry->delta_size;
 		free(trg_entry->delta_data);
 		trg_entry->delta_data = NULL;
 	}
-	trg_entry->delta = src_entry;
-	trg_entry->delta_size = delta_size;
-	trg->depth = src->depth + 1;
 
 	if (delta_cacheable(src_size, trg_size, delta_size)) {
 		trg_entry->delta_data = xrealloc(delta_buf, delta_size);
diff --git a/builtin-tag.c b/builtin-tag.c
index d6d38ad..348919c 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -123,22 +123,15 @@
 static int list_tags(const char *pattern, int lines)
 {
 	struct tag_filter filter;
-	char *newpattern;
 
 	if (pattern == NULL)
-		pattern = "";
+		pattern = "*";
 
-	/* prepend/append * to the shell pattern: */
-	newpattern = xmalloc(strlen(pattern) + 3);
-	sprintf(newpattern, "*%s*", pattern);
-
-	filter.pattern = newpattern;
+	filter.pattern = pattern;
 	filter.lines = lines;
 
 	for_each_tag_ref(show_reference, (void *) &filter);
 
-	free(newpattern);
-
 	return 0;
 }
 
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index 88f34ba..b89d02e 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -72,6 +72,7 @@
 	const char *prefix = NULL;
 	unsigned char sha1[20];
 
+	git_config(git_default_config);
 	while (1 < argc) {
 		const char *arg = argv[1];
 		if (!strcmp(arg, "--missing-ok"))
diff --git a/cache.h b/cache.h
index c7e00e7..70abbd5 100644
--- a/cache.h
+++ b/cache.h
@@ -594,6 +594,9 @@
 extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep);
 extern void *convert_sha1_file(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size);
 
+/* diff.c */
+extern int diff_auto_refresh_index;
+
 /* match-trees.c */
 void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
 
diff --git a/connect.c b/connect.c
index ae49c5a..8b1e993 100644
--- a/connect.c
+++ b/connect.c
@@ -453,6 +453,22 @@
 
 #define MAX_CMD_LEN 1024
 
+char *get_port(char *host)
+{
+	char *end;
+	char *p = strchr(host, ':');
+
+	if (p) {
+		strtol(p+1, &end, 10);
+		if (*end == '\0') {
+			*p = '\0';
+			return p+1;
+		}
+	}
+
+	return NULL;
+}
+
 /*
  * This returns 0 if the transport protocol does not need fork(2),
  * or a process id if it does.  Once done, finish the connection
@@ -471,6 +487,7 @@
 	pid_t pid;
 	enum protocol protocol = PROTO_LOCAL;
 	int free_path = 0;
+	char *port = NULL;
 
 	/* Without this we cannot rely on waitpid() to tell
 	 * what happened to our children.
@@ -527,6 +544,12 @@
 		*ptr = '\0';
 	}
 
+	/*
+	 * Add support for ssh port: ssh://host.xy:<port>/...
+	 */
+	if (protocol == PROTO_SSH && host != url)
+		port = get_port(host);
+
 	if (protocol == PROTO_GIT) {
 		/* These underlying connection commands die() if they
 		 * cannot connect.
@@ -583,7 +606,12 @@
 				ssh_basename = ssh;
 			else
 				ssh_basename++;
-			execlp(ssh, ssh_basename, host, command, NULL);
+
+			if (!port)
+				execlp(ssh, ssh_basename, host, command, NULL);
+			else
+				execlp(ssh, ssh_basename, "-p", port, host,
+				       command, NULL);
 		}
 		else {
 			unsetenv(ALTERNATE_DB_ENVIRONMENT);
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 82b9ed4..cad842a 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -114,6 +114,27 @@
 	done
 }
 
+__git_tags ()
+{
+	local cmd i is_hash=y dir="$(__gitdir "$1")"
+	if [ -d "$dir" ]; then
+		for i in $(git --git-dir="$dir" \
+			for-each-ref --format='%(refname)' \
+			refs/tags ); do
+			echo "${i#refs/tags/}"
+		done
+		return
+	fi
+	for i in $(git-ls-remote "$1" 2>/dev/null); do
+		case "$is_hash,$i" in
+		y,*) is_hash=n ;;
+		n,*^{}) is_hash=y ;;
+		n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
+		n,*) is_hash=y; echo "$i" ;;
+		esac
+	done
+}
+
 __git_refs ()
 {
 	local cmd i is_hash=y dir="$(__gitdir "$1")"
@@ -419,7 +440,7 @@
 	local cur="${COMP_WORDS[COMP_CWORD]}"
 	case "$cur" in
 	--*)
-		__gitcomp "--interactive"
+		__gitcomp "--interactive --refresh"
 		return
 	esac
 	COMPREPLY=()
@@ -459,6 +480,35 @@
 	__gitcomp "$(__git_refs)"
 }
 
+_git_bundle ()
+{
+	local mycword="$COMP_CWORD"
+	case "${COMP_WORDS[0]}" in
+	git)
+		local cmd="${COMP_WORDS[2]}"
+		mycword="$((mycword-1))"
+		;;
+	git-bundle*)
+		local cmd="${COMP_WORDS[1]}"
+		;;
+	esac
+	case "$mycword" in
+	1)
+		__gitcomp "create list-heads verify unbundle"
+		;;
+	2)
+		# looking for a file
+		;;
+	*)
+		case "$cmd" in
+			create)
+				__git_complete_revlist
+			;;
+		esac
+		;;
+	esac
+}
+
 _git_checkout ()
 {
 	__gitcomp "$(__git_refs)"
@@ -496,6 +546,11 @@
 	COMPREPLY=()
 }
 
+_git_describe ()
+{
+	__gitcomp "$(__git_refs)"
+}
+
 _git_diff ()
 {
 	__git_complete_file
@@ -544,6 +599,7 @@
 			--stdout --attach --thread
 			--output-directory
 			--numbered --start-number
+			--numbered-files
 			--keep-subject
 			--signoff
 			--in-reply-to=
@@ -561,7 +617,7 @@
 	local cur="${COMP_WORDS[COMP_CWORD]}"
 	case "$cur" in
 	--*)
-		__gitcomp "--prune"
+		__gitcomp "--prune --aggressive"
 		return
 		;;
 	esac
@@ -588,18 +644,25 @@
 			" "" "${cur##--pretty=}"
 		return
 		;;
+	--date=*)
+		__gitcomp "
+			relative iso8601 rfc2822 short local default
+		" "" "${cur##--date=}"
+		return
+		;;
 	--*)
 		__gitcomp "
 			--max-count= --max-age= --since= --after=
 			--min-age= --before= --until=
 			--root --topo-order --date-order --reverse
-			--no-merges
+			--no-merges --follow
 			--abbrev-commit --abbrev=
-			--relative-date
+			--relative-date --date=
 			--author= --committer= --grep=
 			--all-match
 			--pretty= --name-status --name-only --raw
 			--not --all
+			--left-right --cherry-pick
 			"
 		return
 		;;
@@ -767,7 +830,7 @@
 	case "$cur" in
 	--*)
 		__gitcomp "
-			--global --system
+			--global --system --file=
 			--list --replace-all
 			--get --get-all --get-regexp
 			--add --unset --unset-all
@@ -810,6 +873,7 @@
 		core.ignoreStat
 		core.preferSymlinkRefs
 		core.logAllRefUpdates
+		core.loosecompression
 		core.repositoryFormatVersion
 		core.sharedRepository
 		core.warnAmbiguousRefs
@@ -841,6 +905,7 @@
 		diff.renames
 		fetch.unpackLimit
 		format.headers
+		format.subjectprefix
 		gitcvs.enabled
 		gitcvs.logfile
 		gitcvs.allbinary
@@ -867,6 +932,10 @@
 		merge.verbosity
 		pack.window
 		pack.depth
+		pack.windowMemory
+		pack.compression
+		pack.deltaCacheSize
+		pack.deltaCacheLimit
 		pull.octopus
 		pull.twohead
 		repack.useDeltaBaseOffset
@@ -977,6 +1046,65 @@
 	__gitcomp 'list show apply clear'
 }
 
+_git_submodule ()
+{
+	local i c=1 command
+	while [ $c -lt $COMP_CWORD ]; do
+		i="${COMP_WORDS[c]}"
+		case "$i" in
+		add|status|init|update) command="$i"; break ;;
+		esac
+		c=$((++c))
+	done
+
+	if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
+		local cur="${COMP_WORDS[COMP_CWORD]}"
+		case "$cur" in
+		--*)
+			__gitcomp "--quiet --cached"
+			;;
+		*)
+			__gitcomp "add status init update"
+			;;
+		esac
+		return
+	fi
+}
+
+_git_tag ()
+{
+	local i c=1 f=0
+	while [ $c -lt $COMP_CWORD ]; do
+		i="${COMP_WORDS[c]}"
+		case "$i" in
+		-d|-v)
+			__gitcomp "$(__git_tags)"
+			return
+			;;
+		-f)
+			f=1
+			;;
+		esac
+		c=$((++c))
+	done
+
+	case "${COMP_WORDS[COMP_CWORD-1]}" in
+	-m|-F)
+		COMPREPLY=()
+		;;
+	-*|tag|git-tag)
+		if [ $f = 1 ]; then
+			__gitcomp "$(__git_tags)"
+		else
+			COMPREPLY=()
+		fi
+		;;
+	*)
+		__gitcomp "$(__git_refs)"
+		;;
+	esac
+}
+
 _git ()
 {
 	local i c=1 command __git_dir
@@ -995,7 +1123,14 @@
 	if [ $c -eq $COMP_CWORD -a -z "$command" ]; then
 		case "${COMP_WORDS[COMP_CWORD]}" in
 		--*=*) COMPREPLY=() ;;
-		--*)   __gitcomp "--git-dir= --bare --version --exec-path" ;;
+		--*)   __gitcomp "
+			--no-pager
+			--git-dir=
+			--bare
+			--version
+			--exec-path
+			"
+			;;
 		*)     __gitcomp "$(__git_commands) $(__git_aliases)" ;;
 		esac
 		return
@@ -1009,12 +1144,14 @@
 	add)         _git_add ;;
 	apply)       _git_apply ;;
 	bisect)      _git_bisect ;;
+	bundle)      _git_bundle ;;
 	branch)      _git_branch ;;
 	checkout)    _git_checkout ;;
 	cherry)      _git_cherry ;;
 	cherry-pick) _git_cherry_pick ;;
 	commit)      _git_commit ;;
 	config)      _git_config ;;
+	describe)    _git_describe ;;
 	diff)        _git_diff ;;
 	fetch)       _git_fetch ;;
 	format-patch) _git_format_patch ;;
@@ -1034,6 +1171,8 @@
 	show)        _git_show ;;
 	show-branch) _git_log ;;
 	stash)       _git_stash ;;
+	submodule)   _git_submodule ;;
+	tag)         _git_tag ;;
 	whatchanged) _git_log ;;
 	*)           COMPREPLY=() ;;
 	esac
@@ -1057,10 +1196,12 @@
 complete -o default -o nospace -F _git_apply git-apply
 complete -o default -o nospace -F _git_bisect git-bisect
 complete -o default -o nospace -F _git_branch git-branch
+complete -o default -o nospace -F _git_bundle git-bundle
 complete -o default -o nospace -F _git_checkout git-checkout
 complete -o default -o nospace -F _git_cherry git-cherry
 complete -o default -o nospace -F _git_cherry_pick git-cherry-pick
 complete -o default -o nospace -F _git_commit git-commit
+complete -o default -o nospace -F _git_describe git-describe
 complete -o default -o nospace -F _git_diff git-diff
 complete -o default -o nospace -F _git_fetch git-fetch
 complete -o default -o nospace -F _git_format_patch git-format-patch
@@ -1080,7 +1221,9 @@
 complete -o default -o nospace -F _git_shortlog git-shortlog
 complete -o default -o nospace -F _git_show git-show
 complete -o default -o nospace -F _git_stash git-stash
+complete -o default -o nospace -F _git_submodule git-submodule
 complete -o default -o nospace -F _git_log git-show-branch
+complete -o default -o nospace -F _git_tag git-tag
 complete -o default -o nospace -F _git_log git-whatchanged
 
 # The following are necessary only for Cygwin, and only are needed
@@ -1092,7 +1235,9 @@
 complete -o default -o nospace -F _git_apply git-apply.exe
 complete -o default -o nospace -F _git git.exe
 complete -o default -o nospace -F _git_branch git-branch.exe
+complete -o default -o nospace -F _git_bundle git-bundle.exe
 complete -o default -o nospace -F _git_cherry git-cherry.exe
+complete -o default -o nospace -F _git_describe git-describe.exe
 complete -o default -o nospace -F _git_diff git-diff.exe
 complete -o default -o nospace -F _git_format_patch git-format-patch.exe
 complete -o default -o nospace -F _git_log git-log.exe
@@ -1104,5 +1249,6 @@
 complete -o default -o nospace -F _git_shortlog git-shortlog.exe
 complete -o default -o nospace -F _git_show git-show.exe
 complete -o default -o nospace -F _git_log git-show-branch.exe
+complete -o default -o nospace -F _git_tag git-tag.exe
 complete -o default -o nospace -F _git_log git-whatchanged.exe
 fi
diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el
index be44e06..280557e 100644
--- a/contrib/emacs/git.el
+++ b/contrib/emacs/git.el
@@ -99,47 +99,56 @@
 
 
 (defface git-status-face
-  '((((class color) (background light)) (:foreground "purple")))
+  '((((class color) (background light)) (:foreground "purple"))
+    (((class color) (background dark)) (:foreground "salmon")))
   "Git mode face used to highlight added and modified files."
   :group 'git)
 
 (defface git-unmerged-face
-  '((((class color) (background light)) (:foreground "red" :bold t)))
+  '((((class color) (background light)) (:foreground "red" :bold t))
+    (((class color) (background dark)) (:foreground "red" :bold t)))
   "Git mode face used to highlight unmerged files."
   :group 'git)
 
 (defface git-unknown-face
-  '((((class color) (background light)) (:foreground "goldenrod" :bold t)))
+  '((((class color) (background light)) (:foreground "goldenrod" :bold t))
+    (((class color) (background dark)) (:foreground "goldenrod" :bold t)))
   "Git mode face used to highlight unknown files."
   :group 'git)
 
 (defface git-uptodate-face
-  '((((class color) (background light)) (:foreground "grey60")))
+  '((((class color) (background light)) (:foreground "grey60"))
+    (((class color) (background dark)) (:foreground "grey40")))
   "Git mode face used to highlight up-to-date files."
   :group 'git)
 
 (defface git-ignored-face
-  '((((class color) (background light)) (:foreground "grey60")))
+  '((((class color) (background light)) (:foreground "grey60"))
+    (((class color) (background dark)) (:foreground "grey40")))
   "Git mode face used to highlight ignored files."
   :group 'git)
 
 (defface git-mark-face
-  '((((class color) (background light)) (:foreground "red" :bold t)))
+  '((((class color) (background light)) (:foreground "red" :bold t))
+    (((class color) (background dark)) (:foreground "tomato" :bold t)))
   "Git mode face used for the file marks."
   :group 'git)
 
 (defface git-header-face
-  '((((class color) (background light)) (:foreground "blue")))
+  '((((class color) (background light)) (:foreground "blue"))
+    (((class color) (background dark)) (:foreground "blue")))
   "Git mode face used for commit headers."
   :group 'git)
 
 (defface git-separator-face
-  '((((class color) (background light)) (:foreground "brown")))
+  '((((class color) (background light)) (:foreground "brown"))
+    (((class color) (background dark)) (:foreground "brown")))
   "Git mode face used for commit separator."
   :group 'git)
 
 (defface git-permission-face
-  '((((class color) (background light)) (:foreground "green" :bold t)))
+  '((((class color) (background light)) (:foreground "green" :bold t))
+    (((class color) (background dark)) (:foreground "green" :bold t)))
   "Git mode face used for permission changes."
   :group 'git)
 
@@ -664,9 +673,11 @@
     (ewoc-set-hf status
                  (format "Directory:  %s\nBranch:     %s\nHead:       %s%s\n"
                          default-directory
-                         (if (string-match "^refs/heads/" branch)
-                             (substring branch (match-end 0))
-                           branch)
+                         (if branch
+                             (if (string-match "^refs/heads/" branch)
+                                 (substring branch (match-end 0))
+                               branch)
+                           "none (detached HEAD)")
                          head
                          (if merge-heads
                              (concat "\nMerging:    "
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 6d01062..55778c5 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -231,6 +231,56 @@
 
     return ["", settings]
 
+def createOrUpdateBranchesFromOrigin(localRefPrefix = "refs/remotes/p4/", silent=True):
+    if not silent:
+        print ("Creating/updating branch(es) in %s based on origin branch(es)"
+               % localRefPrefix)
+
+    originPrefix = "origin/p4/"
+
+    for line in read_pipe_lines("git rev-parse --symbolic --remotes"):
+        line = line.strip()
+        if (not line.startswith(originPrefix)) or line.endswith("HEAD"):
+            continue
+
+        headName = line[len(originPrefix):]
+        remoteHead = localRefPrefix + headName
+        originHead = line
+
+        original = extractSettingsGitLog(extractLogMessageFromGitCommit(originHead))
+        if (not original.has_key('depot-paths')
+            or not original.has_key('change')):
+            continue
+
+        update = False
+        if not gitBranchExists(remoteHead):
+            if verbose:
+                print "creating %s" % remoteHead
+            update = True
+        else:
+            settings = extractSettingsGitLog(extractLogMessageFromGitCommit(remoteHead))
+            if settings.has_key('change') > 0:
+                if settings['depot-paths'] == original['depot-paths']:
+                    originP4Change = int(original['change'])
+                    p4Change = int(settings['change'])
+                    if originP4Change > p4Change:
+                        print ("%s (%s) is newer than %s (%s). "
+                               "Updating p4 branch from origin."
+                               % (originHead, originP4Change,
+                                  remoteHead, p4Change))
+                        update = True
+                else:
+                    print ("Ignoring: %s was imported from %s while "
+                           "%s was imported from %s"
+                           % (originHead, ','.join(original['depot-paths']),
+                              remoteHead, ','.join(settings['depot-paths'])))
+
+        if update:
+            system("git update-ref %s %s" % (remoteHead, originHead))
+
+def originP4BranchesExist():
+        return gitBranchExists("origin") or gitBranchExists("origin/p4") or gitBranchExists("origin/p4/master")
+
 class Command:
     def __init__(self):
         self.usage = "usage: %prog [options]"
@@ -1041,53 +1091,6 @@
         for branch in branches.keys():
             self.initialParents[self.refPrefix + branch] = branches[branch]
 
-    def createOrUpdateBranchesFromOrigin(self):
-        if not self.silent:
-            print ("Creating/updating branch(es) in %s based on origin branch(es)"
-                   % self.refPrefix)
-
-        originPrefix = "origin/p4/"
-
-        for line in read_pipe_lines("git rev-parse --symbolic --remotes"):
-            line = line.strip()
-            if (not line.startswith(originPrefix)) or line.endswith("HEAD"):
-                continue
-
-            headName = line[len(originPrefix):]
-            remoteHead = self.refPrefix + headName
-            originHead = line
-
-            original = extractSettingsGitLog(extractLogMessageFromGitCommit(originHead))
-            if (not original.has_key('depot-paths')
-                or not original.has_key('change')):
-                continue
-
-            update = False
-            if not gitBranchExists(remoteHead):
-                if self.verbose:
-                    print "creating %s" % remoteHead
-                update = True
-            else:
-                settings = extractSettingsGitLog(extractLogMessageFromGitCommit(remoteHead))
-                if settings.has_key('change') > 0:
-                    if settings['depot-paths'] == original['depot-paths']:
-                        originP4Change = int(original['change'])
-                        p4Change = int(settings['change'])
-                        if originP4Change > p4Change:
-                            print ("%s (%s) is newer than %s (%s). "
-                                   "Updating p4 branch from origin."
-                                   % (originHead, originP4Change,
-                                      remoteHead, p4Change))
-                            update = True
-                    else:
-                        print ("Ignoring: %s was imported from %s while "
-                               "%s was imported from %s"
-                               % (originHead, ','.join(original['depot-paths']),
-                                  remoteHead, ','.join(settings['depot-paths'])))
-
-            if update:
-                system("git update-ref %s %s" % (remoteHead, originHead))
-
     def updateOptionDict(self, d):
         option_keys = {}
         if self.keepRepoPath:
@@ -1108,7 +1111,7 @@
         # map from branch depot path to parent branch
         self.knownBranches = {}
         self.initialParents = {}
-        self.hasOrigin = gitBranchExists("origin") or gitBranchExists("origin/p4") or gitBranchExists("origin/p4/master")
+        self.hasOrigin = originP4BranchesExist()
         if not self.syncWithOrigin:
             self.hasOrigin = False
 
@@ -1128,14 +1131,14 @@
                 system("git update-ref %s refs/heads/p4" % self.branch)
                 system("git branch -D p4");
             # create it /after/ importing, when master exists
-            if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes:
+            if not gitBranchExists(self.refPrefix + "HEAD") and self.importIntoRemotes and gitBranchExists(self.branch):
                 system("git symbolic-ref %sHEAD %s" % (self.refPrefix, self.branch))
 
         # TODO: should always look at previous commits,
         # merge with previous imports, if possible.
         if args == []:
             if self.hasOrigin:
-                self.createOrUpdateBranchesFromOrigin()
+                createOrUpdateBranchesFromOrigin(self.refPrefix, self.silent)
             self.listExistingP4GitBranches()
 
             if len(self.p4BranchesInGit) > 1:
@@ -1518,6 +1521,9 @@
         self.verbose = False
 
     def run(self, args):
+        if originP4BranchesExist():
+            createOrUpdateBranchesFromOrigin()
+
         cmdline = "git rev-parse --symbolic "
         cmdline += " --remotes"
 
diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir
index 3ff6bd1..c6e154a 100755
--- a/contrib/workdir/git-new-workdir
+++ b/contrib/workdir/git-new-workdir
@@ -24,9 +24,21 @@
   git rev-parse --git-dir 2>/dev/null) ||
   die "\"$orig_git\" is not a git repository!"
 
-if test "$git_dir" = ".git"
-then
+case "$git_dir" in
+.git)
 	git_dir="$orig_git/.git"
+	;;
+.)
+	git_dir=$orig_git
+	;;
+esac
+
+# don't link to a configured bare repository
+isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
+if test ztrue = z$isbare
+then
+	die "\"$git_dir\" has core.bare set to true," \
+		" remove from \"$git_dir/config\" to use $0"
 fi
 
 # don't link to a workdir
diff --git a/diff-delta.c b/diff-delta.c
index 3af5835..0dde2f2 100644
--- a/diff-delta.c
+++ b/diff-delta.c
@@ -213,7 +213,7 @@
 		entry = hash[i];
 		do {
 			struct index_entry *keep = entry;
-			int skip = hash_count[i] / HASH_LIMIT / 2;
+			int skip = hash_count[i] / HASH_LIMIT;
 			do {
 				entry = entry->next;
 			} while(--skip && entry);
diff --git a/diff.c b/diff.c
index 97cc5bc..0d30d05 100644
--- a/diff.c
+++ b/diff.c
@@ -19,6 +19,7 @@
 static int diff_detect_rename_default;
 static int diff_rename_limit_default = -1;
 static int diff_use_color_default;
+int diff_auto_refresh_index = 1;
 
 static char diff_colors[][COLOR_MAXLEN] = {
 	"\033[m",	/* reset */
@@ -166,6 +167,10 @@
 			diff_detect_rename_default = DIFF_DETECT_RENAME;
 		return 0;
 	}
+	if (!strcmp(var, "diff.autorefreshindex")) {
+		diff_auto_refresh_index = git_config_bool(var, value);
+		return 0;
+	}
 	if (!prefixcmp(var, "diff.")) {
 		const char *ep = strrchr(var, '.');
 
@@ -2919,10 +2924,6 @@
 				fill_mmfile(&mf2, p->two) < 0)
 			return error("unable to read files to diff");
 
-		/* Maybe hash p->two? into the patch id? */
-		if (diff_filespec_is_binary(p->two))
-			continue;
-
 		len1 = remove_space(p->one->path, strlen(p->one->path));
 		len2 = remove_space(p->two->path, strlen(p->two->path));
 		if (p->one->mode == 0)
diff --git a/fast-import.c b/fast-import.c
index 170cccd..078079d 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -8,10 +8,11 @@
         | new_tag
         | reset_branch
         | checkpoint
+        | progress
         ;
 
   new_blob ::= 'blob' lf
-	mark?
+    mark?
     file_content;
   file_content ::= data;
 
@@ -23,7 +24,7 @@
     ('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
     ('merge' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)*
     file_change*
-    lf;
+    lf?;
   commit_msg ::= data;
 
   file_change ::= file_clr
@@ -42,33 +43,36 @@
 
   new_tag ::= 'tag' sp tag_str lf
     'from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf
-	'tagger' sp name '<' email '>' when lf
+    'tagger' sp name '<' email '>' when lf
     tag_msg;
   tag_msg ::= data;
 
   reset_branch ::= 'reset' sp ref_str lf
     ('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
-    lf;
+    lf?;
 
   checkpoint ::= 'checkpoint' lf
-    lf;
+    lf?;
+
+  progress ::= 'progress' sp not_lf* lf
+    lf?;
 
      # note: the first idnum in a stream should be 1 and subsequent
      # idnums should not have gaps between values as this will cause
      # the stream parser to reserve space for the gapped values.  An
-	 # idnum can be updated in the future to a new object by issuing
+     # idnum can be updated in the future to a new object by issuing
      # a new mark directive with the old idnum.
-	 #
+     #
   mark ::= 'mark' sp idnum lf;
   data ::= (delimited_data | exact_data)
-    lf;
+    lf?;
 
     # note: delim may be any string but must not contain lf.
     # data_line may contain any data but must not be exactly
     # delim.
   delimited_data ::= 'data' sp '<<' delim lf
     (data_line lf)*
-	delim lf;
+    delim lf;
 
      # note: declen indicates the length of binary_data in bytes.
      # declen does not include the lf preceeding the binary data.
@@ -78,10 +82,10 @@
 
      # note: quoted strings are C-style quoting supporting \c for
      # common escapes of 'c' (e..g \n, \t, \\, \") or \nnn where nnn
-	 # is the signed byte value in octal.  Note that the only
+     # is the signed byte value in octal.  Note that the only
      # characters which must actually be escaped to protect the
      # stream formatting is: \, " and LF.  Otherwise these values
-	 # are UTF8.
+     # are UTF8.
      #
   ref_str     ::= ref;
   sha1exp_str ::= sha1exp;
@@ -104,9 +108,9 @@
   lf ::= # ASCII newline (LF) character;
 
      # note: a colon (':') must precede the numerical value assigned to
-	 # an idnum.  This is to distinguish it from a ref or tag name as
+     # an idnum.  This is to distinguish it from a ref or tag name as
      # GIT does not permit ':' in ref or tag strings.
-	 #
+     #
   idnum   ::= ':' bigint;
   path    ::= # GIT style file path, e.g. "a/b/c";
   ref     ::= # GIT ref name, e.g. "refs/heads/MOZ_GECKO_EXPERIMENT";
@@ -115,13 +119,24 @@
   hexsha1 ::= # SHA1 in hexadecimal format;
 
      # note: name and email are UTF8 strings, however name must not
-	 # contain '<' or lf and email must not contain any of the
+     # contain '<' or lf and email must not contain any of the
      # following: '<', '>', lf.
-	 #
+     #
   name  ::= # valid GIT author/committer name;
   email ::= # valid GIT author/committer email;
   ts    ::= # time since the epoch in seconds, ascii base10 notation;
   tz    ::= # GIT style timezone;
+
+     # note: comments may appear anywhere in the input, except
+     # within a data command.  Any form of the data command
+     # always escapes the related input from comment processing.
+     #
+     # In case it is not clear, the '#' that starts the comment
+     # must be the first character on that the line (an lf have
+     # preceeded it).
+     #
+  comment ::= '#' not_lf* lf;
+  not_lf  ::= # Any byte that is not ASCII newline (LF);
 */
 
 #include "builtin.h"
@@ -254,6 +269,13 @@
 	WHENSPEC_NOW,
 } whenspec_type;
 
+struct recent_command
+{
+	struct recent_command *prev;
+	struct recent_command *next;
+	char *buf;
+};
+
 /* Configured limits on output */
 static unsigned long max_depth = 10;
 static off_t max_packsize = (1LL << 32) - 1;
@@ -319,9 +341,120 @@
 /* Input stream parsing */
 static whenspec_type whenspec = WHENSPEC_RAW;
 static struct strbuf command_buf;
+static int unread_command_buf;
+static struct recent_command cmd_hist = {&cmd_hist, &cmd_hist, NULL};
+static struct recent_command *cmd_tail = &cmd_hist;
+static struct recent_command *rc_free;
+static unsigned int cmd_save = 100;
 static uintmax_t next_mark;
 static struct dbuf new_data;
 
+static void write_branch_report(FILE *rpt, struct branch *b)
+{
+	fprintf(rpt, "%s:\n", b->name);
+
+	fprintf(rpt, "  status      :");
+	if (b->active)
+		fputs(" active", rpt);
+	if (b->branch_tree.tree)
+		fputs(" loaded", rpt);
+	if (is_null_sha1(b->branch_tree.versions[1].sha1))
+		fputs(" dirty", rpt);
+	fputc('\n', rpt);
+
+	fprintf(rpt, "  tip commit  : %s\n", sha1_to_hex(b->sha1));
+	fprintf(rpt, "  old tree    : %s\n", sha1_to_hex(b->branch_tree.versions[0].sha1));
+	fprintf(rpt, "  cur tree    : %s\n", sha1_to_hex(b->branch_tree.versions[1].sha1));
+	fprintf(rpt, "  commit clock: %" PRIuMAX "\n", b->last_commit);
+
+	fputs("  last pack   : ", rpt);
+	if (b->pack_id < MAX_PACK_ID)
+		fprintf(rpt, "%u", b->pack_id);
+	fputc('\n', rpt);
+
+	fputc('\n', rpt);
+}
+
+static void write_crash_report(const char *err)
+{
+	char *loc = git_path("fast_import_crash_%d", getpid());
+	FILE *rpt = fopen(loc, "w");
+	struct branch *b;
+	unsigned long lu;
+	struct recent_command *rc;
+
+	if (!rpt) {
+		error("can't write crash report %s: %s", loc, strerror(errno));
+		return;
+	}
+
+	fprintf(stderr, "fast-import: dumping crash report to %s\n", loc);
+
+	fprintf(rpt, "fast-import crash report:\n");
+	fprintf(rpt, "    fast-import process: %d\n", getpid());
+	fprintf(rpt, "    parent process     : %d\n", getppid());
+	fprintf(rpt, "    at %s\n", show_date(time(NULL), 0, DATE_LOCAL));
+	fputc('\n', rpt);
+
+	fputs("fatal: ", rpt);
+	fputs(err, rpt);
+	fputc('\n', rpt);
+
+	fputc('\n', rpt);
+	fputs("Most Recent Commands Before Crash\n", rpt);
+	fputs("---------------------------------\n", rpt);
+	for (rc = cmd_hist.next; rc != &cmd_hist; rc = rc->next) {
+		if (rc->next == &cmd_hist)
+			fputs("* ", rpt);
+		else
+			fputs("  ", rpt);
+		fputs(rc->buf, rpt);
+		fputc('\n', rpt);
+	}
+
+	fputc('\n', rpt);
+	fputs("Active Branch LRU\n", rpt);
+	fputs("-----------------\n", rpt);
+	fprintf(rpt, "    active_branches = %lu cur, %lu max\n",
+		cur_active_branches,
+		max_active_branches);
+	fputc('\n', rpt);
+	fputs("  pos  clock name\n", rpt);
+	fputs("  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", rpt);
+	for (b = active_branches, lu = 0; b; b = b->active_next_branch)
+		fprintf(rpt, "  %2lu) %6" PRIuMAX" %s\n",
+			++lu, b->last_commit, b->name);
+
+	fputc('\n', rpt);
+	fputs("Inactive Branches\n", rpt);
+	fputs("-----------------\n", rpt);
+	for (lu = 0; lu < branch_table_sz; lu++) {
+		for (b = branch_table[lu]; b; b = b->table_next_branch)
+			write_branch_report(rpt, b);
+	}
+
+	fputc('\n', rpt);
+	fputs("-------------------\n", rpt);
+	fputs("END OF CRASH REPORT\n", rpt);
+	fclose(rpt);
+}
+
+static NORETURN void die_nicely(const char *err, va_list params)
+{
+	static int zombie;
+	char message[2 * PATH_MAX];
+
+	vsnprintf(message, sizeof(message), err, params);
+	fputs("fatal: ", stderr);
+	fputs(message, stderr);
+	fputc('\n', stderr);
+
+	if (!zombie) {
+		zombie = 1;
+		write_crash_report(message);
+	}
+	exit(128);
+}
 
 static void alloc_objects(unsigned int cnt)
 {
@@ -524,8 +657,12 @@
 
 	if (b)
 		die("Invalid attempt to create duplicate branch: %s", name);
-	if (check_ref_format(name))
+	switch (check_ref_format(name)) {
+	case  0: break; /* its valid */
+	case -2: break; /* valid, but too few '/', allow anyway */
+	default:
 		die("Branch name doesn't conform to GIT standards: %s", name);
+	}
 
 	b = pool_calloc(1, sizeof(struct branch));
 	b->name = pool_strdup(name);
@@ -1450,7 +1587,43 @@
 
 static void read_next_command(void)
 {
-	read_line(&command_buf, stdin, '\n');
+	do {
+		if (unread_command_buf) {
+			unread_command_buf = 0;
+			if (command_buf.eof)
+				return;
+		} else {
+			struct recent_command *rc;
+
+			command_buf.buf = NULL;
+			read_line(&command_buf, stdin, '\n');
+			if (command_buf.eof)
+				return;
+
+			rc = rc_free;
+			if (rc)
+				rc_free = rc->next;
+			else {
+				rc = cmd_hist.next;
+				cmd_hist.next = rc->next;
+				cmd_hist.next->prev = &cmd_hist;
+				free(rc->buf);
+			}
+
+			rc->buf = command_buf.buf;
+			rc->prev = cmd_tail;
+			rc->next = cmd_hist.prev;
+			rc->prev->next = rc;
+			cmd_tail = rc;
+		}
+	} while (command_buf.buf[0] == '#');
+}
+
+static void skip_optional_lf(void)
+{
+	int term_char = fgetc(stdin);
+	if (term_char != '\n' && term_char != EOF)
+		ungetc(term_char, stdin);
 }
 
 static void cmd_mark(void)
@@ -1476,19 +1649,15 @@
 		size_t sz = 8192, term_len = command_buf.len - 5 - 2;
 		length = 0;
 		buffer = xmalloc(sz);
+		command_buf.buf = NULL;
 		for (;;) {
-			read_next_command();
+			read_line(&command_buf, stdin, '\n');
 			if (command_buf.eof)
 				die("EOF in data (terminator '%s' not found)", term);
 			if (term_len == command_buf.len
 				&& !strcmp(term, command_buf.buf))
 				break;
-			if (sz < (length + command_buf.len)) {
-				sz = sz * 3 / 2 + 16;
-				if (sz < (length + command_buf.len))
-					sz = length + command_buf.len;
-				buffer = xrealloc(buffer, sz);
-			}
+			ALLOC_GROW(buffer, length + command_buf.len, sz);
 			memcpy(buffer + length,
 				command_buf.buf,
 				command_buf.len - 1);
@@ -1510,9 +1679,7 @@
 		}
 	}
 
-	if (fgetc(stdin) != '\n')
-		die("An lf did not trail the binary data as expected.");
-
+	skip_optional_lf();
 	*size = length;
 	return buffer;
 }
@@ -1808,13 +1975,13 @@
 	}
 }
 
-static void cmd_from(struct branch *b)
+static int cmd_from(struct branch *b)
 {
 	const char *from;
 	struct branch *s;
 
 	if (prefixcmp(command_buf.buf, "from "))
-		return;
+		return 0;
 
 	if (b->branch_tree.tree) {
 		release_tree_content_recursive(b->branch_tree.tree);
@@ -1849,6 +2016,7 @@
 		die("Invalid ref name or SHA1 expression: %s", from);
 
 	read_next_command();
+	return 1;
 }
 
 static struct hash_list *cmd_merge(unsigned int *count)
@@ -1933,10 +2101,8 @@
 	}
 
 	/* file_change* */
-	for (;;) {
-		if (1 == command_buf.len)
-			break;
-		else if (!prefixcmp(command_buf.buf, "M "))
+	while (!command_buf.eof && command_buf.len > 1) {
+		if (!prefixcmp(command_buf.buf, "M "))
 			file_change_m(b);
 		else if (!prefixcmp(command_buf.buf, "D "))
 			file_change_d(b);
@@ -1946,8 +2112,10 @@
 			file_change_cr(b, 0);
 		else if (!strcmp("deleteall", command_buf.buf))
 			file_change_deleteall(b);
-		else
-			die("Unsupported file_change: %s", command_buf.buf);
+		else {
+			unread_command_buf = 1;
+			break;
+		}
 		read_next_command();
 	}
 
@@ -2088,7 +2256,8 @@
 	else
 		b = new_branch(sp);
 	read_next_command();
-	cmd_from(b);
+	if (!cmd_from(b) && command_buf.len > 1)
+		unread_command_buf = 1;
 }
 
 static void cmd_checkpoint(void)
@@ -2099,7 +2268,15 @@
 		dump_tags();
 		dump_marks();
 	}
-	read_next_command();
+	skip_optional_lf();
+}
+
+static void cmd_progress(void)
+{
+	fwrite(command_buf.buf, 1, command_buf.len - 1, stdout);
+	fputc('\n', stdout);
+	fflush(stdout);
+	skip_optional_lf();
 }
 
 static void import_marks(const char *input_file)
@@ -2142,7 +2319,7 @@
 
 int main(int argc, const char **argv)
 {
-	int i, show_stats = 1;
+	unsigned int i, show_stats = 1;
 
 	git_config(git_default_config);
 	alloc_objects(object_entry_alloc);
@@ -2196,8 +2373,14 @@
 	if (i != argc)
 		usage(fast_import_usage);
 
+	rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
+	for (i = 0; i < (cmd_save - 1); i++)
+		rc_free[i].next = &rc_free[i + 1];
+	rc_free[cmd_save - 1].next = NULL;
+
 	prepare_packed_git();
 	start_packfile();
+	set_die_routine(die_nicely);
 	for (;;) {
 		read_next_command();
 		if (command_buf.eof)
@@ -2212,6 +2395,8 @@
 			cmd_reset_branch();
 		else if (!strcmp("checkpoint", command_buf.buf))
 			cmd_checkpoint();
+		else if (!prefixcmp(command_buf.buf, "progress "))
+			cmd_progress();
 		else
 			die("Unsupported command: %s", command_buf.buf);
 	}
diff --git a/git-am.sh b/git-am.sh
index b5ed8ca..6809aa0 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -2,8 +2,10 @@
 #
 # Copyright (c) 2005, 2006 Junio C Hamano
 
-USAGE='[--signoff] [--dotest=<dir>] [--utf8 | --no-utf8] [--binary] [--3way]
-  [--interactive] [--whitespace=<option>] [-C<n>] [-p<n>] <mbox>...
+USAGE='[--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
+  [--3way] [--interactive] [--binary]
+  [--whitespace=<option>] [-C<n>] [-p<n>]
+  <mbox>|<Maildir>...
   or, when resuming [--skip | --resolved]'
 . git-sh-setup
 set_reflog_action am
diff --git a/git-archimport.perl b/git-archimport.perl
index b210772..9a7a906 100755
--- a/git-archimport.perl
+++ b/git-archimport.perl
@@ -595,7 +595,11 @@
     my $pid = open2(*READER, *WRITER,'git-commit-tree',$tree,@par)
         or die $!;
     print WRITER $ps->{summary},"\n\n";
-    print WRITER $ps->{message},"\n";
+
+    # only print message if it's not empty, to avoid a spurious blank line;
+    # also append an extra newline, so there's a blank line before the
+    # following "git-archimport-id:" line.
+    print WRITER $ps->{message},"\n\n" if ($ps->{message} ne "");
 
     # make it easy to backtrack and figure out which Arch revision this was:
     print WRITER 'git-archimport-id: ',$ps->{id},"\n";
diff --git a/git-clone.sh b/git-clone.sh
index e4a9ac4..18003ab 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -99,6 +99,7 @@
 use_separate_remote=t
 depth=
 no_progress=
+local_explicitly_asked_for=
 test -t 1 || no_progress=--no-progress
 while
 	case "$#,$1" in
@@ -109,6 +110,7 @@
 	*,--na|*,--nak|*,--nake|*,--naked|\
 	*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
 	*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
+	  local_explicitly_asked_for=yes
 	  use_local_hardlink=yes ;;
 	*,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
 	*,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
@@ -281,7 +283,8 @@
 			then
 				rm -f "$GIT_DIR/objects/sample"
 				l=l
-			else
+			elif test -n "$local_explicitly_asked_for"
+			then
 				echo >&2 "Warning: -l asked but cannot hardlink to $repo"
 			fi
 		fi &&
diff --git a/git-commit.sh b/git-commit.sh
index d7e7028..1d04f1f 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -49,10 +49,11 @@
 		export GIT_INDEX_FILE
 	fi
 
-	case "$status_only" in
-	t) color= ;;
-	*) color=--nocolor ;;
-	esac
+	if test "$status_only" = "t" -o "$use_status_color" = "t"; then
+		color=
+	else
+		color=--nocolor
+	fi
 	git runstatus ${color} \
 		${verbose:+--verbose} \
 		${amend:+--amend} \
@@ -556,6 +557,7 @@
 if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
 then
 	rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+	use_status_color=t
 	run_status
 	exit 1
 fi
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index c42e451..a4b6577 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -8,9 +8,6 @@
 # a new branch. You can specify a number of filters to modify the commits,
 # files and trees.
 
-USAGE="git-filter-branch [-d TEMPDIR] [FILTERS] DESTBRANCH [REV-RANGE]"
-. git-sh-setup
-
 warn () {
         echo "$*" >&2
 }
@@ -26,6 +23,20 @@
 	fi
 }
 
+# if you run 'skip_commit "$@"' in a commit filter, it will print
+# the (mapped) parents, effectively skipping the commit.
+
+skip_commit()
+{
+	shift;
+	while [ -n "$1" ];
+	do
+		shift;
+		map "$1";
+		shift;
+	done;
+}
+
 # override die(): this version puts in an extra line break, so that
 # the progress is still visible
 
@@ -69,6 +80,20 @@
 	echo "[ -n \"\$GIT_${uid}_NAME\" ] || export GIT_${uid}_NAME=\"\${GIT_${uid}_EMAIL%%@*}\""
 }
 
+# This script can be sourced by the commit filter to get the functions
+test "a$SOURCE_FUNCTIONS" = a1 && return
+this_script="$(cd "$(dirname "$0")"; pwd)"/$(basename "$0")
+export this_script
+
+USAGE="[--env-filter <command>] [--tree-filter <command>] \
+[--index-filter <command>] [--parent-filter <command>] \
+[--msg-filter <command>] [--commit-filter <command>] \
+[--tag-name-filter <command>] [--subdirectory-filter <directory>] \
+[--original <namespace>] [-d <directory>] [-f | --force] \
+[<rev-list options>...]"
+
+. git-sh-setup
+
 tempdir=.git-rewrite
 filter_env=
 filter_tree=
@@ -125,7 +150,7 @@
 		filter_msg="$OPTARG"
 		;;
 	--commit-filter)
-		filter_commit="$OPTARG"
+		filter_commit='SOURCE_FUNCTIONS=1 . "$this_script";'" $OPTARG"
 		;;
 	--tag-name-filter)
 		filter_tag_name="$OPTARG"
@@ -134,7 +159,7 @@
 		filter_subdir="$OPTARG"
 		;;
 	--original)
-		orig_namespace="$OPTARG"
+		orig_namespace=$(expr "$OPTARG/" : '\(.*[^/]\)/*$')/
 		;;
 	*)
 		usage
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 671b887..fa30ccc 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -62,54 +62,6 @@
 
 ######################################################################
 ##
-## configure our library
-
-set oguilib {@@GITGUI_LIBDIR@@}
-set oguirel {@@GITGUI_RELATIVE@@}
-if {$oguirel eq {1}} {
-	set oguilib [file dirname [file dirname [file normalize $argv0]]]
-	set oguilib [file join $oguilib share git-gui lib]
-} elseif {[string match @@* $oguirel]} {
-	set oguilib [file join [file dirname [file normalize $argv0]] lib]
-}
-
-set idx [file join $oguilib tclIndex]
-if {[catch {set fd [open $idx r]} err]} {
-	catch {wm withdraw .}
-	tk_messageBox \
-		-icon error \
-		-type ok \
-		-title "git-gui: fatal error" \
-		-message $err
-	exit 1
-}
-if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
-	set idx [list]
-	while {[gets $fd n] >= 0} {
-		if {$n ne {} && ![string match #* $n]} {
-			lappend idx $n
-		}
-	}
-} else {
-	set idx {}
-}
-close $fd
-
-if {$idx ne {}} {
-	set loaded [list]
-	foreach p $idx {
-		if {[lsearch -exact $loaded $p] >= 0} continue
-		source [file join $oguilib $p]
-		lappend loaded $p
-	}
-	unset loaded p
-} else {
-	set auto_path [concat [list $oguilib] $auto_path]
-}
-unset -nocomplain oguirel idx fd
-
-######################################################################
-##
 ## read only globals
 
 set _appname [lindex [file split $argv0] end]
@@ -532,7 +484,11 @@
 
 if {[catch {set _git_version [git --version]} err]} {
 	catch {wm withdraw .}
-	error_popup "Cannot determine Git version:
+	tk_messageBox \
+		-icon error \
+		-type ok \
+		-title "git-gui: fatal error" \
+		-message "Cannot determine Git version:
 
 $err
 
@@ -541,7 +497,11 @@
 }
 if {![regsub {^git version } $_git_version {} _git_version]} {
 	catch {wm withdraw .}
-	error_popup "Cannot parse Git version string:\n\n$_git_version"
+	tk_messageBox \
+		-icon error \
+		-type ok \
+		-title "git-gui: fatal error" \
+		-message "Cannot parse Git version string:\n\n$_git_version"
 	exit 1
 }
 
@@ -619,7 +579,11 @@
 
 if {[git-version < 1.5]} {
 	catch {wm withdraw .}
-	error_popup "[appname] requires Git 1.5.0 or later.
+	tk_messageBox \
+		-icon error \
+		-type ok \
+		-title "git-gui: fatal error" \
+		-message "[appname] requires Git 1.5.0 or later.
 
 You are using [git-version]:
 
@@ -629,6 +593,54 @@
 
 ######################################################################
 ##
+## configure our library
+
+set oguilib {@@GITGUI_LIBDIR@@}
+set oguirel {@@GITGUI_RELATIVE@@}
+if {$oguirel eq {1}} {
+	set oguilib [file dirname [file dirname [file normalize $argv0]]]
+	set oguilib [file join $oguilib share git-gui lib]
+} elseif {[string match @@* $oguirel]} {
+	set oguilib [file join [file dirname [file normalize $argv0]] lib]
+}
+
+set idx [file join $oguilib tclIndex]
+if {[catch {set fd [open $idx r]} err]} {
+	catch {wm withdraw .}
+	tk_messageBox \
+		-icon error \
+		-type ok \
+		-title "git-gui: fatal error" \
+		-message $err
+	exit 1
+}
+if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
+	set idx [list]
+	while {[gets $fd n] >= 0} {
+		if {$n ne {} && ![string match #* $n]} {
+			lappend idx $n
+		}
+	}
+} else {
+	set idx {}
+}
+close $fd
+
+if {$idx ne {}} {
+	set loaded [list]
+	foreach p $idx {
+		if {[lsearch -exact $loaded $p] >= 0} continue
+		source [file join $oguilib $p]
+		lappend loaded $p
+	}
+	unset loaded p
+} else {
+	set auto_path [concat [list $oguilib] $auto_path]
+}
+unset -nocomplain oguirel idx fd
+
+######################################################################
+##
 ## feature option selection
 
 if {[regexp {^git-(.+)$} [appname] _junk subcommand]} {
@@ -691,7 +703,15 @@
 	error_popup "Git directory not found:\n\n$_gitdir"
 	exit 1
 }
-if {![is_enabled bare]} {
+if {$_prefix ne {}} {
+	regsub -all {[^/]+/} $_prefix ../ cdup
+	if {[catch {cd $cdup} err]} {
+		catch {wm withdraw .}
+		error_popup "Cannot move to top of working directory:\n\n$err"
+		exit 1
+	}
+	unset cdup
+} elseif {![is_enabled bare]} {
 	if {[lindex [file split $_gitdir] end] ne {.git}} {
 		catch {wm withdraw .}
 		error_popup "Cannot use funny .git directory:\n\n$_gitdir"
@@ -726,6 +746,7 @@
 set current_branch {}
 set is_detached 0
 set current_diff_path {}
+set is_3way_diff 0
 set selected_commit_type new
 
 ######################################################################
@@ -1348,6 +1369,9 @@
 proc bind_button3 {w cmd} {
 	bind $w <Any-Button-3> $cmd
 	if {[is_MacOSX]} {
+		# Mac OS X sends Button-2 on right click through three-button mouse,
+		# or through trackpad right-clicking (two-finger touch + click).
+		bind $w <Any-Button-2> $cmd
 		bind $w <Control-Button-1> $cmd
 	}
 }
@@ -1933,6 +1957,12 @@
 }
 unset browser doc_path doc_url
 
+set root_exists 0
+bind . <Visibility> {
+	bind . <Visibility> {}
+	set root_exists 1
+}
+
 # -- Standard bindings
 #
 wm protocol . WM_DELETE_WINDOW do_quit
@@ -2407,21 +2437,26 @@
 $ctxm add command -label {Options...} \
 	-command do_options
 proc popup_diff_menu {ctxm x y X Y} {
+	global current_diff_path file_states
 	set ::cursorX $x
 	set ::cursorY $y
 	if {$::ui_index eq $::current_diff_side} {
-		$ctxm entryconf $::ui_diff_applyhunk \
-			-state normal \
-			-label {Unstage Hunk From Commit}
-	} elseif {{_O} eq [lindex $::file_states($::current_diff_path) 0]} {
-		$ctxm entryconf $::ui_diff_applyhunk \
-			-state disabled \
-			-label {Stage Hunk For Commit}
+		set s normal
+		set l "Unstage Hunk From Commit"
 	} else {
-		$ctxm entryconf $::ui_diff_applyhunk \
-			-state normal \
-			-label {Stage Hunk For Commit}
+		if {$current_diff_path eq {}
+			|| ![info exists file_states($current_diff_path)]
+			|| {_O} eq [lindex $file_states($current_diff_path) 0]} {
+			set s disabled
+		} else {
+			set s normal
+		}
+		set l "Stage Hunk For Commit"
 	}
+	if {$::is_3way_diff} {
+		set s disabled
+	}
+	$ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
 	tk_popup $ctxm $X $Y
 }
 bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]
diff --git a/git-gui/lib/class.tcl b/git-gui/lib/class.tcl
index 24e8cec..dc21411 100644
--- a/git-gui/lib/class.tcl
+++ b/git-gui/lib/class.tcl
@@ -148,11 +148,12 @@
 		}
 	}
 
-	if {[winfo ismapped .]} {
+	if {$::root_exists || [winfo ismapped .]} {
 		regsub -all {::} $this {__} w
 		set top .$w
 		set pfx $top
 		toplevel $top
+		set ::root_exists 1
 	} else {
 		set top .
 		set pfx {}
diff --git a/git-gui/lib/merge.tcl b/git-gui/lib/merge.tcl
index 5de0d82..0e50919 100644
--- a/git-gui/lib/merge.tcl
+++ b/git-gui/lib/merge.tcl
@@ -114,7 +114,7 @@
 	lappend cmd --strategy=recursive
 	lappend cmd [git fmt-merge-msg <[gitdir FETCH_HEAD]]
 	lappend cmd HEAD
-	lappend cmd $cmit
+	lappend cmd $name
 
 	set msg "Merging $current_branch and $stitle"
 	ui_status "$msg..."
diff --git a/git-merge-resolve.sh b/git-merge-resolve.sh
index bb19da2..93bcfc2 100755
--- a/git-merge-resolve.sh
+++ b/git-merge-resolve.sh
@@ -25,7 +25,7 @@
 	esac
 done
 
-# Give up if we are given more than two remotes -- not handling octopus.
+# Give up if we are given two or more remotes -- not handling octopus.
 case "$remotes" in
 ?*' '?*)
 	exit 2 ;;
diff --git a/git-merge-stupid.sh b/git-merge-stupid.sh
index 4b1e595..f612d47 100755
--- a/git-merge-stupid.sh
+++ b/git-merge-stupid.sh
@@ -24,7 +24,7 @@
 	esac
 done
 
-# Give up if we are given more than two remotes -- not handling octopus.
+# Give up if we are given two or more remotes -- not handling octopus.
 case "$remotes" in
 ?*' '?*)
 	exit 2 ;;
diff --git a/git-merge.sh b/git-merge.sh
index 5ccf282..3a01db0 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -19,10 +19,12 @@
 all_strategies='recur recursive octopus resolve stupid ours subtree'
 default_twohead_strategies='recursive'
 default_octopus_strategies='octopus'
-no_trivial_merge_strategies='ours subtree'
+no_fast_forward_strategies='subtree ours'
+no_trivial_strategies='recursive recur subtree ours'
 use_strategies=
 
-index_merge=t
+allow_fast_forward=t
+allow_trivial_merge=t
 
 dropsave() {
 	rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
@@ -265,11 +267,20 @@
 
 for s in $use_strategies
 do
-	for nt in $no_trivial_merge_strategies
+	for ss in $no_fast_forward_strategies
 	do
 		case " $s " in
-		*" $nt "*)
-			index_merge=f
+		*" $ss "*)
+			allow_fast_forward=f
+			break
+			;;
+		esac
+	done
+	for ss in $no_trivial_strategies
+	do
+		case " $s " in
+		*" $ss "*)
+			allow_trivial_merge=f
 			break
 			;;
 		esac
@@ -286,10 +297,7 @@
 esac
 echo "$head" >"$GIT_DIR/ORIG_HEAD"
 
-case "$index_merge,$#,$common,$no_commit" in
-f,*)
-	# We've been told not to try anything clever.  Skip to real merge.
-	;;
+case "$allow_fast_forward,$#,$common,$no_commit" in
 ?,*,'',*)
 	# No common ancestors found. We need a real merge.
 	;;
@@ -299,7 +307,7 @@
 	finish_up_to_date "Already up-to-date."
 	exit 0
 	;;
-?,1,"$head",*)
+t,1,"$head",*)
 	# Again the most common case of merging one remote.
 	echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
 	git update-index --refresh 2>/dev/null
@@ -322,11 +330,8 @@
 	# We are not doing octopus, not fast forward, and have only
 	# one common.
 	git update-index --refresh 2>/dev/null
-	case " $use_strategies " in
-	*' recursive '*|*' recur '*)
-		: run merge later
-		;;
-	*)
+	case "$allow_trivial_merge" in
+	t)
 		# See if it is really trivial.
 		git var GIT_COMMITTER_IDENT >/dev/null || exit
 		echo "Trying really trivial in-index merge..."
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index bdec462..abc2b1c 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -96,13 +96,14 @@
 }
 
 pick_one () {
-	case "$1" in -n) sha1=$2 ;; *) sha1=$1 ;; esac
+	no_ff=
+	case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
 	output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
 	test -d "$REWRITTEN" &&
 		pick_one_preserving_merges "$@" && return
 	parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
 	current_sha1=$(git rev-parse --verify HEAD)
-	if test $current_sha1 = $parent_sha1; then
+	if test $no_ff$current_sha1 = $parent_sha1; then
 		output git reset --hard $sha1
 		test "a$1" = a-n && output git reset --soft $current_sha1
 		sha1=$(git rev-parse --short $sha1)
@@ -189,7 +190,7 @@
 
 make_squash_message () {
 	if test -f "$SQUASH_MSG"; then
-		COUNT=$(($(sed -n "s/^# This is [^0-9]*\([0-9]\+\).*/\1/p" \
+		COUNT=$(($(sed -n "s/^# This is [^0-9]*\([1-9][0-9]*\).*/\1/p" \
 			< "$SQUASH_MSG" | tail -n 1)+1))
 		echo "# This is a combination of $COUNT commits."
 		sed -n "2,\$p" < "$SQUASH_MSG"
diff --git a/git-rebase.sh b/git-rebase.sh
index cbafa14..3bd66b0 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -59,20 +59,20 @@
 		die "$RESOLVEMSG"
 	fi
 
+	cmt=`cat $dotest/current`
 	if ! git diff-index --quiet HEAD
 	then
-		if ! git-commit -C "`cat $dotest/current`"
+		if ! git-commit -C "$cmt"
 		then
 			echo "Commit failed, please do not call \"git commit\""
 			echo "directly, but instead do one of the following: "
 			die "$RESOLVEMSG"
 		fi
-		printf "Committed: %0${prec}d" $msgnum
+		printf "Committed: %0${prec}d " $msgnum
 	else
-		printf "Already applied: %0${prec}d" $msgnum
+		printf "Already applied: %0${prec}d " $msgnum
 	fi
-	echo ' '`git rev-list --pretty=oneline -1 HEAD | \
-				sed 's/^[a-f0-9]\+ //'`
+	git rev-list --pretty=oneline -1 "$cmt" | sed -e 's/^[^ ]* //'
 
 	prev_head=`git rev-parse HEAD^0`
 	# save the resulting commit so we can read-tree on it later
diff --git a/git-send-email.perl b/git-send-email.perl
index 4767249..e0b7d12 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -21,8 +21,11 @@
 use Term::ReadLine;
 use Getopt::Long;
 use Data::Dumper;
+use Term::ANSIColor;
 use Git;
 
+$SIG{INT} = sub { print color("reset"), "\n"; exit };
+
 package FakeTerm;
 sub new {
 	my ($class, $reason) = @_;
diff --git a/git-submodule.sh b/git-submodule.sh
index 2cfeadd..3320998 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -313,7 +313,7 @@
 ,,1,,)
 	modules_update "$@"
 	;;
-,,,1,*)
+,,,*,*)
 	modules_list "$@"
 	;;
 *)
diff --git a/git-svn.perl b/git-svn.perl
index d162114..d3c8cd0 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -77,11 +77,12 @@
 		   \$Git::SVN::_repack_flags,
 		%remote_opts );
 
-my ($_trunk, $_tags, $_branches);
+my ($_trunk, $_tags, $_branches, $_stdlayout);
 my %icv;
 my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared,
                   'trunk|T=s' => \$_trunk, 'tags|t=s' => \$_tags,
                   'branches|b=s' => \$_branches, 'prefix=s' => \$_prefix,
+                  'stdlayout|s' => \$_stdlayout,
                   'minimize-url|m' => \$Git::SVN::_minimize_url,
 		  'no-metadata' => sub { $icv{noMetadata} = 1 },
 		  'use-svm-props' => sub { $icv{useSvmProps} = 1 },
@@ -292,7 +293,8 @@
 sub cmd_clone {
 	my ($url, $path) = @_;
 	if (!defined $path &&
-	    (defined $_trunk || defined $_branches || defined $_tags) &&
+	    (defined $_trunk || defined $_branches || defined $_tags ||
+	     defined $_stdlayout) &&
 	    $url !~ m#^[a-z\+]+://#) {
 		$path = $url;
 	}
@@ -302,6 +304,11 @@
 }
 
 sub cmd_init {
+	if (defined $_stdlayout) {
+		$_trunk = 'trunk' if (!defined $_trunk);
+		$_tags = 'tags' if (!defined $_tags);
+		$_branches = 'branches' if (!defined $_branches);
+	}
 	if (defined $_trunk || defined $_branches || defined $_tags) {
 		return cmd_multi_init(@_);
 	}
@@ -370,12 +377,19 @@
 	$head ||= 'HEAD';
 	my @refs;
 	my ($url, $rev, $uuid, $gs) = working_head_info($head, \@refs);
+	print "Committing to $url ...\n";
 	unless ($gs) {
 		die "Unable to determine upstream SVN information from ",
 		    "$head history\n";
 	}
 	my $last_rev;
 	my ($linear_refs, $parents) = linearize_history($gs, \@refs);
+	if ($_no_rebase && scalar(@$linear_refs) > 1) {
+		warn "Attempting to commit more than one change while ",
+		     "--no-rebase is enabled.\n",
+		     "If these changes depend on each other, re-running ",
+		     "without --no-rebase will be required."
+	}
 	foreach my $d (@$linear_refs) {
 		unless (defined $last_rev) {
 			(undef, $last_rev, undef) = cmt_metadata("$d~1");
@@ -387,6 +401,7 @@
 		if ($_dry_run) {
 			print "diff-tree $d~1 $d\n";
 		} else {
+			my $cmt_rev;
 			my %ed_opts = ( r => $last_rev,
 			                log => get_commit_entry($d)->{log},
 			                ra => Git::SVN::Ra->new($gs->full_url),
@@ -394,42 +409,39 @@
 			                tree_b => $d,
 			                editor_cb => sub {
 			                       print "Committed r$_[0]\n";
-			                       $last_rev = $_[0]; },
+			                       $cmt_rev = $_[0];
+			                },
 			                svn_path => '');
 			if (!SVN::Git::Editor->new(\%ed_opts)->apply_diff) {
 				print "No changes\n$d~1 == $d\n";
 			} elsif ($parents->{$d} && @{$parents->{$d}}) {
-				$gs->{inject_parents_dcommit}->{$last_rev} =
+				$gs->{inject_parents_dcommit}->{$cmt_rev} =
 				                               $parents->{$d};
 			}
+			$_fetch_all ? $gs->fetch_all : $gs->fetch;
+			next if $_no_rebase;
+
+			# we always want to rebase against the current HEAD,
+			# not any head that was passed to us
+			my @diff = command('diff-tree', 'HEAD',
+			                   $gs->refname, '--');
+			my @finish;
+			if (@diff) {
+				@finish = rebase_cmd();
+				print STDERR "W: HEAD and ", $gs->refname,
+				             " differ, using @finish:\n",
+				             "@diff";
+			} else {
+				print "No changes between current HEAD and ",
+				      $gs->refname,
+				      "\nResetting to the latest ",
+				      $gs->refname, "\n";
+				@finish = qw/reset --mixed/;
+			}
+			command_noisy(@finish, $gs->refname);
+			$last_rev = $cmt_rev;
 		}
 	}
-	return if $_dry_run;
-	unless ($gs) {
-		warn "Could not determine fetch information for $url\n",
-		     "Will not attempt to fetch and rebase commits.\n",
-		     "This probably means you have useSvmProps and should\n",
-		     "now resync your SVN::Mirror repository.\n";
-		return;
-	}
-	$_fetch_all ? $gs->fetch_all : $gs->fetch;
-	unless ($_no_rebase) {
-		# we always want to rebase against the current HEAD, not any
-		# head that was passed to us
-		my @diff = command('diff-tree', 'HEAD', $gs->refname, '--');
-		my @finish;
-		if (@diff) {
-			@finish = rebase_cmd();
-			print STDERR "W: HEAD and ", $gs->refname, " differ, ",
-				     "using @finish:\n", "@diff";
-		} else {
-			print "No changes between current HEAD and ",
-			      $gs->refname, "\nResetting to the latest ",
-			      $gs->refname, "\n";
-			@finish = qw/reset --mixed/;
-		}
-		command_noisy(@finish, $gs->refname);
-	}
 }
 
 sub cmd_find_rev {
@@ -799,7 +811,7 @@
 
 sub working_head_info {
 	my ($head, $refs) = @_;
-	my ($fh, $ctx) = command_output_pipe('log', $head);
+	my ($fh, $ctx) = command_output_pipe('log', '--no-color', $head);
 	my $hash;
 	my %max;
 	while (<$fh>) {
@@ -2064,7 +2076,7 @@
 		return;
 	}
 	print "Rebuilding $db_path ...\n";
-	my ($log, $ctx) = command_output_pipe("log", $self->refname);
+	my ($log, $ctx) = command_output_pipe("log", '--no-color', $self->refname);
 	my $latest;
 	my $full_url = $self->full_url;
 	remove_username($full_url);
diff --git a/git.c b/git.c
index cab0e72..fd3d83c 100644
--- a/git.c
+++ b/git.c
@@ -4,7 +4,7 @@
 #include "quote.h"
 
 const char git_usage_string[] =
-	"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
+	"git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
 
 static void prepend_to_path(const char *dir, int len)
 {
@@ -58,6 +58,10 @@
 			}
 		} else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
 			setup_pager();
+		} else if (!strcmp(cmd, "--no-pager")) {
+			setenv("GIT_PAGER", "cat", 1);
+			if (envchanged)
+				*envchanged = 1;
 		} else if (!strcmp(cmd, "--git-dir")) {
 			if (*argc < 2) {
 				fprintf(stderr, "No directory given for --git-dir.\n" );
@@ -89,7 +93,8 @@
 				*envchanged = 1;
 		} else if (!strcmp(cmd, "--bare")) {
 			static char git_dir[PATH_MAX+1];
-			setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);
+			is_bare_repository_cfg = 1;
+			setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 0);
 			if (envchanged)
 				*envchanged = 1;
 		} else {
diff --git a/gitk b/gitk
index 57617d5..300fdce 100755
--- a/gitk
+++ b/gitk
@@ -519,6 +519,7 @@
     global textfont mainfont uifont tabstop
     global findtype findtypemenu findloc findstring fstring geometry
     global entries sha1entry sha1string sha1but
+    global diffcontextstring diffcontext
     global maincursor textcursor curtextcursor
     global rowctxmenu fakerowmenu mergemax wrapcomment
     global highlight_files gdttype
@@ -532,6 +533,7 @@
     menu .bar.file
     .bar.file add command -label "Update" -command updatecommits
     .bar.file add command -label "Reread references" -command rereadrefs
+    .bar.file add command -label "List references" -command showrefs
     .bar.file add command -label "Quit" -command doquit
     .bar.file configure -font $uifont
     menu .bar.edit
@@ -733,7 +735,17 @@
 	-command changediffdisp -variable diffelide -value {0 1}
     radiobutton .bleft.mid.new -text "New version" \
 	-command changediffdisp -variable diffelide -value {1 0}
+    label .bleft.mid.labeldiffcontext -text "      Lines of context: " \
+	-font $uifont
     pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left
+    spinbox .bleft.mid.diffcontext -width 5 -font $textfont \
+	-from 1 -increment 1 -to 10000000 \
+	-validate all -validatecommand "diffcontextvalidate %P" \
+	-textvariable diffcontextstring
+    .bleft.mid.diffcontext set $diffcontext
+    trace add variable diffcontextstring write diffcontextchange
+    lappend entries .bleft.mid.diffcontext
+    pack .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
     set ctext .bleft.ctext
     text $ctext -background $bgcolor -foreground $fgcolor \
 	-tabs "[expr {$tabstop * $charspc}]" \
@@ -1001,8 +1013,8 @@
     global stuffsaved findmergefiles maxgraphpct
     global maxwidth showneartags showlocalchanges
     global viewname viewfiles viewargs viewperm nextviewnum
-    global cmitmode wrapcomment
-    global colors bgcolor fgcolor diffcolors selectbgcolor
+    global cmitmode wrapcomment datetimeformat
+    global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
 
     if {$stuffsaved} return
     if {![winfo viewable .]} return
@@ -1019,10 +1031,12 @@
 	puts $f [list set wrapcomment $wrapcomment]
 	puts $f [list set showneartags $showneartags]
 	puts $f [list set showlocalchanges $showlocalchanges]
+	puts $f [list set datetimeformat $datetimeformat]
 	puts $f [list set bgcolor $bgcolor]
 	puts $f [list set fgcolor $fgcolor]
 	puts $f [list set colors $colors]
 	puts $f [list set diffcolors $diffcolors]
+	puts $f [list set diffcontext $diffcontext]
 	puts $f [list set selectbgcolor $selectbgcolor]
 
 	puts $f "set geometry(main) [wm geometry .]"
@@ -1453,6 +1467,38 @@
        0x00, 0x00};
 }
 
+image create bitmap reficon-T -background black -foreground yellow -data {
+    #define tagicon_width 13
+    #define tagicon_height 9
+    static unsigned char tagicon_bits[] = {
+       0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0xf8, 0x07,
+       0xfc, 0x07, 0xf8, 0x07, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00};
+} -maskdata {
+    #define tagicon-mask_width 13
+    #define tagicon-mask_height 9
+    static unsigned char tagicon-mask_bits[] = {
+       0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x0f, 0xfc, 0x0f,
+       0xfe, 0x0f, 0xfc, 0x0f, 0xf8, 0x0f, 0xf0, 0x0f, 0x00, 0x00};
+}
+set rectdata {
+    #define headicon_width 13
+    #define headicon_height 9
+    static unsigned char headicon_bits[] = {
+       0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xf8, 0x07,
+       0xf8, 0x07, 0xf8, 0x07, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00};
+}
+set rectmask {
+    #define headicon-mask_width 13
+    #define headicon-mask_height 9
+    static unsigned char headicon-mask_bits[] = {
+       0x00, 0x00, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f,
+       0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0xfc, 0x0f, 0x00, 0x00};
+}
+image create bitmap reficon-H -background black -foreground green \
+    -data $rectdata -maskdata $rectmask
+image create bitmap reficon-o -background black -foreground "#ddddff" \
+    -data $rectdata -maskdata $rectmask
+
 proc init_flist {first} {
     global cflist cflist_top selectedline difffilestart
 
@@ -1975,6 +2021,7 @@
     } elseif {$numcommits == 0} {
 	show_status "No commits selected"
     }
+    run refill_reflist
 }
 
 # Stuff relating to the highlighting facility
@@ -2738,13 +2785,22 @@
 proc showstuff {canshow last} {
     global numcommits commitrow pending_select selectedline curview
     global lookingforhead mainheadid displayorder selectfirst
-    global lastscrollset
+    global lastscrollset commitinterest
 
     if {$numcommits == 0} {
 	global phase
 	set phase "incrdraw"
 	allcanvs delete all
     }
+    for {set l $numcommits} {$l < $canshow} {incr l} {
+	set id [lindex $displayorder $l]
+	if {[info exists commitinterest($id)]} {
+	    foreach script $commitinterest($id) {
+		eval [string map [list "%I" $id] $script]
+	    }
+	    unset commitinterest($id)
+	}
+    }
     set r0 $numcommits
     set prev $numcommits
     set numcommits $canshow
@@ -4471,6 +4527,7 @@
     $canv delete hover
     normalline
     cancel_next_highlight
+    unsel_reflist
     if {$l < 0 || $l >= $numcommits} return
     set y [expr {$canvy0 + $l * $linespc}]
     set ymax [lindex [$canv cget -scrollregion] 3]
@@ -5052,12 +5109,29 @@
     return 0
 }
 
+# empty string or positive integer
+proc diffcontextvalidate {v} {
+    return [regexp {^(|[1-9][0-9]*)$} $v]
+}
+
+proc diffcontextchange {n1 n2 op} {
+    global diffcontextstring diffcontext
+
+    if {[string is integer -strict $diffcontextstring]} {
+	if {$diffcontextstring > 0} {
+	    set diffcontext $diffcontextstring
+	    reselectline
+	}
+    }
+}
+
 proc getblobdiffs {ids} {
     global diffopts blobdifffd diffids env
     global diffinhdr treediffs
+    global diffcontext
 
     set env(GIT_DIFF_OPTS) $diffopts
-    if {[catch {set bdf [open [diffcmd $ids {-p -C --no-commit-id}] r]} err]} {
+    if {[catch {set bdf [open [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] r]} err]} {
 	puts "error getting diffs: $err"
 	return
     }
@@ -5116,8 +5190,8 @@
 	    # the middle char will be a space, and the two bits either
 	    # side will be a/name and b/name, or "a/name" and "b/name".
 	    # If the name has changed we'll get "rename from" and
-	    # "rename to" lines following this, and we'll use them
-	    # to get the filenames.
+	    # "rename to" or "copy from" and "copy to" lines following this,
+	    # and we'll use them to get the filenames.
 	    # This complexity is necessary because spaces in the filename(s)
 	    # don't get escaped.
 	    set l [string length $line]
@@ -5141,8 +5215,9 @@
 	    set diffinhdr 0
 
 	} elseif {$diffinhdr} {
-	    if {![string compare -length 12 "rename from " $line]} {
-		set fname [string range $line 12 end]
+	    if {![string compare -length 12 "rename from " $line] ||
+		![string compare -length 10 "copy from " $line]} {
+		set fname [string range $line [expr 6 + [string first " from " $line] ] end]
 		if {[string index $fname 0] eq "\""} {
 		    set fname [lindex $fname 0]
 		}
@@ -5150,8 +5225,9 @@
 		if {$i >= 0} {
 		    setinlist difffilestart $i $curdiffstart
 		}
-	    } elseif {![string compare -length 10 $line "rename to "]} {
-		set fname [string range $line 10 end]
+	    } elseif {![string compare -length 10 $line "rename to "] ||
+		      ![string compare -length 8 $line "copy to "]} {
+		set fname [string range $line [expr 4 + [string first " to " $line] ] end]
 		if {[string index $fname 0] eq "\""} {
 		    set fname [lindex $fname 0]
 		}
@@ -5382,7 +5458,7 @@
 }
 
 proc incrfont {inc} {
-    global mainfont textfont ctext canv phase cflist
+    global mainfont textfont ctext canv phase cflist showrefstop
     global charspc tabstop
     global stopped entries
     unmarkmatches
@@ -5398,6 +5474,9 @@
     if {$phase eq "getcommits"} {
 	$canv itemconf textitems -font $mainfont
     }
+    if {[info exists showrefstop] && [winfo exists $showrefstop]} {
+	$showrefstop.list conf -font $mainfont
+    }
     redisplay
 }
 
@@ -5856,6 +5935,8 @@
     lappend idtags($id) $tag
     redrawtags $id
     addedtag $id
+    dispneartags 0
+    run refill_reflist
 }
 
 proc redrawtags {id} {
@@ -5997,6 +6078,7 @@
 	notbusy newbranch
 	redrawtags $id
 	dispneartags 0
+	run refill_reflist
     }
 }
 
@@ -6168,7 +6250,7 @@
 
 proc rmbranch {} {
     global headmenuid headmenuhead mainhead
-    global headids idheads
+    global idheads
 
     set head $headmenuhead
     set id $headmenuid
@@ -6178,7 +6260,7 @@
 	return
     }
     set dheads [descheads $id]
-    if {$dheads eq $headids($head)} {
+    if {[llength $dheads] == 1 && $idheads($dheads) eq $head} {
 	# the stuff on this branch isn't on any other branch
 	if {![confirm_popup "The commits on branch $head aren't on any other\
 			branch.\nReally delete branch $head?"]} return
@@ -6195,6 +6277,163 @@
     redrawtags $id
     notbusy rmbranch
     dispneartags 0
+    run refill_reflist
+}
+
+# Display a list of tags and heads
+proc showrefs {} {
+    global showrefstop bgcolor fgcolor selectbgcolor mainfont
+    global bglist fglist uifont reflistfilter reflist maincursor
+
+    set top .showrefs
+    set showrefstop $top
+    if {[winfo exists $top]} {
+	raise $top
+	refill_reflist
+	return
+    }
+    toplevel $top
+    wm title $top "Tags and heads: [file tail [pwd]]"
+    text $top.list -background $bgcolor -foreground $fgcolor \
+	-selectbackground $selectbgcolor -font $mainfont \
+	-xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \
+	-width 30 -height 20 -cursor $maincursor \
+	-spacing1 1 -spacing3 1 -state disabled
+    $top.list tag configure highlight -background $selectbgcolor
+    lappend bglist $top.list
+    lappend fglist $top.list
+    scrollbar $top.ysb -command "$top.list yview" -orient vertical
+    scrollbar $top.xsb -command "$top.list xview" -orient horizontal
+    grid $top.list $top.ysb -sticky nsew
+    grid $top.xsb x -sticky ew
+    frame $top.f
+    label $top.f.l -text "Filter: " -font $uifont
+    entry $top.f.e -width 20 -textvariable reflistfilter -font $uifont
+    set reflistfilter "*"
+    trace add variable reflistfilter write reflistfilter_change
+    pack $top.f.e -side right -fill x -expand 1
+    pack $top.f.l -side left
+    grid $top.f - -sticky ew -pady 2
+    button $top.close -command [list destroy $top] -text "Close" \
+	-font $uifont
+    grid $top.close -
+    grid columnconfigure $top 0 -weight 1
+    grid rowconfigure $top 0 -weight 1
+    bind $top.list <1> {break}
+    bind $top.list <B1-Motion> {break}
+    bind $top.list <ButtonRelease-1> {sel_reflist %W %x %y; break}
+    set reflist {}
+    refill_reflist
+}
+
+proc sel_reflist {w x y} {
+    global showrefstop reflist headids tagids otherrefids
+
+    if {![winfo exists $showrefstop]} return
+    set l [lindex [split [$w index "@$x,$y"] "."] 0]
+    set ref [lindex $reflist [expr {$l-1}]]
+    set n [lindex $ref 0]
+    switch -- [lindex $ref 1] {
+	"H" {selbyid $headids($n)}
+	"T" {selbyid $tagids($n)}
+	"o" {selbyid $otherrefids($n)}
+    }
+    $showrefstop.list tag add highlight $l.0 "$l.0 lineend"
+}
+
+proc unsel_reflist {} {
+    global showrefstop
+
+    if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
+    $showrefstop.list tag remove highlight 0.0 end
+}
+
+proc reflistfilter_change {n1 n2 op} {
+    global reflistfilter
+
+    after cancel refill_reflist
+    after 200 refill_reflist
+}
+
+proc refill_reflist {} {
+    global reflist reflistfilter showrefstop headids tagids otherrefids
+    global commitrow curview commitinterest
+
+    if {![info exists showrefstop] || ![winfo exists $showrefstop]} return
+    set refs {}
+    foreach n [array names headids] {
+	if {[string match $reflistfilter $n]} {
+	    if {[info exists commitrow($curview,$headids($n))]} {
+		lappend refs [list $n H]
+	    } else {
+		set commitinterest($headids($n)) {run refill_reflist}
+	    }
+	}
+    }
+    foreach n [array names tagids] {
+	if {[string match $reflistfilter $n]} {
+	    if {[info exists commitrow($curview,$tagids($n))]} {
+		lappend refs [list $n T]
+	    } else {
+		set commitinterest($tagids($n)) {run refill_reflist}
+	    }
+	}
+    }
+    foreach n [array names otherrefids] {
+	if {[string match $reflistfilter $n]} {
+	    if {[info exists commitrow($curview,$otherrefids($n))]} {
+		lappend refs [list $n o]
+	    } else {
+		set commitinterest($otherrefids($n)) {run refill_reflist}
+	    }
+	}
+    }
+    set refs [lsort -index 0 $refs]
+    if {$refs eq $reflist} return
+
+    # Update the contents of $showrefstop.list according to the
+    # differences between $reflist (old) and $refs (new)
+    $showrefstop.list conf -state normal
+    $showrefstop.list insert end "\n"
+    set i 0
+    set j 0
+    while {$i < [llength $reflist] || $j < [llength $refs]} {
+	if {$i < [llength $reflist]} {
+	    if {$j < [llength $refs]} {
+		set cmp [string compare [lindex $reflist $i 0] \
+			     [lindex $refs $j 0]]
+		if {$cmp == 0} {
+		    set cmp [string compare [lindex $reflist $i 1] \
+				 [lindex $refs $j 1]]
+		}
+	    } else {
+		set cmp -1
+	    }
+	} else {
+	    set cmp 1
+	}
+	switch -- $cmp {
+	    -1 {
+		$showrefstop.list delete "[expr {$j+1}].0" "[expr {$j+2}].0"
+		incr i
+	    }
+	    0 {
+		incr i
+		incr j
+	    }
+	    1 {
+		set l [expr {$j + 1}]
+		$showrefstop.list image create $l.0 -align baseline \
+		    -image reficon-[lindex $refs $j 1] -padx 2
+		$showrefstop.list insert $l.1 "[lindex $refs $j 0]\n"
+		incr j
+	    }
+	}
+    }
+    set reflist $refs
+    # delete last newline
+    $showrefstop.list delete end-2c end-1c
+    $showrefstop.list conf -state disabled
 }
 
 # Stuff for finding nearby tags
@@ -6402,8 +6641,9 @@
 proc addnewchild {id p} {
     global allids allparents allchildren idtags nextarc nbmp
     global arcnos arcids arctags arcout arcend arcstart archeads growing
-    global seeds
+    global seeds allcommits
 
+    if {![info exists allcommits]} return
     lappend allids $id
     set allparents($id) [list $p]
     set allchildren($id) {}
@@ -7092,6 +7332,7 @@
 	    redrawtags $id
 	}
     }
+    run refill_reflist
 }
 
 proc listrefs {id} {
@@ -7312,8 +7553,9 @@
 }
 
 proc formatdate {d} {
+    global datetimeformat
     if {$d ne {}} {
-	set d [clock format $d -format "%Y-%m-%d %H:%M:%S"]
+	set d [clock format $d -format $datetimeformat]
     }
     return $d
 }
@@ -7626,11 +7868,13 @@
 set maxrefs 20
 set maxlinelen 200
 set showlocalchanges 1
+set datetimeformat "%Y-%m-%d %H:%M:%S"
 
 set colors {green red blue magenta darkgrey brown orange}
 set bgcolor white
 set fgcolor black
 set diffcolors {red "#00a000" blue}
+set diffcontext 3
 set selectbgcolor gray85
 
 catch {source ~/.gitk}
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 096313b..1b88879 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -430,7 +430,7 @@
 	font-size: 100%;
 	font-weight: normal;
 	margin: 4px 8px;
-	position: absolute;
+	float: right;
 	top: 56px;
 	right: 12px
 }
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f282a67..b2bae1b 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -471,9 +471,6 @@
 our $searchtext = $cgi->param('s');
 our $search_regexp;
 if (defined $searchtext) {
-	if ($searchtype ne 'grep' and $searchtype ne 'pickaxe' and $searchtext =~ m/[^a-zA-Z0-9_\.\/\-\+\:\@ ]/) {
-		die_error(undef, "Invalid search parameter");
-	}
 	if (length($searchtext) < 2) {
 		die_error(undef, "At least two characters are required for search parameter");
 	}
@@ -3422,7 +3419,7 @@
 		      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
 		                        -class => "list", -title => $pr->{'descr_long'}},
 		                        esc_html($pr->{'descr'})) . "</td>\n" .
-		      "<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n";
+		      "<td><i>" . esc_html(chop_str($pr->{'owner'}, 15)) . "</i></td>\n";
 		print "<td class=\"". age_class($pr->{'age'}) . "\">" .
 		      (defined $pr->{'age_string'} ? $pr->{'age_string'} : "No commits") . "</td>\n" .
 		      "<td class=\"link\">" .
@@ -3798,7 +3795,7 @@
 	print "<div class=\"title\">&nbsp;</div>\n";
 	print "<table cellspacing=\"0\">\n" .
 	      "<tr><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
-	      "<tr><td>owner</td><td>$owner</td></tr>\n";
+	      "<tr><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
 	if (defined $cd{'rfc2822'}) {
 		print "<tr><td>last change</td><td>$cd{'rfc2822'}</td></tr>\n";
 	}
diff --git a/perl/Git.pm b/perl/Git.pm
index 8fd3611..3f4080c 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -860,7 +860,13 @@
 	if ($self->{i} >= scalar @{$self->{data}}) {
 		return undef;
 	}
-	return $self->{'data'}->[ $self->{i}++ ];
+	my $i = $self->{i};
+	if (wantarray) {
+		$self->{i} = $#{$self->{'data'}} + 1;
+		return splice(@{$self->{'data'}}, $i);
+	}
+	$self->{i} = $i + 1;
+	return $self->{'data'}->[ $i ];
 }
 
 sub CLOSE {
diff --git a/perl/Makefile.PL b/perl/Makefile.PL
index 4375161..6aecd89 100644
--- a/perl/Makefile.PL
+++ b/perl/Makefile.PL
@@ -29,5 +29,6 @@
 	VERSION_FROM    => 'Git.pm',
 	PM		=> \%pm,
 	MAKEFILE	=> 'perl.mak',
+	INSTALLSITEMAN3DIR => '$(SITEPREFIX)/share/man/man3',
 	%extra
 );
diff --git a/revision.c b/revision.c
index 7d32a89..c193c3e 100644
--- a/revision.c
+++ b/revision.c
@@ -896,7 +896,8 @@
 			continue;
 		argv[i] = NULL;
 		argc = i;
-		revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
+		if (argv[i + 1])
+			revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
 		seen_dashdash = 1;
 		break;
 	}
@@ -1277,6 +1278,9 @@
 		compile_grep_patterns(revs->grep_filter);
 	}
 
+	if (revs->reverse && revs->reflog_info)
+		die("cannot combine --reverse with --walk-reflogs");
+
 	return left;
 }
 
diff --git a/sha1_file.c b/sha1_file.c
index b219d4d..9978a58 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1570,6 +1570,10 @@
 		    (uintmax_t)base_offset, p->pack_name);
 
 	delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size);
+	if (!delta_data)
+		die("failed to unpack compressed delta"
+		    " at %"PRIuMAX" from %s",
+		    (uintmax_t)curpos, p->pack_name);
 	result = patch_delta(base, base_size,
 			     delta_data, delta_size,
 			     sizep);
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
new file mode 100755
index 0000000..b14b3ec
--- /dev/null
+++ b/t/t0001-init.sh
@@ -0,0 +1,116 @@
+#!/bin/sh
+
+test_description='git init'
+
+. ./test-lib.sh
+
+check_config () {
+	if test -d "$1" && test -f "$1/config" && test -d "$1/refs"
+	then
+		: happy
+	else
+		echo "expected a directory $1, a file $1/config and $1/refs"
+		return 1
+	fi
+	bare=$(GIT_CONFIG="$1/config" git config --bool core.bare)
+	worktree=$(GIT_CONFIG="$1/config" git config core.worktree) ||
+	worktree=unset
+
+	test "$bare" = "$2" && test "$worktree" = "$3" || {
+		echo "expected bare=$2 worktree=$3"
+		echo "     got bare=$bare worktree=$worktree"
+		return 1
+	}
+}
+
+test_expect_success 'plain' '
+	(
+		unset GIT_DIR GIT_WORK_TREE &&
+		mkdir plain &&
+		cd plain &&
+		git init
+	) &&
+	check_config plain/.git false unset
+'
+
+test_expect_success 'plain with GIT_WORK_TREE' '
+	if (
+		unset GIT_DIR &&
+		mkdir plain-wt &&
+		cd plain-wt &&
+		GIT_WORK_TREE=$(pwd) git init
+	)
+	then
+		echo Should have failed -- GIT_WORK_TREE should not be used
+		false
+	fi
+'
+
+test_expect_success 'plain bare' '
+	(
+		unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
+		mkdir plain-bare-1 &&
+		cd plain-bare-1 &&
+		git --bare init
+	) &&
+	check_config plain-bare-1 true unset
+'
+
+test_expect_success 'plain bare with GIT_WORK_TREE' '
+	if (
+		unset GIT_DIR GIT_CONFIG &&
+		mkdir plain-bare-2 &&
+		cd plain-bare-2 &&
+		GIT_WORK_TREE=$(pwd) git --bare init
+	)
+	then
+		echo Should have failed -- GIT_WORK_TREE should not be used
+		false
+	fi
+'
+
+test_expect_success 'GIT_DIR bare' '
+
+	(
+		unset GIT_CONFIG &&
+		mkdir git-dir-bare.git &&
+		GIT_DIR=git-dir-bare.git git init
+	) &&
+	check_config git-dir-bare.git true unset
+'
+
+test_expect_success 'GIT_DIR non-bare' '
+
+	(
+		unset GIT_CONFIG &&
+		mkdir non-bare &&
+		cd non-bare &&
+		GIT_DIR=.git git init
+	) &&
+	check_config non-bare/.git false unset
+'
+
+test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' '
+
+	(
+		unset GIT_CONFIG &&
+		mkdir git-dir-wt-1.git &&
+		GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init
+	) &&
+	check_config git-dir-wt-1.git false "$(pwd)"
+'
+
+test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' '
+
+	if (
+		unset GIT_CONFIG &&
+		mkdir git-dir-wt-2.git &&
+		GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init
+	)
+	then
+		echo Should have failed -- --bare should not be used
+		false
+	fi
+'
+
+test_done
diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh
new file mode 100755
index 0000000..6f8a434
--- /dev/null
+++ b/t/t0023-crlf-am.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+test_description='Test am with auto.crlf'
+
+. ./test-lib.sh
+
+cat >patchfile <<\EOF
+From 38be10072e45dd6b08ce40851e3fca60a31a340b Mon Sep 17 00:00:00 2001
+From: Marius Storm-Olsen <x@y.com>
+Date: Thu, 23 Aug 2007 13:00:00 +0200
+Subject: test1
+
+---
+ foo |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 foo
+
+diff --git a/foo b/foo
+new file mode 100644
+index 0000000000000000000000000000000000000000..5716ca5987cbf97d6bb54920bea6adde242d87e6
+--- /dev/null
++++ b/foo
+@@ -0,0 +1 @@
++bar
+EOF
+
+test_expect_success 'setup' '
+
+	git config core.autocrlf true &&
+	echo foo >bar &&
+	git add bar &&
+	test_tick &&
+	git commit -m initial
+
+'
+
+test_expect_success 'am' '
+
+	git am --binary -3 <patchfile &&
+	git diff-files --name-status --exit-code
+
+'
+
+test_done
diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh
new file mode 100755
index 0000000..34f26a8
--- /dev/null
+++ b/t/t3050-subprojects-fetch.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+test_description='fetching and pushing project with subproject'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	test_tick &&
+	mkdir -p sub && (
+		cd sub &&
+		git init &&
+		>subfile &&
+		git add subfile
+		git commit -m "subproject commit #1"
+	) &&
+	>mainfile
+	git add sub mainfile &&
+	test_tick &&
+	git commit -m "superproject commit #1"
+'
+
+test_expect_success clone '
+	git clone file://`pwd`/.git cloned &&
+	(git rev-parse HEAD; git ls-files -s) >expected &&
+	(
+		cd cloned &&
+		(git rev-parse HEAD; git ls-files -s) >../actual
+	) &&
+	diff -u expected actual
+'
+
+test_expect_success advance '
+	echo more >mainfile &&
+	git update-index --force-remove sub &&
+	mv sub/.git sub/.git-disabled &&
+	git add sub/subfile mainfile &&
+	mv sub/.git-disabled sub/.git &&
+	test_tick &&
+	git commit -m "superproject commit #2"
+'
+
+test_expect_success fetch '
+	(git rev-parse HEAD; git ls-files -s) >expected &&
+	(
+		cd cloned &&
+		git pull &&
+		(git rev-parse HEAD; git ls-files -s) >../actual
+	) &&
+	diff -u expected actual
+'
+
+test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 40d6799..718c9c1 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -264,6 +264,27 @@
 	test $one = $(git rev-parse HEAD~2)
 '
 
+test_expect_success 'interrupted squash works as expected (case 2)' '
+	for n in one two three four
+	do
+		echo $n >> conflict &&
+		git add conflict &&
+		git commit -m $n
+	done &&
+	one=$(git rev-parse HEAD~3) &&
+	! FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 &&
+	(echo one; echo four) > conflict &&
+	git add conflict &&
+	! git rebase --continue &&
+	(echo one; echo two; echo four) > conflict &&
+	git add conflict &&
+	! git rebase --continue &&
+	echo resolved > conflict &&
+	git add conflict &&
+	git rebase --continue &&
+	test $one = $(git rev-parse HEAD~2)
+'
+
 test_expect_success 'ignore patch if in upstream' '
 	HEAD=$(git rev-parse HEAD) &&
 	git checkout -b has-cherry-picked HEAD^ &&
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
new file mode 100755
index 0000000..332b2b2
--- /dev/null
+++ b/t/t3406-rebase-message.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+test_description='messages from rebase operation'
+
+. ./test-lib.sh
+
+quick_one () {
+	echo "$1" >"file$1" &&
+	git add "file$1" &&
+	test_tick &&
+	git commit -m "$1"
+}
+
+test_expect_success setup '
+	quick_one O &&
+	git branch topic &&
+	quick_one X &&
+	quick_one A &&
+	quick_one B &&
+	quick_one Y &&
+
+	git checkout topic &&
+	quick_one A &&
+	quick_one B &&
+	quick_one Z
+
+'
+
+cat >expect <<\EOF
+Already applied: 0001 A
+Already applied: 0002 B
+Committed: 0003 Z
+EOF
+
+test_expect_success 'rebase -m' '
+
+	git rebase -m master >report &&
+	sed -n -e "/^Already applied: /p" \
+		-e "/^Committed: /p" report >actual &&
+	diff -u expect actual
+
+'
+
+test_done
diff --git a/t/t6028-merge-up-to-date.sh b/t/t6028-merge-up-to-date.sh
new file mode 100755
index 0000000..f8f3e3f
--- /dev/null
+++ b/t/t6028-merge-up-to-date.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+test_description='merge fast forward and up to date'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	>file &&
+	git add file &&
+	test_tick &&
+	git commit -m initial &&
+	git tag c0 &&
+
+	echo second >file &&
+	git add file &&
+	test_tick &&
+	git commit -m second &&
+	git tag c1 &&
+	git branch test
+'
+
+test_expect_success 'merge -s recursive up-to-date' '
+
+	git reset --hard c1 &&
+	test_tick &&
+	git merge -s recursive c0 &&
+	expect=$(git rev-parse c1) &&
+	current=$(git rev-parse HEAD) &&
+	test "$expect" = "$current"
+
+'
+
+test_expect_success 'merge -s recursive fast-forward' '
+
+	git reset --hard c0 &&
+	test_tick &&
+	git merge -s recursive c1 &&
+	expect=$(git rev-parse c1) &&
+	current=$(git rev-parse HEAD) &&
+	test "$expect" = "$current"
+
+'
+
+test_expect_success 'merge -s ours up-to-date' '
+
+	git reset --hard c1 &&
+	test_tick &&
+	git merge -s ours c0 &&
+	expect=$(git rev-parse c1) &&
+	current=$(git rev-parse HEAD) &&
+	test "$expect" = "$current"
+
+'
+
+test_expect_success 'merge -s ours fast-forward' '
+
+	git reset --hard c0 &&
+	test_tick &&
+	git merge -s ours c1 &&
+	expect=$(git rev-parse c0^{tree}) &&
+	current=$(git rev-parse HEAD^{tree}) &&
+	test "$expect" = "$current"
+
+'
+
+test_expect_success 'merge -s subtree up-to-date' '
+
+	git reset --hard c1 &&
+	test_tick &&
+	git merge -s subtree c0 &&
+	expect=$(git rev-parse c1) &&
+	current=$(git rev-parse HEAD) &&
+	test "$expect" = "$current"
+
+'
+
+test_done
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index bc6e2dd..e935b20 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -138,13 +138,7 @@
 	git-filter-branch -f --commit-filter "\
 		if [ \"\$GIT_AUTHOR_NAME\" = \"B V Uips\" ];\
 		then\
-			shift;\
-			while [ -n \"\$1\" ];\
-			do\
-				shift;\
-				echo \"\$1\";\
-				shift;\
-			done;\
+			skip_commit \"\$@\";
 		else\
 			git commit-tree \"\$@\";\
 		fi" removed-author &&
@@ -159,4 +153,14 @@
 	! git filter-branch -f HEAD^
 '
 
+test_expect_success '"map" works in commit filter' '
+	git filter-branch -f --commit-filter "\
+		parent=\$(git rev-parse \$GIT_COMMIT^) &&
+		mapped=\$(map \$parent) &&
+		actual=\$(echo \"\$@\" | sed \"s/^.*-p //\") &&
+		test \$mapped = \$actual &&
+		git commit-tree \"\$@\";" master~2..master &&
+	git rev-parse --verify master
+'
+
 test_done
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index c4fa446..606d4f2 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -185,18 +185,17 @@
 EOF
 test_expect_success \
 	'listing tags with substring as pattern must print those matching' '
-	git-tag -l a > actual &&
+	git-tag -l "*a*" > actual &&
 	git diff expect actual
 '
 
 cat >expect <<EOF
 v0.2.1
 v1.0.1
-v1.1.3
 EOF
 test_expect_success \
-	'listing tags with substring as pattern must print those matching' '
-	git-tag -l .1 > actual &&
+	'listing tags with a suffix as pattern must print those matching' '
+	git-tag -l "*.1" > actual &&
 	git diff expect actual
 '
 
@@ -205,37 +204,36 @@
 t211
 EOF
 test_expect_success \
-	'listing tags with substring as pattern must print those matching' '
-	git-tag -l t21 > actual &&
+	'listing tags with a prefix as pattern must print those matching' '
+	git-tag -l "t21*" > actual &&
 	git diff expect actual
 '
 
 cat >expect <<EOF
 a1
-aa1
 EOF
 test_expect_success \
-	'listing tags using a name as pattern must print those matching' '
+	'listing tags using a name as pattern must print that one matching' '
 	git-tag -l a1 > actual &&
 	git diff expect actual
 '
 
 cat >expect <<EOF
 v1.0
-v1.0.1
 EOF
 test_expect_success \
-	'listing tags using a name as pattern must print those matching' '
+	'listing tags using a name as pattern must print that one matching' '
 	git-tag -l v1.0 > actual &&
 	git diff expect actual
 '
 
 cat >expect <<EOF
+v1.0.1
 v1.1.3
 EOF
 test_expect_success \
 	'listing tags with ? in the pattern should print those matching' '
-	git-tag -l "1.1?" > actual &&
+	git-tag -l "v1.?.?" > actual &&
 	git diff expect actual
 '
 
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index 6f132f2..79b7968 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -66,4 +66,34 @@
 	git-svn dcommit
 	"
 
+test_expect_success 'commit another change from svn side' "
+	svn co $svnrepo t.svn &&
+	cd t.svn &&
+		echo third line from svn >> file &&
+		poke file &&
+		svn commit -m 'third line from svn' &&
+	cd .. &&
+	rm -rf t.svn
+	"
+
+test_expect_failure 'multiple dcommit from git-svn will not clobber svn' "
+	git reset --hard refs/remotes/git-svn &&
+	echo new file >> new-file &&
+	git update-index --add new-file &&
+	git commit -a -m 'new file' &&
+	echo clobber > file &&
+	git commit -a -m 'clobber' &&
+	git svn dcommit
+	" || true
+
+
+test_expect_success 'check that rebase really failed' 'test -d .dotest'
+
+test_expect_success 'resolve, continue the rebase and dcommit' "
+	echo clobber and I really mean it > file &&
+	git update-index file &&
+	git rebase --continue &&
+	git svn dcommit
+	"
+
 test_done
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 6f95305..0595041 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -170,6 +170,53 @@
     'git-fast-import <input'
 rm -f .git/objects/pack_* .git/objects/index_*
 
+cat >input <<INPUT_END
+commit .badbranchname
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+corrupt
+COMMIT
+
+from refs/heads/master
+
+INPUT_END
+test_expect_failure \
+    'B: fail on invalid branch name ".badbranchname"' \
+    'git-fast-import <input'
+rm -f .git/objects/pack_* .git/objects/index_*
+
+cat >input <<INPUT_END
+commit bad[branch]name
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+corrupt
+COMMIT
+
+from refs/heads/master
+
+INPUT_END
+test_expect_failure \
+    'B: fail on invalid branch name "bad[branch]name"' \
+    'git-fast-import <input'
+rm -f .git/objects/pack_* .git/objects/index_*
+
+cat >input <<INPUT_END
+commit TEMP_TAG
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+tag base
+COMMIT
+
+from refs/heads/master
+
+INPUT_END
+test_expect_success \
+    'B: accept branch name "TEMP_TAG"' \
+    'git-fast-import <input &&
+	 test -f .git/TEMP_TAG &&
+	 test `git rev-parse master` = `git rev-parse TEMP_TAG^`'
+rm -f .git/TEMP_TAG
+
 ###
 ### series C
 ###
@@ -731,4 +778,142 @@
 	'git-fast-import <input &&
 	 test `git-rev-parse N2^{tree}` = `git-rev-parse N3^{tree}`'
 
+###
+### series O
+###
+
+cat >input <<INPUT_END
+#we will
+commit refs/heads/O1
+# -- ignore all of this text
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+# $GIT_COMMITTER_NAME has inserted here for his benefit.
+data <<COMMIT
+dirty directory copy
+COMMIT
+
+# don't forget the import blank line!
+#
+# yes, we started from our usual base of branch^0.
+# i like branch^0.
+from refs/heads/branch^0
+# and we need to reuse file2/file5 from N3 above.
+M 644 inline file2/file5
+# otherwise the tree will be different
+data <<EOF
+$file5_data
+EOF
+
+# don't forget to copy file2 to file3
+C file2 file3
+#
+# or to delete file5 from file2.
+D file2/file5
+# are we done yet?
+
+INPUT_END
+
+test_expect_success \
+	'O: comments are all skipped' \
+	'git-fast-import <input &&
+	 test `git-rev-parse N3` = `git-rev-parse O1`'
+
+cat >input <<INPUT_END
+commit refs/heads/O2
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+dirty directory copy
+COMMIT
+from refs/heads/branch^0
+M 644 inline file2/file5
+data <<EOF
+$file5_data
+EOF
+C file2 file3
+D file2/file5
+
+INPUT_END
+
+test_expect_success \
+	'O: blank lines not necessary after data commands' \
+	'git-fast-import <input &&
+	 test `git-rev-parse N3` = `git-rev-parse O2`'
+
+test_expect_success \
+	'O: repack before next test' \
+	'git repack -a -d'
+
+cat >input <<INPUT_END
+commit refs/heads/O3
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zstring
+COMMIT
+commit refs/heads/O3
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zof
+COMMIT
+checkpoint
+commit refs/heads/O3
+mark :5
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zempty
+COMMIT
+checkpoint
+commit refs/heads/O3
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zcommits
+COMMIT
+reset refs/tags/O3-2nd
+from :5
+INPUT_END
+
+cat >expect <<INPUT_END
+string
+of
+empty
+commits
+INPUT_END
+test_expect_success \
+	'O: blank lines not necessary after other commands' \
+	'git-fast-import <input &&
+	 test 8 = `find .git/objects/pack -type f | wc -l` &&
+	 test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` &&
+	 git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&
+	 git diff expect actual'
+
+cat >input <<INPUT_END
+commit refs/heads/O4
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zstring
+COMMIT
+commit refs/heads/O4
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zof
+COMMIT
+progress Two commits down, 2 to go!
+commit refs/heads/O4
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zempty
+COMMIT
+progress Three commits down, 1 to go!
+commit refs/heads/O4
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+zcommits
+COMMIT
+progress I'm done!
+INPUT_END
+test_expect_success \
+	'O: progress outputs as requested by input' \
+	'git-fast-import <input >actual &&
+	 grep "progress " <input >expect &&
+	 git diff expect actual'
+
 test_done