Merge branch 'jc/show-merge'
authorJunio C Hamano <junkio@cox.net>
Mon, 10 Jul 2006 07:53:39 +0000 (00:53 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 10 Jul 2006 07:53:39 +0000 (00:53 -0700)
* jc/show-merge:
  git log -p --merge [[--] paths...]

104 files changed:
.gitignore
Documentation/SubmittingPatches
Documentation/config.txt
Documentation/cvs-migration.txt
Documentation/diff-options.txt
Documentation/git-cvsexportcommit.txt
Documentation/git-diff-files.txt
Documentation/git-diff.txt
Documentation/git-init-db.txt
Documentation/git-mailsplit.txt
Documentation/git-merge.txt
Documentation/git-name-rev.txt
Documentation/git-p4import.txt
Documentation/git-pack-redundant.txt
Documentation/git-push.txt
Documentation/git-repo-config.txt
Documentation/git-rev-list.txt
Documentation/git-svn.txt [moved from contrib/git-svn/git-svn.txt with 99% similarity]
Documentation/git-tools.txt
Documentation/git-upload-tar.txt
Documentation/git.txt
Documentation/glossary.txt
Documentation/howto/isolate-bugs-with-bisect.txt
Documentation/howto/rebase-from-internal-branch.txt
Documentation/technical/pack-heuristics.txt
Documentation/urls.txt
INSTALL
Makefile
blame.c
builtin-add.c
builtin-apply.c
builtin-diff-files.c
builtin-diff-index.c
builtin-diff-stages.c
builtin-diff-tree.c
builtin-diff.c
builtin-grep.c
builtin-help.c
builtin-log.c
builtin-mailinfo.c
builtin-push.c
builtin-read-tree.c
builtin-rm.c
builtin-update-index.c
builtin-write-tree.c
cache.h
checkout-index.c
combine-diff.c
compat/subprocess.py
contrib/colordiff/colordiff.perl
contrib/git-svn/.gitignore [deleted file]
contrib/git-svn/Makefile [deleted file]
contrib/git-svn/t/lib-git-svn.sh [deleted file]
convert-objects.c
diff-delta.c
diff.c
diff.h
diffcore-rename.c
dir.c
fetch-clone.c
git-am.sh
git-applypatch.sh
git-archimport.perl
git-bisect.sh
git-clone.sh
git-commit.sh
git-cvsexportcommit.perl
git-cvsserver.perl
git-fetch.sh
git-instaweb.sh
git-merge-one-file.sh
git-merge-recursive.py
git-push.sh
git-quiltimport.sh
git-rebase.sh
git-send-email.perl
git-svn.perl [moved from contrib/git-svn/git-svn.perl with 99% similarity]
git.c
gitweb/gitweb.cgi
http-fetch.c
mktag.c
name-rev.c
pack-objects.c
pager.c
ppc/sha1ppc.S
read-cache.c
refs.c
server-info.c
sha1_file.c
ssh-fetch.c
t/Makefile
t/lib-git-svn.sh [new file with mode: 0644]
t/t5700-clone-reference.sh
t/t5710-info-alternate.sh
t/t6002-rev-list-bisect.sh
t/t6021-merge-criss-cross.sh
t/t9100-git-svn-basic.sh [moved from contrib/git-svn/t/t0000-contrib-git-svn.sh with 98% similarity, mode: 0755]
t/t9101-git-svn-props.sh [moved from contrib/git-svn/t/t0001-contrib-git-svn-props.sh with 100% similarity, mode: 0755]
t/t9102-git-svn-deep-rmdir.sh [moved from contrib/git-svn/t/t0002-deep-rmdir.sh with 100% similarity, mode: 0755]
t/t9103-git-svn-graft-branches.sh [moved from contrib/git-svn/t/t0003-graft-branches.sh with 100% similarity, mode: 0755]
t/t9104-git-svn-follow-parent.sh [moved from contrib/git-svn/t/t0004-follow-parent.sh with 100% similarity, mode: 0755]
t/t9105-git-svn-commit-diff.sh [moved from contrib/git-svn/t/t0005-commit-diff.sh with 100% similarity, mode: 0755]
templates/hooks--update
xdiff/xdiffi.c

index 2bcc604..52d61f3 100644 (file)
@@ -107,6 +107,7 @@ git-ssh-push
 git-ssh-upload
 git-status
 git-stripspace
+git-svn
 git-svnimport
 git-symbolic-ref
 git-tag
index 8601949..90722c2 100644 (file)
@@ -49,7 +49,7 @@ People on the git mailing list need to be able to read and
 comment on the changes you are submitting.  It is important for
 a developer to be able to "quote" your changes, using standard
 e-mail tools, so that they may comment on specific portions of
-your code.  For this reason, all patches should be submited
+your code.  For this reason, all patches should be submitted
 "inline".  WARNING: Be wary of your MUAs word-wrap
 corrupting your patch.  Do not cut-n-paste your patch; you can
 lose tabs that way if you are not careful.
index f075f19..0b434c1 100644 (file)
@@ -110,10 +110,31 @@ apply.whitespace::
        Tells `git-apply` how to handle whitespaces, in the same way
        as the '--whitespace' option. See gitlink:git-apply[1].
 
+diff.color::
+       When true (or `always`), always use colors in patch.
+       When false (or `never`), never.  When set to `auto`, use
+       colors only when the output is to the terminal.
+
+diff.color.<slot>::
+       Use customized color for diff colorization.  `<slot>`
+       specifies which part of the patch to use the specified
+       color, and is one of `plain` (context text), `meta`
+       (metainformation), `frag` (hunk header), `old` (removed
+       lines), or `new` (added lines).  The value for these
+       configuration variables can be one of: `normal`, `bold`,
+       `dim`, `ul`, `blink`, `reverse`, `reset`, `black`,
+       `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, or
+       `white`.
+
 diff.renameLimit::
        The number of files to consider when performing the copy/rename
        detection; equivalent to the git diff option '-l'.
 
+diff.renames::
+       Tells git to detect renames.  If set to any boolean value, it
+       will enable basic rename detection.  If set to "copies" or
+       "copy", it will detect copies, as well.
+
 format.headers::
        Additional email headers to include in a patch to be submitted
        by mail.  See gitlink:git-format-patch[1].
index 1fbca83..d2b0bd3 100644 (file)
@@ -93,7 +93,7 @@ machine where the repository is hosted.  If you don't want to give them a
 full shell on the machine, there is a restricted shell which only allows
 users to do git pushes and pulls; see gitlink:git-shell[1].
 
-Put all the committers should in the same group, and make the repository
+Put all the committers in the same group, and make the repository
 writable by that group:
 
 ------------------------------------------------
index f523ec2..47ba9a4 100644 (file)
@@ -4,18 +4,21 @@
 -u::
        Synonym for "-p".
 
+--raw::
+       Generate the raw format.
+
 --patch-with-raw::
-       Generate patch but keep also the default raw diff output.
+       Synonym for "-p --raw".
 
 --stat::
-       Generate a diffstat instead of a patch.
+       Generate a diffstat.
 
 --summary::
        Output a condensed summary of extended header information
        such as creations, renames and mode changes.
 
 --patch-with-stat::
-       Generate patch and prepend its diffstat.
+       Synonym for "-p --stat".
 
 -z::
        \0 line termination on output
 --name-status::
        Show only names and status of changed files.
 
+--color::
+       Show colored diff.
+
+--no-color::
+       Turn off colored diff, even when the configuration file
+       gives the default to color output.
+
+--no-renames::
+       Turn off rename detection, even when the configuration
+       file gives the default to do so.
+
 --full-index::
        Instead of the first handful characters, show full
        object name of pre- and post-image blob on the "index"
-       line when generating a patch format output.     
+       line when generating a patch format output.
+
+--binary::
+       In addition to --full-index, output "binary diff" that
+       can be applied with "git apply".
 
 --abbrev[=<n>]::
        Instead of showing the full 40-byte hexadecimal object
        Swap two inputs; that is, show differences from index or
        on-disk file to tree contents.
 
+--text::
+       Treat all files as text.
+
+-a::
+       Shorthand for "--text".
+
 For more detailed explanation on these common options, see also
 link:diffcore.html[diffcore documentation].
index 56bd3e5..27ac72d 100644 (file)
@@ -8,7 +8,7 @@ git-cvsexportcommit - Export a commit to a CVS checkout
 
 SYNOPSIS
 --------
-'git-cvsexportcommmit' [-h] [-v] [-c] [-p] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
+'git-cvsexportcommit' [-h] [-v] [-c] [-p] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
 
 
 DESCRIPTION
index 481b8b3..7248b35 100644 (file)
@@ -37,7 +37,7 @@ omit diff output for unmerged entries and just show "Unmerged".
        commit with these flags.
 
 -q::
-       Remain silent even on nonexisting files
+       Remain silent even on nonexistent files
 
 Output format
 -------------
index 7ab2080..228c4d9 100644 (file)
@@ -8,24 +8,24 @@ git-diff - Show changes between commits, commit and working tree, etc
 
 SYNOPSIS
 --------
-'git-diff' [ --diff-options ] <ent>{0,2} [<path>...]
+'git-diff' [ --diff-options ] <tree-ish>{0,2} [<path>...]
 
 DESCRIPTION
 -----------
-Show changes between two ents, an ent and the working tree, an
-ent and the index file, or the index file and the working tree.
+Show changes between two trees, a tree and the working tree, a
+tree and the index file, or the index file and the working tree.
 The combination of what is compared with what is determined by
-the number of ents given to the command.
+the number of trees given to the command.
 
-* When no <ent> is given, the working tree and the index
-  file is compared, using `git-diff-files`.
+* When no <tree-ish> is given, the working tree and the index
+  file are compared, using `git-diff-files`.
 
-* When one <ent> is given, the working tree and the named
-  tree is compared, using `git-diff-index`.  The option
+* When one <tree-ish> is given, the working tree and the named
+  tree are compared, using `git-diff-index`.  The option
   `--cached` can be given to compare the index file and
   the named tree.
 
-* When two <ent>s are given, these two trees are compared
+* When two <tree-ish>s are given, these two trees are compared
   using `git-diff-tree`.
 
 OPTIONS
index 8a150d8..0a4fc14 100644 (file)
@@ -25,7 +25,7 @@ DESCRIPTION
 -----------
 This command creates an empty git repository - basically a `.git` directory
 with subdirectories for `objects`, `refs/heads`, `refs/tags`, and
-templated files.
+template files.
 An initial `HEAD` file that references the HEAD of the master branch
 is also created.
 
index 209e36b..5a17801 100644 (file)
@@ -25,7 +25,7 @@ OPTIONS
 
 -b::
        If any file doesn't begin with a From line, assume it is a
-       single mail message instead of signalling error.
+       single mail message instead of signaling error.
 
 -d<prec>::
        Instead of the default 4 digits with leading zeros,
index 4ce799b..bebf30a 100644 (file)
@@ -83,7 +83,7 @@ your local modifications interfere with the merge, again, it
 stops before touching anything.
 
 So in the above two "failed merge" case, you do not have to
-worry about lossage of data --- you simply were not ready to do
+worry about loss of data --- you simply were not ready to do
 a merge, so no merge happened at all.  You may want to finish
 whatever you were in the middle of doing, and retry the same
 pull after you are done and ready.
index 39a1434..43f8c25 100644 (file)
@@ -26,7 +26,7 @@ OPTIONS
        List all commits reachable from all refs
 
 --stdin::
-       Read from stdin, append "(<rev_name>)" to all sha1's of name'able
+       Read from stdin, append "(<rev_name>)" to all sha1's of nameable
        commits, and pass to stdout
 
 EXAMPLE
index 0858e5e..ee9e8fa 100644 (file)
@@ -128,7 +128,7 @@ Tags
 A git tag of the form p4/xx is created for every change imported from
 the Perforce repository where xx is the Perforce changeset number.
 Therefore after the import you can use git to access any commit by its
-Perforce number, eg. git show p4/327.
+Perforce number, e.g. git show p4/327.
 
 The tag associated with the HEAD commit is also how `git-p4import`
 determines if there are new changes to incrementally import from the
@@ -143,7 +143,7 @@ may delete the tags.
 
 Notes
 -----
-You can interrupt the import (eg. ctrl-c) at any time and restart it
+You can interrupt the import (e.g. ctrl-c) at any time and restart it
 without worry.
 
 Author information is automatically determined by querying the
index 8fb0659..7d54b17 100644 (file)
@@ -29,7 +29,7 @@ OPTIONS
 
 
 --all::
-       Processes all packs. Any filenames on the commandline are ignored.
+       Processes all packs. Any filenames on the command line are ignored.
 
 --alt-odb::
        Don't require objects present in packs from alternate object
index d5b5ca1..56afd64 100644 (file)
@@ -67,7 +67,7 @@ Some short-cut notations are also supported.
 
 -f, \--force::
        Usually, the command refuses to update a remote ref that is
-       not a descendent of the local ref used to overwrite it.
+       not a descendant of the local ref used to overwrite it.
        This flag disables the check.  This can cause the
        remote repository to lose commits; use it with care.
 
index 803c0d5..b03d66f 100644 (file)
@@ -119,8 +119,8 @@ you can set the filemode to true with
 % git repo-config core.filemode true
 ------------
 
-The hypothetic proxy command entries actually have a postfix to discern
-to what URL they apply. Here is how to change the entry for kernel.org
+The hypothetical proxy command entries actually have a postfix to discern
+what URL they apply to. Here is how to change the entry for kernel.org
 to "ssh".
 
 ------------
index 6c370e1..e220842 100644 (file)
@@ -64,7 +64,7 @@ OPTIONS
 
 --objects-edge::
        Similar to `--objects`, but also print the IDs of
-       excluded commits refixed with a `-` character.  This is
+       excluded commits prefixed with a `-` character.  This is
        used by `git-pack-objects` to build 'thin' pack, which
        records objects in deltified form based on objects
        contained in these excluded commits to reduce network
similarity index 99%
rename from contrib/git-svn/git-svn.txt
rename to Documentation/git-svn.txt
index f7d3de4..7d86809 100644 (file)
@@ -224,7 +224,7 @@ Merge tracking in Subversion is lacking and doing branched development
 with Subversion is cumbersome as a result.  git-svn completely forgoes
 any automated merge/branch tracking on the Subversion side and leaves it
 entirely up to the user on the git side.  It's simply not worth it to do
-a useful translation when the the original signal is weak.
+a useful translation when the original signal is weak.
 
 TRACKING MULTIPLE REPOSITORIES OR BRANCHES
 ------------------------------------------
index d79523f..0914cbb 100644 (file)
@@ -42,7 +42,7 @@ History Viewers
 
    - *gitk* (shipped with git-core)
 
-   gitk is a simple TK GUI for browsing history of GIT repositories easily.
+   gitk is a simple Tk GUI for browsing history of GIT repositories easily.
 
 
    - *gitview*  (contrib/)
index a1019a0..394af62 100644 (file)
@@ -17,7 +17,7 @@ to the other end over the git protocol.
 
 This command is usually not invoked directly by the end user.
 The UI for the protocol is on the 'git-tar-tree' side, and the
-program pair is meant to be used to get a tar achive from a
+program pair is meant to be used to get a tar archive from a
 remote repository.
 
 
index 51f20c6..d00cc3e 100644 (file)
@@ -478,7 +478,7 @@ Configuration Mechanism
 
 Starting from 0.99.9 (actually mid 0.99.8.GIT), `.git/config` file
 is used to hold per-repository configuration options.  It is a
-simple text file modelled after `.ini` format familiar to some
+simple text file modeled after `.ini` format familiar to some
 people.  Here is an example:
 
 ------------
index 116ddb7..14449ca 100644 (file)
@@ -86,7 +86,7 @@ directory::
 ent::
        Favorite synonym to "tree-ish" by some total geeks. See
        `http://en.wikipedia.org/wiki/Ent_(Middle-earth)` for an in-depth
-       explanation.
+       explanation.  Avoid this term, not to confuse people.
 
 fast forward::
        A fast-forward is a special type of merge where you have
index edbcd4c..926bbdc 100644 (file)
@@ -28,7 +28,7 @@ Then do
 
 and at this point "git bisect" will churn for a while, and tell you what 
 the mid-point between those two commits are, and check that state out as 
-the head of the bew "bisect" branch.
+the head of the new "bisect" branch.
 
 Compile and reboot.
 
index c2d4a91..fcd64e9 100644 (file)
@@ -124,7 +124,7 @@ up your changes, along with other changes.
 
 The two commits #2' and #3' in the above picture record the same
 changes your e-mail submission for #2 and #3 contained, but
-probably with the new sign-off line added by the upsteam
+probably with the new sign-off line added by the upstream
 maintainer and definitely with different committer and ancestry
 information, they are different objects from #2 and #3 commits.
 
index 9aadd5c..103eb5d 100644 (file)
@@ -73,7 +73,7 @@ The traditional insight:
 
     <pasky> yes
 
-And Bable-like confusion flowed.
+And Babel-like confusion flowed.
 
     <njs`> oh, hmm, and I'm not sure what this sliding window means either
 
@@ -257,7 +257,7 @@ proclaim it a non-issue.  Good style too!
         (type, basename, size)).
 
         Then we walk through this list, and calculate a delta of
-        each object against the last n (tunable paramater) objects,
+        each object against the last n (tunable parameter) objects,
         and pick the smallest of these deltas.
 
 Vastly simplified, but the essence is there!
@@ -395,7 +395,7 @@ used as setup for a later optimization, which is a real word:
         do "object name->location in packfile" translation.
 
     <njs`> I'm assuming the real win for delta-ing large->small is
-        more homogenous statistics for gzip to run over?
+        more homogeneous statistics for gzip to run over?
 
         (You have to put the bytes in one place or another, but
         putting them in a larger blob wins on compression)
@@ -448,7 +448,7 @@ design options, etc.
 
         Bugs happen, but they are "simple" bugs. And bugs that
         actually get some object store detail wrong are almost always
-        so obious that they never go anywhere.
+        so obvious that they never go anywhere.
 
     <njs`> Yeah.
 
index 7477413..d60b371 100644 (file)
@@ -47,7 +47,7 @@ Then such a short-hand is specified in place of
 <repository> without <refspec> parameters on the command
 line, <refspec> specified on `Push:` lines or `Pull:`
 lines are used for `git-push` and `git-fetch`/`git-pull`,
-respectively.  Multiple `Push:` and and `Pull:` lines may
+respectively.  Multiple `Push:` and `Pull:` lines may
 be specified for additional branch mappings.
 
 The name of a file in `$GIT_DIR/branches` directory can be
diff --git a/INSTALL b/INSTALL
index f8337e2..7da2c89 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -44,7 +44,7 @@ Issues of note:
 
        - "libcurl" and "curl" executable.  git-http-fetch and
          git-fetch use them.  If you do not use http
-         transfer, you are probabaly OK if you do not have
+         transfer, you are probably OK if you do not have
          them.
 
        - expat library; git-http-push uses it for remote lock
@@ -69,7 +69,7 @@ Issues of note:
          git, and if you only use git to track other peoples work you'll
          never notice the lack of it. 
 
-        - "wish", the TCL/Tk windowing shell is used in gitk to show the
+        - "wish", the Tcl/Tk windowing shell is used in gitk to show the
           history graphically
 
        - "ssh" is used to push and pull over the net
index 202f261..e75fb13 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -33,6 +33,10 @@ all:
 # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
 # Enable it on Windows.  By default, symrefs are still used.
 #
+# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability
+# tests.  These tests take up a significant amount of the total test time
+# but are not needed unless you plan to talk to SVN repos.
+#
 # Define PPC_SHA1 environment variable when running make to make use of
 # a bundled SHA1 routine optimized for PowerPC.
 #
@@ -60,7 +64,7 @@ all:
 # Define NO_ACCURATE_DIFF if your diff program at least sometimes misses
 # a missing newline at the end of the file.
 #
-# Define NO_PYTHON if you want to loose all benefits of the recursive merge.
+# Define NO_PYTHON if you want to lose all benefits of the recursive merge.
 #
 # Define COLLISION_CHECK below if you believe that SHA1's
 # 1461501637330902918203684832716283019655932542976 hashes do not give you
@@ -134,7 +138,7 @@ SCRIPT_PERL = \
        git-shortlog.perl git-rerere.perl \
        git-annotate.perl git-cvsserver.perl \
        git-svnimport.perl git-mv.perl git-cvsexportcommit.perl \
-       git-send-email.perl
+       git-send-email.perl git-svn.perl
 
 SCRIPT_PYTHON = \
        git-merge-recursive.py
@@ -469,7 +473,7 @@ ifdef NO_ACCURATE_DIFF
        ALL_CFLAGS += -DNO_ACCURATE_DIFF
 endif
 
-# Shell quote (do not use $(call) to accomodate ancient setups);
+# Shell quote (do not use $(call) to accommodate ancient setups);
 
 SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
 
@@ -514,6 +518,7 @@ common-cmds.h: Documentation/git-*.txt
 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
        rm -f $@ $@+
        sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
+           -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \
            -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
            -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
            -e 's/@@NO_PYTHON@@/$(NO_PYTHON)/g' \
@@ -552,9 +557,9 @@ git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
            -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
            -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
            -e 's/@@NO_PYTHON@@/$(NO_PYTHON)/g' \
-           -e '/@@GITWEB_CGI@@/rgitweb/gitweb.cgi' \
+           -e '/@@GITWEB_CGI@@/r gitweb/gitweb.cgi' \
            -e '/@@GITWEB_CGI@@/d' \
-           -e '/@@GITWEB_CSS@@/rgitweb/gitweb.css' \
+           -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \
            -e '/@@GITWEB_CSS@@/d' \
            $@.sh > $@+
        chmod +x $@+
@@ -652,6 +657,7 @@ GIT-CFLAGS: .FORCE-GIT-CFLAGS
 # with that.
 
 export NO_PYTHON
+export NO_SVN_TESTS
 
 test: all
        $(MAKE) -C t/ all
diff --git a/blame.c b/blame.c
index c86e2fd..b04b8f5 100644 (file)
--- a/blame.c
+++ b/blame.c
 #define DEBUG 0
 
 static const char blame_usage[] = "[-c] [-l] [-t] [-S <revs-file>] [--] file [commit]\n"
-       "  -c, --compability Use the same output mode as git-annotate (Default: off)\n"
-       "  -l, --long        Show long commit SHA1 (Default: off)\n"
-       "  -t, --time        Show raw timestamp (Default: off)\n"
-       "  -S, --revs-file   Use revisions from revs-file instead of calling git-rev-list\n"
-       "  -h, --help        This message";
+       "  -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
+       "  -l, --long          Show long commit SHA1 (Default: off)\n"
+       "  -t, --time          Show raw timestamp (Default: off)\n"
+       "  -S, --revs-file     Use revisions from revs-file instead of calling git-rev-list\n"
+       "  -h, --help          This message";
 
 static struct commit **blame_lines;
 static int num_blame_lines;
@@ -44,8 +44,8 @@ struct util_info {
 };
 
 struct chunk {
-       int off1, len1; // ---
-       int off2, len2; // +++
+       int off1, len1; /* --- */
+       int off2, len2; /* +++ */
 };
 
 struct patch {
@@ -255,7 +255,7 @@ static void print_map(struct commit *cmit, struct commit *other)
 }
 #endif
 
-// p is a patch from commit to other.
+/* p is a patch from commit to other. */
 static void fill_line_map(struct commit *commit, struct commit *other,
                          struct patch *p)
 {
@@ -747,7 +747,7 @@ int main(int argc, const char **argv)
        const char *filename = NULL, *commit = NULL;
        char filename_buf[256];
        int sha1_len = 8;
-       int compability = 0;
+       int compatibility = 0;
        int show_raw_time = 0;
        int options = 1;
        struct commit* start_commit;
@@ -774,8 +774,8 @@ int main(int argc, const char **argv)
                                sha1_len = 40;
                                continue;
                        } else if(!strcmp(argv[i], "-c") ||
-                                 !strcmp(argv[i], "--compability")) {
-                               compability = 1;
+                                 !strcmp(argv[i], "--compatibility")) {
+                               compatibility = 1;
                                continue;
                        } else if(!strcmp(argv[i], "-t") ||
                                  !strcmp(argv[i], "--time")) {
@@ -784,7 +784,7 @@ int main(int argc, const char **argv)
                        } else if(!strcmp(argv[i], "-S")) {
                                if (i + 1 < argc &&
                                    !read_ancestry(argv[i + 1], &sha1_p)) {
-                                       compability = 1;
+                                       compatibility = 1;
                                        i++;
                                        continue;
                                }
@@ -884,7 +884,7 @@ int main(int argc, const char **argv)
                u = c->util;
                get_commit_info(c, &ci);
                fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
-               if(compability) {
+               if(compatibility) {
                        printf("\t(%10s\t%10s\t%d)", ci.author,
                               format_time(ci.author_time, ci.author_tz,
                                           show_raw_time),
index bfbbb1b..2d25698 100644 (file)
@@ -181,7 +181,7 @@ int cmd_add(int argc, const char **argv, char **envp)
 
        if (active_cache_changed) {
                if (write_cache(newfd, active_cache, active_nr) ||
-                   commit_lock_file(&lock_file))
+                   close(newfd) || commit_lock_file(&lock_file))
                        die("Unable to write new index file");
        }
 
index e9ead00..c903146 100644 (file)
 #include "delta.h"
 #include "builtin.h"
 
-//  --check turns on checking that the working tree matches the
-//    files that are being modified, but doesn't apply the patch
-//  --stat does just a diffstat, and doesn't actually apply
-//  --numstat does numeric diffstat, and doesn't actually apply
-//  --index-info shows the old and new index info for paths if available.
-//  --index updates the cache as well.
-//  --cached updates only the cache without ever touching the working tree.
-//
+/*
+ *  --check turns on checking that the working tree matches the
+ *    files that are being modified, but doesn't apply the patch
+ *  --stat does just a diffstat, and doesn't actually apply
+ *  --numstat does numeric diffstat, and doesn't actually apply
+ *  --index-info shows the old and new index info for paths if available.
+ *  --index updates the cache as well.
+ *  --cached updates only the cache without ever touching the working tree.
+ */
 static const char *prefix;
 static int prefix_length = -1;
 static int newfd = -1;
@@ -284,8 +285,8 @@ static void parse_traditional_patch(const char *first, const char *second, struc
 {
        char *name;
 
-       first += 4;     // skip "--- "
-       second += 4;    // skip "+++ "
+       first += 4;     /* skip "--- " */
+       second += 4;    /* skip "+++ " */
        if (is_dev_null(first)) {
                patch->is_new = 1;
                patch->is_delete = 0;
@@ -765,7 +766,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
                        continue;
 
                /*
-                * Make sure we don't find any unconnected patch fragmants.
+                * Make sure we don't find any unconnected patch fragments.
                 * That's a sign that we didn't find a header, and that a
                 * patch has become corrupted/broken up.
                 */
@@ -990,7 +991,7 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
         * so one line can fit up to 13 groups that would decode
         * to 52 bytes max.  The length byte 'A'-'Z' corresponds
         * to 1-26 bytes, and 'a'-'z' corresponds to 27-52 bytes.
-        * The end of binary is signalled with an empty line.
+        * The end of binary is signaled with an empty line.
         */
        int llen, used;
        struct fragment *fragment;
@@ -2323,7 +2324,7 @@ int cmd_apply(int argc, const char **argv, char **envp)
 
        if (write_index) {
                if (write_cache(newfd, active_cache, active_nr) ||
-                   commit_lock_file(&lock_file))
+                   close(newfd) || commit_lock_file(&lock_file))
                        die("Unable to write new index file");
        }
 
index a655eea..81ac2fe 100644 (file)
@@ -18,7 +18,7 @@ int cmd_diff_files(int argc, const char **argv, char **envp)
        struct rev_info rev;
        int silent = 0;
 
-       git_config(git_diff_config);
+       git_config(git_default_config); /* no "diff" UI options */
        init_revisions(&rev);
        rev.abbrev = 0;
 
index b37c9e8..a1fa1b8 100644 (file)
@@ -15,7 +15,7 @@ int cmd_diff_index(int argc, const char **argv, char **envp)
        int cached = 0;
        int i;
 
-       git_config(git_diff_config);
+       git_config(git_default_config); /* no "diff" UI options */
        init_revisions(&rev);
        rev.abbrev = 0;
 
index 30931fe..9c62702 100644 (file)
@@ -61,7 +61,7 @@ int cmd_diff_stages(int ac, const char **av, char **envp)
        const char *prefix = setup_git_directory();
        const char **pathspec = NULL;
 
-       git_config(git_diff_config);
+       git_config(git_default_config); /* no "diff" UI options */
        read_cache();
        diff_setup(&diff_options);
        while (1 < ac && av[1][0] == '-') {
index ae1cde9..b610668 100644 (file)
@@ -67,7 +67,7 @@ int cmd_diff_tree(int argc, const char **argv, char **envp)
        static struct rev_info *opt = &log_tree_opt;
        int read_stdin = 0;
 
-       git_config(git_diff_config);
+       git_config(git_default_config); /* no "diff" UI options */
        nr_sha1 = 0;
        init_revisions(opt);
        opt->abbrev = 0;
index d520c7c..ae901dd 100644 (file)
@@ -176,7 +176,7 @@ static int builtin_diff_tree(struct rev_info *revs,
                usage(builtin_diff_usage);
 
        /* We saw two trees, ent[0] and ent[1].
-        * if ent[1] is unintesting, they are swapped
+        * if ent[1] is uninteresting, they are swapped
         */
        if (ent[1].item->flags & UNINTERESTING)
                swap = 1;
@@ -250,7 +250,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
         * Other cases are errors.
         */
 
-       git_config(git_diff_config);
+       git_config(git_diff_ui_config);
        init_revisions(&rev);
 
        argc = setup_revisions(argc, argv, &rev, NULL);
index 6973c66..4c2f7df 100644 (file)
@@ -82,17 +82,47 @@ static int pathspec_matches(const char **paths, const char *name)
        return 0;
 }
 
+enum grep_pat_token {
+       GREP_PATTERN,
+       GREP_AND,
+       GREP_OPEN_PAREN,
+       GREP_CLOSE_PAREN,
+       GREP_NOT,
+       GREP_OR,
+};
+
 struct grep_pat {
        struct grep_pat *next;
        const char *origin;
        int no;
+       enum grep_pat_token token;
        const char *pattern;
        regex_t regexp;
 };
 
+enum grep_expr_node {
+       GREP_NODE_ATOM,
+       GREP_NODE_NOT,
+       GREP_NODE_AND,
+       GREP_NODE_OR,
+};
+
+struct grep_expr {
+       enum grep_expr_node node;
+       union {
+               struct grep_pat *atom;
+               struct grep_expr *unary;
+               struct {
+                       struct grep_expr *left;
+                       struct grep_expr *right;
+               } binary;
+       } u;
+};
+
 struct grep_opt {
        struct grep_pat *pattern_list;
        struct grep_pat **pattern_tail;
+       struct grep_expr *pattern_expression;
        regex_t regexp;
        unsigned linenum:1;
        unsigned invert:1;
@@ -105,43 +135,224 @@ struct grep_opt {
 #define GREP_BINARY_NOMATCH    1
 #define GREP_BINARY_TEXT       2
        unsigned binary:2;
+       unsigned extended:1;
        int regflags;
        unsigned pre_context;
        unsigned post_context;
 };
 
 static void add_pattern(struct grep_opt *opt, const char *pat,
-                       const char *origin, int no)
+                       const char *origin, int no, enum grep_pat_token t)
 {
        struct grep_pat *p = xcalloc(1, sizeof(*p));
        p->pattern = pat;
        p->origin = origin;
        p->no = no;
+       p->token = t;
        *opt->pattern_tail = p;
        opt->pattern_tail = &p->next;
        p->next = NULL;
 }
 
+static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
+{
+       int err = regcomp(&p->regexp, p->pattern, opt->regflags);
+       if (err) {
+               char errbuf[1024];
+               char where[1024];
+               if (p->no)
+                       sprintf(where, "In '%s' at %d, ",
+                               p->origin, p->no);
+               else if (p->origin)
+                       sprintf(where, "%s, ", p->origin);
+               else
+                       where[0] = 0;
+               regerror(err, &p->regexp, errbuf, 1024);
+               regfree(&p->regexp);
+               die("%s'%s': %s", where, p->pattern, errbuf);
+       }
+}
+
+#if DEBUG
+static inline void indent(int in)
+{
+       int i;
+       for (i = 0; i < in; i++) putchar(' ');
+}
+
+static void dump_pattern_exp(struct grep_expr *x, int in)
+{
+       switch (x->node) {
+       case GREP_NODE_ATOM:
+               indent(in);
+               puts(x->u.atom->pattern);
+               break;
+       case GREP_NODE_NOT:
+               indent(in);
+               puts("--not");
+               dump_pattern_exp(x->u.unary, in+1);
+               break;
+       case GREP_NODE_AND:
+               dump_pattern_exp(x->u.binary.left, in+1);
+               indent(in);
+               puts("--and");
+               dump_pattern_exp(x->u.binary.right, in+1);
+               break;
+       case GREP_NODE_OR:
+               dump_pattern_exp(x->u.binary.left, in+1);
+               indent(in);
+               puts("--or");
+               dump_pattern_exp(x->u.binary.right, in+1);
+               break;
+       }
+}
+
+static void looking_at(const char *msg, struct grep_pat **list)
+{
+       struct grep_pat *p = *list;
+       fprintf(stderr, "%s: looking at ", msg);
+       if (!p)
+               fprintf(stderr, "empty\n");
+       else
+               fprintf(stderr, "<%s>\n", p->pattern);
+}
+#else
+#define looking_at(a,b) do {} while(0)
+#endif
+
+static struct grep_expr *compile_pattern_expr(struct grep_pat **);
+static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
+{
+       struct grep_pat *p;
+       struct grep_expr *x;
+
+       looking_at("atom", list);
+
+       p = *list;
+       switch (p->token) {
+       case GREP_PATTERN: /* atom */
+               x = xcalloc(1, sizeof (struct grep_expr));
+               x->node = GREP_NODE_ATOM;
+               x->u.atom = p;
+               *list = p->next;
+               return x;
+       case GREP_OPEN_PAREN:
+               *list = p->next;
+               x = compile_pattern_expr(list);
+               if (!x)
+                       return NULL;
+               if (!*list || (*list)->token != GREP_CLOSE_PAREN)
+                       die("unmatched parenthesis");
+               *list = (*list)->next;
+               return x;
+       default:
+               return NULL;
+       }
+}
+
+static struct grep_expr *compile_pattern_not(struct grep_pat **list)
+{
+       struct grep_pat *p;
+       struct grep_expr *x;
+
+       looking_at("not", list);
+
+       p = *list;
+       switch (p->token) {
+       case GREP_NOT:
+               if (!p->next)
+                       die("--not not followed by pattern expression");
+               *list = p->next;
+               x = xcalloc(1, sizeof (struct grep_expr));
+               x->node = GREP_NODE_NOT;
+               x->u.unary = compile_pattern_not(list);
+               if (!x->u.unary)
+                       die("--not followed by non pattern expression");
+               return x;
+       default:
+               return compile_pattern_atom(list);
+       }
+}
+
+static struct grep_expr *compile_pattern_and(struct grep_pat **list)
+{
+       struct grep_pat *p;
+       struct grep_expr *x, *y, *z;
+
+       looking_at("and", list);
+
+       x = compile_pattern_not(list);
+       p = *list;
+       if (p && p->token == GREP_AND) {
+               if (!p->next)
+                       die("--and not followed by pattern expression");
+               *list = p->next;
+               y = compile_pattern_and(list);
+               if (!y)
+                       die("--and not followed by pattern expression");
+               z = xcalloc(1, sizeof (struct grep_expr));
+               z->node = GREP_NODE_AND;
+               z->u.binary.left = x;
+               z->u.binary.right = y;
+               return z;
+       }
+       return x;
+}
+
+static struct grep_expr *compile_pattern_or(struct grep_pat **list)
+{
+       struct grep_pat *p;
+       struct grep_expr *x, *y, *z;
+
+       looking_at("or", list);
+
+       x = compile_pattern_and(list);
+       p = *list;
+       if (x && p && p->token != GREP_CLOSE_PAREN) {
+               y = compile_pattern_or(list);
+               if (!y)
+                       die("not a pattern expression %s", p->pattern);
+               z = xcalloc(1, sizeof (struct grep_expr));
+               z->node = GREP_NODE_OR;
+               z->u.binary.left = x;
+               z->u.binary.right = y;
+               return z;
+       }
+       return x;
+}
+
+static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
+{
+       looking_at("expr", list);
+
+       return compile_pattern_or(list);
+}
+
 static void compile_patterns(struct grep_opt *opt)
 {
        struct grep_pat *p;
+
+       /* First compile regexps */
        for (p = opt->pattern_list; p; p = p->next) {
-               int err = regcomp(&p->regexp, p->pattern, opt->regflags);
-               if (err) {
-                       char errbuf[1024];
-                       char where[1024];
-                       if (p->no)
-                               sprintf(where, "In '%s' at %d, ",
-                                       p->origin, p->no);
-                       else if (p->origin)
-                               sprintf(where, "%s, ", p->origin);
-                       else
-                               where[0] = 0;
-                       regerror(err, &p->regexp, errbuf, 1024);
-                       regfree(&p->regexp);
-                       die("%s'%s': %s", where, p->pattern, errbuf);
-               }
+               if (p->token == GREP_PATTERN)
+                       compile_regexp(p, opt);
+               else
+                       opt->extended = 1;
        }
+
+       if (!opt->extended)
+               return;
+
+       /* Then bundle them up in an expression.
+        * A classic recursive descent parser would do.
+        */
+       p = opt->pattern_list;
+       opt->pattern_expression = compile_pattern_expr(&p);
+#if DEBUG
+       dump_pattern_exp(opt->pattern_expression, 0);
+#endif
+       if (p)
+               die("incomplete pattern expression: %s", p->pattern);
 }
 
 static char *end_of_line(char *cp, unsigned long *left)
@@ -196,6 +407,79 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match)
        }
 }
 
+static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol)
+{
+       int hit = 0;
+       regmatch_t pmatch[10];
+
+       if (!opt->fixed) {
+               regex_t *exp = &p->regexp;
+               hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
+                              pmatch, 0);
+       }
+       else {
+               hit = !fixmatch(p->pattern, bol, pmatch);
+       }
+
+       if (hit && opt->word_regexp) {
+               /* Match beginning must be either
+                * beginning of the line, or at word
+                * boundary (i.e. the last char must
+                * not be alnum or underscore).
+                */
+               if ((pmatch[0].rm_so < 0) ||
+                   (eol - bol) <= pmatch[0].rm_so ||
+                   (pmatch[0].rm_eo < 0) ||
+                   (eol - bol) < pmatch[0].rm_eo)
+                       die("regexp returned nonsense");
+               if (pmatch[0].rm_so != 0 &&
+                   word_char(bol[pmatch[0].rm_so-1]))
+                       hit = 0;
+               if (pmatch[0].rm_eo != (eol-bol) &&
+                   word_char(bol[pmatch[0].rm_eo]))
+                       hit = 0;
+       }
+       return hit;
+}
+
+static int match_expr_eval(struct grep_opt *opt,
+                          struct grep_expr *x,
+                          char *bol, char *eol)
+{
+       switch (x->node) {
+       case GREP_NODE_ATOM:
+               return match_one_pattern(opt, x->u.atom, bol, eol);
+               break;
+       case GREP_NODE_NOT:
+               return !match_expr_eval(opt, x->u.unary, bol, eol);
+       case GREP_NODE_AND:
+               return (match_expr_eval(opt, x->u.binary.left, bol, eol) &&
+                       match_expr_eval(opt, x->u.binary.right, bol, eol));
+       case GREP_NODE_OR:
+               return (match_expr_eval(opt, x->u.binary.left, bol, eol) ||
+                       match_expr_eval(opt, x->u.binary.right, bol, eol));
+       }
+       die("Unexpected node type (internal error) %d\n", x->node);
+}
+
+static int match_expr(struct grep_opt *opt, char *bol, char *eol)
+{
+       struct grep_expr *x = opt->pattern_expression;
+       return match_expr_eval(opt, x, bol, eol);
+}
+
+static int match_line(struct grep_opt *opt, char *bol, char *eol)
+{
+       struct grep_pat *p;
+       if (opt->extended)
+               return match_expr(opt, bol, eol);
+       for (p = opt->pattern_list; p; p = p->next) {
+               if (match_one_pattern(opt, p, bol, eol))
+                       return 1;
+       }
+       return 0;
+}
+
 static int grep_buffer(struct grep_opt *opt, const char *name,
                       char *buf, unsigned long size)
 {
@@ -231,46 +515,15 @@ static int grep_buffer(struct grep_opt *opt, const char *name,
                hunk_mark = "--\n";
 
        while (left) {
-               regmatch_t pmatch[10];
                char *eol, ch;
                int hit = 0;
-               struct grep_pat *p;
 
                eol = end_of_line(bol, &left);
                ch = *eol;
                *eol = 0;
 
-               for (p = opt->pattern_list; p; p = p->next) {
-                       if (!opt->fixed) {
-                               regex_t *exp = &p->regexp;
-                               hit = !regexec(exp, bol, ARRAY_SIZE(pmatch),
-                                              pmatch, 0);
-                       }
-                       else {
-                               hit = !fixmatch(p->pattern, bol, pmatch);
-                       }
+               hit = match_line(opt, bol, eol);
 
-                       if (hit && opt->word_regexp) {
-                               /* Match beginning must be either
-                                * beginning of the line, or at word
-                                * boundary (i.e. the last char must
-                                * not be alnum or underscore).
-                                */
-                               if ((pmatch[0].rm_so < 0) ||
-                                   (eol - bol) <= pmatch[0].rm_so ||
-                                   (pmatch[0].rm_eo < 0) ||
-                                   (eol - bol) < pmatch[0].rm_eo)
-                                       die("regexp returned nonsense");
-                               if (pmatch[0].rm_so != 0 &&
-                                   word_char(bol[pmatch[0].rm_so-1]))
-                                       hit = 0;
-                               if (pmatch[0].rm_eo != (eol-bol) &&
-                                   word_char(bol[pmatch[0].rm_eo]))
-                                       hit = 0;
-                       }
-                       if (hit)
-                               break;
-               }
                /* "grep -v -e foo -e bla" should list lines
                 * that do not have either, so inversion should
                 * be done outside.
@@ -452,6 +705,8 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
        char *argptr = randarg;
        struct grep_pat *p;
 
+       if (opt->extended)
+               return -1;
        len = nr = 0;
        push_arg("grep");
        if (opt->fixed)
@@ -686,7 +941,7 @@ int cmd_grep(int argc, const char **argv, char **envp)
         * pattern, but then what follows it must be zero or more
         * valid refs up to the -- (if exists), and then existing
         * paths.  If there is an explicit pattern, then the first
-        * unrecocnized non option is the beginning of the refs list
+        * unrecognized non option is the beginning of the refs list
         * that continues up to the -- (if exists), and then paths.
         */
 
@@ -813,16 +1068,36 @@ int cmd_grep(int argc, const char **argv, char **envp)
                                /* ignore empty line like grep does */
                                if (!buf[0])
                                        continue;
-                               add_pattern(&opt, strdup(buf), argv[1], ++lno);
+                               add_pattern(&opt, strdup(buf), argv[1], ++lno,
+                                           GREP_PATTERN);
                        }
                        fclose(patterns);
                        argv++;
                        argc--;
                        continue;
                }
+               if (!strcmp("--not", arg)) {
+                       add_pattern(&opt, arg, "command line", 0, GREP_NOT);
+                       continue;
+               }
+               if (!strcmp("--and", arg)) {
+                       add_pattern(&opt, arg, "command line", 0, GREP_AND);
+                       continue;
+               }
+               if (!strcmp("--or", arg))
+                       continue; /* no-op */
+               if (!strcmp("(", arg)) {
+                       add_pattern(&opt, arg, "command line", 0, GREP_OPEN_PAREN);
+                       continue;
+               }
+               if (!strcmp(")", arg)) {
+                       add_pattern(&opt, arg, "command line", 0, GREP_CLOSE_PAREN);
+                       continue;
+               }
                if (!strcmp("-e", arg)) {
                        if (1 < argc) {
-                               add_pattern(&opt, argv[1], "-e option", 0);
+                               add_pattern(&opt, argv[1], "-e option", 0,
+                                           GREP_PATTERN);
                                argv++;
                                argc--;
                                continue;
@@ -840,7 +1115,8 @@ int cmd_grep(int argc, const char **argv, char **envp)
 
                /* First unrecognized non-option token */
                if (!opt.pattern_list) {
-                       add_pattern(&opt, arg, "command line", 0);
+                       add_pattern(&opt, arg, "command line", 0,
+                                   GREP_PATTERN);
                        break;
                }
                else {
index 7470faa..335fe5f 100644 (file)
@@ -12,7 +12,7 @@
 static const char git_usage[] =
        "Usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ ARGS ]";
 
-/* most gui terms set COLUMNS (although some don't export it) */
+/* most GUI terminals set COLUMNS (although some don't export it) */
 static int term_columns(void)
 {
        char *col_string = getenv("COLUMNS");
index 698b71e..7e5cab1 100644 (file)
@@ -47,7 +47,7 @@ int cmd_whatchanged(int argc, const char **argv, char **envp)
 {
        struct rev_info rev;
 
-       git_config(git_diff_config);
+       git_config(git_diff_ui_config);
        init_revisions(&rev);
        rev.diff = 1;
        rev.diffopt.recursive = 1;
@@ -62,7 +62,7 @@ int cmd_show(int argc, const char **argv, char **envp)
 {
        struct rev_info rev;
 
-       git_config(git_diff_config);
+       git_config(git_diff_ui_config);
        init_revisions(&rev);
        rev.diff = 1;
        rev.diffopt.recursive = 1;
@@ -79,7 +79,7 @@ int cmd_log(int argc, const char **argv, char **envp)
 {
        struct rev_info rev;
 
-       git_config(git_diff_config);
+       git_config(git_diff_ui_config);
        init_revisions(&rev);
        rev.always_show_header = 1;
        cmd_log_init(argc, argv, envp, &rev);
@@ -105,7 +105,10 @@ static int git_format_config(const char *var, const char *value)
                strcat(extra_headers, value);
                return 0;
        }
-       return git_diff_config(var, value);
+       if (!strcmp(var, "diff.color")) {
+               return 0;
+       }
+       return git_diff_ui_config(var, value);
 }
 
 
index 3e40747..ac53f76 100644 (file)
@@ -348,7 +348,7 @@ static void cleanup_space(char *buf)
        }
 }
 
-static void decode_header_bq(char *it);
+static void decode_header(char *it);
 typedef int (*header_fn_t)(char *);
 struct header_def {
        const char *name;
@@ -371,7 +371,7 @@ static void check_header(char *line, struct header_def *header)
                        /* Unwrap inline B and Q encoding, and optionally
                         * normalize the meta information to utf8.
                         */
-                       decode_header_bq(line + len + 2);
+                       decode_header(line + len + 2);
                        header[i].func(line + len + 2);
                        break;
                }
@@ -566,16 +566,19 @@ static void convert_to_utf8(char *line, char *charset)
 #endif
 }
 
-static void decode_header_bq(char *it)
+static int decode_header_bq(char *it)
 {
        char *in, *out, *ep, *cp, *sp;
        char outbuf[1000];
+       int rfc2047 = 0;
 
        in = it;
        out = outbuf;
        while ((ep = strstr(in, "=?")) != NULL) {
                int sz, encoding;
                char charset_q[256], piecebuf[256];
+               rfc2047 = 1;
+
                if (in != ep) {
                        sz = ep - in;
                        memcpy(out, in, sz);
@@ -589,19 +592,19 @@ static void decode_header_bq(char *it)
                ep += 2;
                cp = strchr(ep, '?');
                if (!cp)
-                       return; /* no munging */
+                       return rfc2047; /* no munging */
                for (sp = ep; sp < cp; sp++)
                        charset_q[sp - ep] = tolower(*sp);
                charset_q[cp - ep] = 0;
                encoding = cp[1];
                if (!encoding || cp[2] != '?')
-                       return; /* no munging */
+                       return rfc2047; /* no munging */
                ep = strstr(cp + 3, "?=");
                if (!ep)
-                       return; /* no munging */
+                       return rfc2047; /* no munging */
                switch (tolower(encoding)) {
                default:
-                       return; /* no munging */
+                       return rfc2047; /* no munging */
                case 'b':
                        sz = decode_b_segment(cp + 3, piecebuf, ep);
                        break;
@@ -610,7 +613,7 @@ static void decode_header_bq(char *it)
                        break;
                }
                if (sz < 0)
-                       return;
+                       return rfc2047;
                if (metainfo_charset)
                        convert_to_utf8(piecebuf, charset_q);
                strcpy(out, piecebuf);
@@ -619,6 +622,19 @@ static void decode_header_bq(char *it)
        }
        strcpy(out, in);
        strcpy(it, outbuf);
+       return rfc2047;
+}
+
+static void decode_header(char *it)
+{
+
+       if (decode_header_bq(it))
+               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, "");
 }
 
 static void decode_transfer_encoding(char *line)
index 66b9407..31cbfd7 100644 (file)
@@ -104,7 +104,7 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
                        if (n < MAX_URI)
                                uri[n++] = strdup(s);
                        else
-                               error("more than %d URL's specified, ignoreing the rest", MAX_URI);
+                               error("more than %d URL's specified, ignoring the rest", MAX_URI);
                }
                else if (is_refspec && !has_explicit_refspec)
                        add_refspec(strdup(s));
@@ -273,7 +273,7 @@ static int do_push(const char *repo)
 int cmd_push(int argc, const char **argv, char **envp)
 {
        int i;
-       const char *repo = "origin";    // default repository
+       const char *repo = "origin";    /* default repository */
 
        for (i = 1; i < argc; i++) {
                const char *arg = argv[i];
index 9a2099d..6df5d7c 100644 (file)
@@ -43,10 +43,7 @@ struct tree_entry_list {
        const unsigned char *sha1;
 };
 
-static struct tree_entry_list df_conflict_list = {
-       .name = NULL,
-       .next = &df_conflict_list
-};
+static struct tree_entry_list df_conflict_list;
 
 typedef int (*merge_fn_t)(struct cache_entry **src);
 
@@ -333,14 +330,9 @@ static void setup_progress_signal(void)
        setitimer(ITIMER_REAL, &v, NULL);
 }
 
+static struct checkout state;
 static void check_updates(struct cache_entry **src, int nr)
 {
-       static struct checkout state = {
-               .base_dir = "",
-               .force = 1,
-               .quiet = 1,
-               .refresh_cache = 1,
-       };
        unsigned short mask = htons(CE_UPDATE);
        unsigned last_percent = 200, cnt = 0, total = 0;
 
@@ -884,6 +876,12 @@ int cmd_read_tree(int argc, const char **argv, char **envp)
        unsigned char sha1[20];
        merge_fn_t fn = NULL;
 
+       df_conflict_list.next = &df_conflict_list;
+       state.base_dir = "";
+       state.force = 1;
+       state.quiet = 1;
+       state.refresh_cache = 1;
+
        setup_git_directory();
        git_config(git_default_config);
 
@@ -1038,7 +1036,7 @@ int cmd_read_tree(int argc, const char **argv, char **envp)
        }
 
        if (write_cache(newfd, active_cache, active_nr) ||
-           commit_lock_file(&lock_file))
+           close(newfd) || commit_lock_file(&lock_file))
                die("unable to write new index file");
        return 0;
 }
index 4d56a1f..5deb811 100644 (file)
@@ -129,7 +129,7 @@ int cmd_rm(int argc, const char **argv, char **envp)
         * workspace. If we fail to remove the first one, we
         * abort the "git rm" (but once we've successfully removed
         * any file at all, we'll go ahead and commit to it all:
-        * by then we've already committed ourself and can't fail
+        * by then we've already committed ourselves and can't fail
         * in the middle)
         */
        if (force) {
@@ -147,7 +147,7 @@ int cmd_rm(int argc, const char **argv, char **envp)
 
        if (active_cache_changed) {
                if (write_cache(newfd, active_cache, active_nr) ||
-                   commit_lock_file(&lock_file))
+                   close(newfd) || commit_lock_file(&lock_file))
                        die("Unable to write new index file");
        }
 
index ef50243..1a4200d 100644 (file)
@@ -648,7 +648,7 @@ int cmd_update_index(int argc, const char **argv, char **envp)
  finish:
        if (active_cache_changed) {
                if (write_cache(newfd, active_cache, active_nr) ||
-                   commit_lock_file(lock_file))
+                   close(newfd) || commit_lock_file(lock_file))
                        die("Unable to write new index file");
        }
 
index 70e9b6f..449a4d1 100644 (file)
@@ -35,7 +35,8 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
                                      missing_ok, 0) < 0)
                        die("git-write-tree: error building trees");
                if (0 <= newfd) {
-                       if (!write_cache(newfd, active_cache, active_nr))
+                       if (!write_cache(newfd, active_cache, active_nr)
+                                       && !close(newfd))
                                commit_lock_file(lock_file);
                }
                /* Not being able to write is fine -- we are only interested
diff --git a/cache.h b/cache.h
index 7b5c91c..b5e3f8f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -382,6 +382,7 @@ extern int receive_keep_pack(int fd[2], const char *me, int quiet, int);
 
 /* pager.c */
 extern void setup_pager(void);
+extern int pager_in_use;
 
 /* base85 */
 int decode_85(char *dst, char *line, int linelen);
index ea40bc2..61152f3 100644 (file)
@@ -49,14 +49,7 @@ static int checkout_stage; /* default to checkout stage0 */
 static int to_tempfile;
 static char topath[4][MAXPATHLEN+1];
 
-static struct checkout state = {
-       .base_dir = "",
-       .base_dir_len = 0,
-       .force = 0,
-       .quiet = 0,
-       .not_new = 0,
-       .refresh_cache = 0,
-};
+static struct checkout state;
 
 static void write_tempfile_record (const char *name)
 {
@@ -177,6 +170,7 @@ int main(int argc, char **argv)
        int all = 0;
        int read_from_stdin = 0;
 
+       state.base_dir = "";
        prefix = setup_git_directory();
        git_config(git_default_config);
        prefix_length = prefix ? strlen(prefix) : 0;
@@ -311,7 +305,7 @@ int main(int argc, char **argv)
 
        if (0 <= newfd &&
            (write_cache(newfd, active_cache, active_nr) ||
-            commit_lock_file(&lock_file)))
+            close(newfd) || commit_lock_file(&lock_file)))
                die("Unable to write new index file");
        return 0;
 }
index caffb92..1bc1484 100644 (file)
@@ -320,7 +320,7 @@ static int give_context(struct sline *sline, unsigned long cnt, int num_parent)
        unsigned long i;
 
        /* Two groups of interesting lines may have a short gap of
-        * unintersting lines.  Connect such groups to give them a
+        * uninteresting lines.  Connect such groups to give them a
         * bit of context.
         *
         * We first start from what the interesting() function says,
index bbd26c7..6474eab 100644 (file)
@@ -568,7 +568,7 @@ class Popen(object):
         # Windows methods
         #
         def _get_handles(self, stdin, stdout, stderr):
-            """Construct and return tupel with IO objects:
+            """Construct and return tuple with IO objects:
             p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
             """
             if stdin == None and stdout == None and stderr == None:
@@ -635,7 +635,7 @@ class Popen(object):
 
 
         def _find_w9xpopen(self):
-            """Find and return absolut path to w9xpopen.exe"""
+            """Find and return absolute path to w9xpopen.exe"""
             w9xpopen = os.path.join(os.path.dirname(GetModuleFileName(0)),
                                     "w9xpopen.exe")
             if not os.path.exists(w9xpopen):
@@ -812,7 +812,7 @@ class Popen(object):
         # POSIX methods
         #
         def _get_handles(self, stdin, stdout, stderr):
-            """Construct and return tupel with IO objects:
+            """Construct and return tuple with IO objects:
             p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite
             """
             p2cread, p2cwrite = None, None
index 5789cfb..9566a76 100755 (executable)
@@ -110,7 +110,7 @@ foreach $config_file (@config_files) {
     }
 }
 
-# colordiff specfic options here.  Need to pre-declare if using variables
+# colordiff specific options here.  Need to pre-declare if using variables
 GetOptions(
     "no-banner" => sub { $show_banner = 0 },
     "plain-text=s" => \&set_color,
diff --git a/contrib/git-svn/.gitignore b/contrib/git-svn/.gitignore
deleted file mode 100644 (file)
index d8d87e3..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-git-svn
-git-svn.xml
-git-svn.html
-git-svn.1
diff --git a/contrib/git-svn/Makefile b/contrib/git-svn/Makefile
deleted file mode 100644 (file)
index 7c20946..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-all: git-svn
-
-prefix?=$(HOME)
-bindir=$(prefix)/bin
-mandir=$(prefix)/man
-man1=$(mandir)/man1
-INSTALL?=install
-doc_conf=../../Documentation/asciidoc.conf
--include ../../config.mak
-
-git-svn: git-svn.perl
-       cp $< $@
-       chmod +x $@
-
-install: all
-       $(INSTALL) -d -m755 $(DESTDIR)$(bindir)
-       $(INSTALL) git-svn $(DESTDIR)$(bindir)
-
-install-doc: doc
-       $(INSTALL) git-svn.1 $(DESTDIR)$(man1)
-
-doc: git-svn.1
-git-svn.1 : git-svn.xml
-       xmlto man git-svn.xml
-git-svn.xml : git-svn.txt
-       asciidoc -b docbook -d manpage \
-               -f ../../Documentation/asciidoc.conf $<
-git-svn.html : git-svn.txt
-       asciidoc -b xhtml11 -d manpage \
-               -f ../../Documentation/asciidoc.conf $<
-test: git-svn
-       cd t && for i in t????-*.sh; do $(SHELL) ./$$i $(TEST_FLAGS); done
-
-# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
-full-test:
-       $(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
-       $(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
-       $(MAKE) test GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
-                                                       LC_ALL=en_US.UTF-8
-       $(MAKE) test GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
-                                                       LC_ALL=en_US.UTF-8
-
-clean:
-       rm -f git-svn *.xml *.html *.1
diff --git a/contrib/git-svn/t/lib-git-svn.sh b/contrib/git-svn/t/lib-git-svn.sh
deleted file mode 100644 (file)
index d7f972a..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-PATH=$PWD/../:$PATH
-if test -d ../../../t
-then
-    cd ../../../t
-else
-    echo "Must be run in contrib/git-svn/t" >&2
-    exit 1
-fi
-
-. ./test-lib.sh
-
-GIT_DIR=$PWD/.git
-GIT_SVN_DIR=$GIT_DIR/svn/git-svn
-SVN_TREE=$GIT_SVN_DIR/svn-tree
-
-svnadmin >/dev/null 2>&1
-if test $? != 1
-then
-    test_expect_success 'skipping contrib/git-svn test' :
-    test_done
-    exit
-fi
-
-svn >/dev/null 2>&1
-if test $? != 1
-then
-    test_expect_success 'skipping contrib/git-svn test' :
-    test_done
-    exit
-fi
-
-svnrepo=$PWD/svnrepo
-
-set -e
-
-if svnadmin create --help | grep fs-type >/dev/null
-then
-       svnadmin create --fs-type fsfs "$svnrepo"
-else
-       svnadmin create "$svnrepo"
-fi
-
-svnrepo="file://$svnrepo/test-git-svn"
-
-
index 0fabd89..ebea8e4 100644 (file)
@@ -240,14 +240,14 @@ static void convert_date(void *buffer, unsigned long size, unsigned char *result
 {
        char *new = xmalloc(size + 100);
        unsigned long newlen = 0;
-       
-       // "tree <sha1>\n"
+
+       /* "tree <sha1>\n" */
        memcpy(new + newlen, buffer, 46);
        newlen += 46;
        buffer = (char *) buffer + 46;
        size -= 46;
 
-       // "parent <sha1>\n"
+       /* "parent <sha1>\n" */
        while (!memcmp(buffer, "parent ", 7)) {
                memcpy(new + newlen, buffer, 48);
                newlen += 48;
@@ -255,12 +255,12 @@ static void convert_date(void *buffer, unsigned long size, unsigned char *result
                size -= 48;
        }
 
-       // "author xyz <xyz> date"
+       /* "author xyz <xyz> date" */
        newlen += convert_date_line(new + newlen, &buffer, &size);
-       // "committer xyz <xyz> date"
+       /* "committer xyz <xyz> date" */
        newlen += convert_date_line(new + newlen, &buffer, &size);
 
-       // Rest
+       /* Rest */
        memcpy(new + newlen, buffer, size);
        newlen += size;
 
index 8b9172a..7da9205 100644 (file)
@@ -148,7 +148,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
                return NULL;
 
        /* Determine index hash size.  Note that indexing skips the
-          first byte to allow for optimizing the rabin polynomial
+          first byte to allow for optimizing the Rabin's polynomial
           initialization in create_delta(). */
        entries = (bufsize - 1)  / RABIN_WINDOW;
        hsize = entries / 4;
@@ -205,7 +205,7 @@ struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
 
        /*
         * Determine a limit on the number of entries in the same hash
-        * bucket.  This guard us against patological data sets causing
+        * bucket.  This guards us against pathological data sets causing
         * really bad hash distribution with most entries in the same hash
         * bucket that would bring us to O(m*n) computing costs (m and n
         * corresponding to reference and target buffer sizes).
@@ -240,7 +240,7 @@ void free_delta_index(struct delta_index *index)
 
 /*
  * The maximum size for any opcode sequence, including the initial header
- * plus rabin window plus biggest copy.
+ * plus Rabin window plus biggest copy.
  */
 #define MAX_OP_SIZE    (5 + 5 + 1 + RABIN_WINDOW + 7)
 
diff --git a/diff.c b/diff.c
index f0450a8..287a927 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -13,6 +13,7 @@
 
 static int use_size_cache;
 
+static int diff_detect_rename_default = 0;
 static int diff_rename_limit_default = -1;
 static int diff_use_color_default = 0;
 
@@ -43,12 +44,12 @@ enum color_diff {
 #define COLOR_WHITE   "\033[37m"
 
 static const char *diff_colors[] = {
-       [DIFF_RESET]    = COLOR_RESET,
-       [DIFF_PLAIN]    = COLOR_NORMAL,
-       [DIFF_METAINFO] = COLOR_BOLD,
-       [DIFF_FRAGINFO] = COLOR_CYAN,
-       [DIFF_FILE_OLD] = COLOR_RED,
-       [DIFF_FILE_NEW] = COLOR_GREEN,
+       COLOR_RESET,
+       COLOR_NORMAL,
+       COLOR_BOLD,
+       COLOR_CYAN,
+       COLOR_RED,
+       COLOR_GREEN
 };
 
 static int parse_diff_color_slot(const char *var, int ofs)
@@ -101,7 +102,13 @@ static const char *parse_diff_color_value(const char *value, const char *var)
        die("bad config value '%s' for variable '%s'", value, var);
 }
 
-int git_diff_config(const char *var, const char *value)
+/*
+ * These are to give UI layer defaults.
+ * The core-level commands such as git-diff-files should
+ * never be affected by the setting of diff.renames
+ * the user happens to have in the configuration file.
+ */
+int git_diff_ui_config(const char *var, const char *value)
 {
        if (!strcmp(var, "diff.renamelimit")) {
                diff_rename_limit_default = git_config_int(var, value);
@@ -110,8 +117,14 @@ int git_diff_config(const char *var, const char *value)
        if (!strcmp(var, "diff.color")) {
                if (!value)
                        diff_use_color_default = 1; /* bool */
-               else if (!strcasecmp(value, "auto"))
-                       diff_use_color_default = isatty(1);
+               else if (!strcasecmp(value, "auto")) {
+                       diff_use_color_default = 0;
+                       if (isatty(1) || pager_in_use) {
+                               char *term = getenv("TERM");
+                               if (term && strcmp(term, "dumb"))
+                                       diff_use_color_default = 1;
+                       }
+               }
                else if (!strcasecmp(value, "never"))
                        diff_use_color_default = 0;
                else if (!strcasecmp(value, "always"))
@@ -120,6 +133,16 @@ int git_diff_config(const char *var, const char *value)
                        diff_use_color_default = git_config_bool(var, value);
                return 0;
        }
+       if (!strcmp(var, "diff.renames")) {
+               if (!value)
+                       diff_detect_rename_default = DIFF_DETECT_RENAME;
+               else if (!strcasecmp(value, "copies") ||
+                        !strcasecmp(value, "copy"))
+                       diff_detect_rename_default = DIFF_DETECT_COPY;
+               else if (git_config_bool(var,value))
+                       diff_detect_rename_default = DIFF_DETECT_RENAME;
+               return 0;
+       }
        if (!strncmp(var, "diff.color.", 11)) {
                int slot = parse_diff_color_slot(var, 11);
                diff_colors[slot] = parse_diff_color_value(value, var);
@@ -723,7 +746,7 @@ static void builtin_diff(const char *name_a,
        if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
                die("unable to read files to diff");
 
-       if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2)) {
+       if (!o->text && (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2))) {
                /* Quite common confusing case */
                if (mf1.size == mf2.size &&
                    !memcmp(mf1.ptr, mf2.ptr, mf1.size))
@@ -1431,6 +1454,7 @@ void diff_setup(struct diff_options *options)
        options->change = diff_change;
        options->add_remove = diff_addremove;
        options->color_diff = diff_use_color_default;
+       options->detect_rename = diff_detect_rename_default;
 }
 
 int diff_setup_done(struct diff_options *options)
@@ -1561,6 +1585,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
                options->output_format |= DIFF_FORMAT_PATCH;
                options->full_index = options->binary = 1;
        }
+       else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) {
+               options->text = 1;
+       }
        else if (!strcmp(arg, "--name-only"))
                options->output_format |= DIFF_FORMAT_NAME;
        else if (!strcmp(arg, "--name-status"))
@@ -1610,10 +1637,14 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        }
        else if (!strcmp(arg, "--color"))
                options->color_diff = 1;
+       else if (!strcmp(arg, "--no-color"))
+               options->color_diff = 0;
        else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
                options->xdl_opts |= XDF_IGNORE_WHITESPACE;
        else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
                options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
+       else if (!strcmp(arg, "--no-renames"))
+               options->detect_rename = 0;
        else
                return 0;
        return 1;
diff --git a/diff.h b/diff.h
index d557394..a06f959 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -42,6 +42,7 @@ struct diff_options {
        unsigned recursive:1,
                 tree_in_recursive:1,
                 binary:1,
+                text:1,
                 full_index:1,
                 silent_on_remove:1,
                 find_copies_harder:1,
@@ -122,7 +123,7 @@ extern int diff_scoreopt_parse(const char *opt);
 #define DIFF_SETUP_USE_CACHE           2
 #define DIFF_SETUP_USE_SIZE_CACHE      4
 
-extern int git_diff_config(const char *var, const char *value);
+extern int git_diff_ui_config(const char *var, const char *value);
 extern void diff_setup(struct diff_options *);
 extern int diff_opt_parse(struct diff_options *, const char **, int);
 extern int diff_setup_done(struct diff_options *);
@@ -161,7 +162,8 @@ extern void diffcore_std_no_resolve(struct diff_options *);
 "  -O<file>      reorder diffs according to the <file>.\n" \
 "  -S<string>    find filepair whose only one side contains the string.\n" \
 "  --pickaxe-all\n" \
-"                show all files diff when -S is used and hit is found.\n"
+"                show all files diff when -S is used and hit is found.\n" \
+"  -a  --text    treat all files as text.\n"
 
 extern int diff_queue_is_empty(void);
 extern void diff_flush(struct diff_options*);
index d57e865..1de8d32 100644 (file)
@@ -96,11 +96,15 @@ static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
        return &(rename_src[first]);
 }
 
-static int is_exact_match(struct diff_filespec *src, struct diff_filespec *dst)
+static int is_exact_match(struct diff_filespec *src,
+                         struct diff_filespec *dst,
+                         int contents_too)
 {
        if (src->sha1_valid && dst->sha1_valid &&
            !memcmp(src->sha1, dst->sha1, 20))
                return 1;
+       if (!contents_too)
+               return 0;
        if (diff_populate_filespec(src, 1) || diff_populate_filespec(dst, 1))
                return 0;
        if (src->size != dst->size)
@@ -242,7 +246,7 @@ void diffcore_rename(struct diff_options *options)
        struct diff_queue_struct *q = &diff_queued_diff;
        struct diff_queue_struct outq;
        struct diff_score *mx;
-       int i, j, rename_count;
+       int i, j, rename_count, contents_too;
        int num_create, num_src, dst_cnt;
 
        if (!minimum_score)
@@ -273,16 +277,23 @@ void diffcore_rename(struct diff_options *options)
 
        /* We really want to cull the candidates list early
         * with cheap tests in order to avoid doing deltas.
+        * The first round matches up the up-to-date entries,
+        * and then during the second round we try to match
+        * cache-dirty entries as well.
         */
-       for (i = 0; i < rename_dst_nr; i++) {
-               struct diff_filespec *two = rename_dst[i].two;
-               for (j = 0; j < rename_src_nr; j++) {
-                       struct diff_filespec *one = rename_src[j].one;
-                       if (!is_exact_match(one, two))
-                               continue;
-                       record_rename_pair(i, j, MAX_SCORE);
-                       rename_count++;
-                       break; /* we are done with this entry */
+       for (contents_too = 0; contents_too < 2; contents_too++) {
+               for (i = 0; i < rename_dst_nr; i++) {
+                       struct diff_filespec *two = rename_dst[i].two;
+                       if (rename_dst[i].pair)
+                               continue; /* dealt with an earlier round */
+                       for (j = 0; j < rename_src_nr; j++) {
+                               struct diff_filespec *one = rename_src[j].one;
+                               if (!is_exact_match(one, two, contents_too))
+                                       continue;
+                               record_rename_pair(i, j, MAX_SCORE);
+                               rename_count++;
+                               break; /* we are done with this entry */
+                       }
                }
        }
 
diff --git a/dir.c b/dir.c
index d778ecd..092d077 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -336,7 +336,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
                                if (dir->show_other_directories &&
                                    (subdir || !dir->hide_empty_directories) &&
                                    !dir_exists(fullname, baselen + len)) {
-                                       // Rewind the read subdirectory
+                                       /* Rewind the read subdirectory */
                                        while (dir->nr > rewind_base)
                                                free(dir->entries[--dir->nr]);
                                        break;
index c16b0c4..81d1371 100644 (file)
@@ -198,8 +198,8 @@ int receive_unpack_pack(int xd[2], const char *me, int quiet, int sideband)
 
 /*
  * A "binary msec" is a power-of-two-msec, aka 1/1024th of a second.
- * Keeing the time in that format means that "bytes / msecs" means
- * is the same as kB/s (modulo rounding).
+ * Keeping the time in that format means that "bytes / msecs" means
+ * the same as kB/s (modulo rounding).
  *
  * 1000512 is a magic number (usecs in a second, rounded up by half
  * of 1024, to make "rounding" come out right ;)
index 679045a..db9a20a 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -77,7 +77,7 @@ fall_back_3way () {
     # This is not so wrong.  Depending on which base we picked,
     # orig_tree may be wildly different from ours, but his_tree
     # has the same set of wildly different changes in parts the
-    # patch did not touch, so resolve ends up cancelling them,
+    # patch did not touch, so resolve ends up canceling them,
     # saying that we reverted all those changes.
 
     git-merge-resolve $orig_tree -- HEAD $his_tree || {
index e4b0947..8df2aee 100755 (executable)
@@ -182,7 +182,7 @@ git-apply --index "$PATCHFILE" || {
        # This is not so wrong.  Depending on which base we picked,
        # orig_tree may be wildly different from ours, but his_tree
        # has the same set of wildly different changes in parts the
-       # patch did not touch, so resolve ends up cancelling them,
+       # patch did not touch, so resolve ends up canceling them,
        # saying that we reverted all those changes.
 
        if git-merge-resolve $orig_tree -- HEAD $his_tree
index 740bc1f..ada60ec 100755 (executable)
@@ -14,7 +14,7 @@
 
 Imports a project from one or more Arch repositories. It will follow branches
 and repositories within the namespaces defined by the <archive/branch>
-parameters suppplied. If it cannot find the remote branch a merge comes from
+parameters supplied. If it cannot find the remote branch a merge comes from
 it will just import it as a regular commit. If it can find it, it will mark it 
 as a merge whenever possible.
 
@@ -88,7 +88,7 @@ usage if $opt_h;
 # $arch_branches:
 # values associated with keys:
 #   =1 - Arch version / git 'branch' detected via abrowse on a limit
-#   >1 - Arch version / git 'branch' of an auxilliary branch we've merged
+#   >1 - Arch version / git 'branch' of an auxiliary branch we've merged
 my %arch_branches = map { $_ => 1 } @ARGV;
 
 $ENV{'TMPDIR'} = $opt_t if $opt_t; # $ENV{TMPDIR} will affect tempdir() calls:
@@ -667,7 +667,7 @@ sub apply_cset {
     if (`find $tmp/changeset/patches -type f -name '*.patch'`) {
         # this can be sped up considerably by doing
         #    (find | xargs cat) | patch
-        # but that cna get mucked up by patches
+        # but that can get mucked up by patches
         # with missing trailing newlines or the standard 
         # 'missing newline' flag in the patch - possibly
         # produced with an old/buggy diff.
@@ -1026,7 +1026,7 @@ sub commitid2pset {
 }
 
 
-# an alterative to `command` that allows input to be passed as an array
+# an alternative to `command` that allows input to be passed as an array
 # to work around shell problems with weird characters in arguments
 sub safe_pipe_capture {
     my @output;
index 03df143..06a8d26 100755 (executable)
@@ -13,7 +13,7 @@ git bisect log                        show bisect log.'
 . git-sh-setup
 
 sq() {
-       perl -e '
+       @@PERL@@ -e '
                for (@ARGV) {
                        s/'\''/'\'\\\\\'\''/g;
                        print " '\''$_'\''";
index 6a14b25..0368803 100755 (executable)
@@ -324,7 +324,7 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"
 if test -f "$GIT_DIR/CLONE_HEAD"
 then
        # Read git-fetch-pack -k output and store the remote branches.
-       perl -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin"
+       @@PERL@@ -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin"
 fi
 
 cd "$D" || exit
index 22c4ce8..351d13c 100755 (executable)
@@ -147,7 +147,7 @@ run_status () {
            git-ls-files -z --others $option \
                --exclude-per-directory=.gitignore
        fi |
-       perl -e '$/ = "\0";
+       @@PERL@@ -e '$/ = "\0";
            my $shown = 0;
            while (<>) {
                chomp;
@@ -599,7 +599,7 @@ then
        GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
        test '' != "$GIT_AUTHOR_NAME" &&
        test '' != "$GIT_AUTHOR_EMAIL" ||
-       die "malformatted --author parameter"
+       die "malformed --author parameter"
        export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
 elif test '' != "$use_commit"
 then
index d1051d0..5d13a54 100755 (executable)
@@ -63,15 +63,15 @@ foreach my $p (@commit) {
 }
 
 if ($parent) {
+    my $found;
     # double check that it's a valid parent
     foreach my $p (@parents) {
-       my $found;
        if ($p eq $parent) {
            $found = 1;
            last;
        }; # found it
-       die "Did not find $parent in the parents for this commit!";
     }
+    die "Did not find $parent in the parents for this commit!" if !$found;
 } else { # we don't have a parent from the cmdline...
     if (@parents == 1) { # it's safe to get it from the commit
        $parent = $parents[0];
@@ -179,7 +179,7 @@ my @bfiles = grep(m/^Binary/, safe_pipe_capture('git-diff-tree', '-p', $parent,
 @bfiles = map { chomp } @bfiles;
 foreach my $f (@bfiles) {
     # check that the file in cvs matches the "old" file
-    # extract the file to $tmpdir and comparre with cmp
+    # extract the file to $tmpdir and compare with cmp
     my $tree = safe_pipe_capture('git-rev-parse', "$parent^{tree}");
     chomp $tree;
     my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`;
@@ -273,7 +273,7 @@ sub cleanupcvs {
     }
 }
 
-# An alterative to `command` that allows input to be passed as an array
+# An alternative to `command` that allows input to be passed as an array
 # to work around shell problems with weird characters in arguments
 # if the exec returns non-zero we die
 sub safe_pipe_capture {
index 5ccca4f..c30ef70 100755 (executable)
@@ -779,7 +779,7 @@ sub req_update
 
     #$log->debug("update state : " . Dumper($state));
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @{$state->{args}} )
     {
         $filename = filecleanup($filename);
@@ -1031,7 +1031,7 @@ sub req_ci
 
     my @committedfiles = ();
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @{$state->{args}} )
     {
         my $committedfile = $filename;
@@ -1145,7 +1145,7 @@ sub req_ci
 
     $updater->update();
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @committedfiles )
     {
         $filename = filecleanup($filename);
@@ -1190,7 +1190,7 @@ sub req_status
     # if no files were specified, we need to work out what files we should be providing status on ...
     argsfromdir($updater);
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @{$state->{args}} )
     {
         $filename = filecleanup($filename);
@@ -1291,7 +1291,7 @@ sub req_diff
     # if no files were specified, we need to work out what files we should be providing status on ...
     argsfromdir($updater);
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @{$state->{args}} )
     {
         $filename = filecleanup($filename);
@@ -1433,7 +1433,7 @@ sub req_log
     # if no files were specified, we need to work out what files we should be providing status on ...
     argsfromdir($updater);
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @{$state->{args}} )
     {
         $filename = filecleanup($filename);
@@ -1519,7 +1519,7 @@ sub req_annotate
 
     chdir $tmpdir;
 
-    # foreach file specified on the commandline ...
+    # foreach file specified on the command line ...
     foreach my $filename ( @{$state->{args}} )
     {
         $filename = filecleanup($filename);
index 48818f8..f80299d 100755 (executable)
@@ -278,7 +278,7 @@ fetch_main () {
          head="ref: $remote_name"
          while (expr "z$head" : "zref:" && expr $depth \< $max_depth) >/dev/null
          do
-           remote_name_quoted=$(perl -e '
+           remote_name_quoted=$(@@PERL@@ -e '
              my $u = $ARGV[0];
               $u =~ s/^ref:\s*//;
              $u =~ s{([^-a-zA-Z0-9/.])}{sprintf"%%%02x",ord($1)}eg;
index 69aef3c..63b18b9 100755 (executable)
@@ -25,7 +25,7 @@ conf=$GIT_DIR/gitweb/httpd.conf
 
 # Defaults:
 
-# if installed, it doens't need further configuration (module_path)
+# if installed, it doesn't need further configuration (module_path)
 test -z "$httpd" && httpd='lighttpd -f'
 
 # probably the most popular browser among gitweb users
index 5619409..fba4b0c 100755 (executable)
@@ -8,7 +8,7 @@
 #   $2 - file in branch1 SHA1 (or empty)
 #   $3 - file in branch2 SHA1 (or empty)
 #   $4 - pathname in repository
-#   $5 - orignal file mode (or empty)
+#   $5 - original file mode (or empty)
 #   $6 - file in branch1 mode (or empty)
 #   $7 - file in branch2 mode (or empty)
 #
index ce8a31f..4039435 100755 (executable)
@@ -47,7 +47,7 @@ cacheOnly = False
 
 def merge(h1, h2, branch1Name, branch2Name, graph, callDepth=0, ancestor=None):
     '''Merge the commits h1 and h2, return the resulting virtual
-    commit object and a flag indicating the cleaness of the merge.'''
+    commit object and a flag indicating the cleanness of the merge.'''
     assert(isinstance(h1, Commit) and isinstance(h2, Commit))
 
     global outputIndent
index f10cadb..21775fc 100755 (executable)
@@ -63,7 +63,7 @@ esac
 shift ;# away the initial 'x'
 
 # $# is now 0 if there was no explicit refspec on the command line
-# and there was no defalt refspec to push from remotes/ file.
+# and there was no default refspec to push from remotes/ file.
 # we will let git-send-pack to do its "matching refs" thing.
 
 case "$remote" in
index 86b51ab..364baff 100755 (executable)
@@ -49,7 +49,7 @@ if [ -n "$quilt_author" ] ; then
        quilt_author_email=$(expr "z$quilt_author" : '.*<\([^>]*\)') &&
        test '' != "$quilt_author_name" &&
        test '' != "$quilt_author_email" ||
-       die "malformatted --author parameter"
+       die "malformed --author parameter"
 fi
 
 # Quilt patch directory
index 3945e06..1b9e986 100755 (executable)
@@ -311,7 +311,7 @@ echo "$prev_head" > "$dotest/prev_head"
 
 msgnum=0
 for cmt in `git-rev-list --no-merges "$upstream"..ORIG_HEAD \
-                       | perl -e 'print reverse <>'`
+                       | @@PERL@@ -e 'print reverse <>'`
 do
        msgnum=$(($msgnum + 1))
        echo "$cmt" > "$dotest/cmt.$msgnum"
index c9c1975..d7f5dce 100755 (executable)
@@ -361,7 +361,7 @@ Options:
    --smtp-server  If set, specifies the outgoing SMTP server to use.
                   Defaults to localhost.
 
-  --suppress-from Supress sending emails to yourself if your address
+  --suppress-from Suppress sending emails to yourself if your address
                   appears in a From: line.
 
    --quiet     Make git-send-email less verbose.  One line per email should be
similarity index 99%
rename from contrib/git-svn/git-svn.perl
rename to git-svn.perl
index 8bc4188..4530ffe 100755 (executable)
@@ -8,7 +8,7 @@ use vars qw/    $AUTHOR $VERSION
                $GIT_SVN_INDEX $GIT_SVN
                $GIT_DIR $GIT_SVN_DIR $REVDB/;
 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
-$VERSION = '1.1.1-broken';
+$VERSION = '@@GIT_VERSION@@';
 
 use Cwd qw/abs_path/;
 $GIT_DIR = abs_path($ENV{GIT_DIR} || '.git');
@@ -760,7 +760,7 @@ sub commit_diff {
                exit 1;
        }
        if (defined $_file) {
-               $_message = file_to_s($_message);
+               $_message = file_to_s($_file);
        } else {
                $_message ||= get_commit_message($tb,
                                        "$GIT_DIR/.svn-commit.tmp.$$")->{msg};
@@ -1518,12 +1518,12 @@ sub get_commit_message {
        open my $msg, '>', $commit_msg or croak $!;
 
        chomp(my $type = `git-cat-file -t $commit`);
-       if ($type eq 'commit') {
+       if ($type eq 'commit' || $type eq 'tag') {
                my $pid = open my $msg_fh, '-|';
                defined $pid or croak $!;
 
                if ($pid == 0) {
-                       exec(qw(git-cat-file commit), $commit) or croak $!;
+                       exec('git-cat-file', $type, $commit) or croak $!;
                }
                my $in_msg = 0;
                while (<$msg_fh>) {
@@ -2429,7 +2429,7 @@ sub extract_metadata {
                                                        \s([a-f\d\-]+)$/x);
        if (!$rev || !$uuid || !$url) {
                # some of the original repositories I made had
-               # indentifiers like this:
+               # identifiers like this:
                ($rev, $uuid) = ($id =~/^git-svn-id:\s(\d+)\@([a-f\d\-]+)/);
        }
        return ($url, $rev, $uuid);
diff --git a/git.c b/git.c
index 2567301..49062ca 100644 (file)
--- a/git.c
+++ b/git.c
@@ -251,6 +251,11 @@ int main(int argc, const char **argv, char **envp)
                cmd = *++argv;
                argc--;
 
+               if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
+                       setup_pager();
+                       continue;
+               }
+
                if (strncmp(cmd, "--", 2))
                        break;
 
index 3e2790c..2e87de4 100755 (executable)
@@ -39,6 +39,9 @@ if ($git_version =~ m/git version (.*)$/) {
 
 # location for temporary files needed for diffs
 our $git_temp = "/tmp/gitweb";
+if (! -d $git_temp) {
+    mkdir($git_temp, 0700) || die_error("Couldn't mkdir $git_temp");
+}
 
 # target of the home link on top of all pages
 our $home_link = $my_uri;
@@ -1455,61 +1458,6 @@ sub git_get_hash_by_path {
        }
 }
 
-sub git_blob {
-       if (!defined $hash && defined $file_name) {
-               my $base = $hash_base || git_read_head($project);
-               $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
-       }
-       my $have_blame = git_get_project_config_bool ('blame');
-       open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed.");
-       git_header_html();
-       if (defined $hash_base && (my %co = git_read_commit($hash_base))) {
-               print "<div class=\"page_nav\">\n" .
-                     $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") .
-                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") .
-                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") .
-                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") .
-                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") .
-                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "<br/>\n";
-               if (defined $file_name) {
-                       if ($have_blame) {
-                               print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") .  " | ";
-                       }
-                       print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") .
-                       " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head") . "<br/>\n";
-               } else {
-                       print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain") . "<br/>\n";
-               }
-               print "</div>\n".
-                      "<div>" .
-                     $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) .
-                     "</div>\n";
-       } else {
-               print "<div class=\"page_nav\">\n" .
-                     "<br/><br/></div>\n" .
-                     "<div class=\"title\">$hash</div>\n";
-       }
-       if (defined $file_name) {
-               print "<div class=\"page_path\"><b>" . esc_html($file_name) . "</b></div>\n";
-       }
-       print "<div class=\"page_body\">\n";
-       my $nr;
-       while (my $line = <$fd>) {
-               chomp $line;
-               $nr++;
-               while ((my $pos = index($line, "\t")) != -1) {
-                       if (my $count = (8 - ($pos % 8))) {
-                               my $spaces = ' ' x $count;
-                               $line =~ s/\t/$spaces/;
-                       }
-               }
-               printf "<div class=\"pre\"><a id=\"l%i\" href=\"#l%i\" class=\"linenr\">%4i</a> %s</div>\n", $nr, $nr, $nr, esc_html($line);
-       }
-       close $fd or print "Reading blob failed.\n";
-       print "</div>";
-       git_footer_html();
-}
-
 sub mimetype_guess_file {
        my $filename = shift;
        my $mimemap = shift;
@@ -1548,14 +1496,14 @@ sub git_blob_plain_mimetype {
        my $fd = shift;
        my $filename = shift;
 
-       # just in case
-       return $default_blob_plain_mimetype unless $fd;
-
        if ($filename) {
                my $mime = mimetype_guess($filename);
                $mime and return $mime;
        }
 
+       # just in case
+       return $default_blob_plain_mimetype unless $fd;
+
        if (-T $fd) {
                return 'text/plain' .
                       ($default_text_plain_charset ? '; charset='.$default_text_plain_charset : '');
@@ -1573,8 +1521,10 @@ sub git_blob_plain_mimetype {
 }
 
 sub git_blob_plain {
-       open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or return;
-       my $type = git_blob_plain_mimetype($fd, $file_name);
+       my $type = shift;
+       open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash");
+
+       $type ||= git_blob_plain_mimetype($fd, $file_name);
 
        # save as filename, even when no $file_name is given
        my $save_as = "$hash";
@@ -1593,6 +1543,66 @@ sub git_blob_plain {
        close $fd;
 }
 
+sub git_blob {
+       if (!defined $hash && defined $file_name) {
+               my $base = $hash_base || git_read_head($project);
+               $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
+       }
+       my $have_blame = git_get_project_config_bool ('blame');
+       open my $fd, "-|", "$gitbin/git-cat-file blob $hash" or die_error(undef, "Open failed.");
+       my $mimetype = git_blob_plain_mimetype($fd, $file_name);
+       if ($mimetype !~ m/^text\//) {
+               close $fd;
+               return git_blob_plain($mimetype);
+       }
+       git_header_html();
+       if (defined $hash_base && (my %co = git_read_commit($hash_base))) {
+               print "<div class=\"page_nav\">\n" .
+                     $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") .
+                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") .
+                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") .
+                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") .
+                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") .
+                     " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") . "<br/>\n";
+               if (defined $file_name) {
+                       if ($have_blame) {
+                               print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name")}, "blame") .  " | ";
+                       }
+                       print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash;f=$file_name")}, "plain") .
+                       " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=HEAD;f=$file_name")}, "head") . "<br/>\n";
+               } else {
+                       print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$hash")}, "plain") . "<br/>\n";
+               }
+               print "</div>\n".
+                      "<div>" .
+                     $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) .
+                     "</div>\n";
+       } else {
+               print "<div class=\"page_nav\">\n" .
+                     "<br/><br/></div>\n" .
+                     "<div class=\"title\">$hash</div>\n";
+       }
+       if (defined $file_name) {
+               print "<div class=\"page_path\"><b>" . esc_html($file_name) . "</b></div>\n";
+       }
+       print "<div class=\"page_body\">\n";
+       my $nr;
+       while (my $line = <$fd>) {
+               chomp $line;
+               $nr++;
+               while ((my $pos = index($line, "\t")) != -1) {
+                       if (my $count = (8 - ($pos % 8))) {
+                               my $spaces = ' ' x $count;
+                               $line =~ s/\t/$spaces/;
+                       }
+               }
+               printf "<div class=\"pre\"><a id=\"l%i\" href=\"#l%i\" class=\"linenr\">%4i</a> %s</div>\n", $nr, $nr, $nr, esc_html($line);
+       }
+       close $fd or print "Reading blob failed.\n";
+       print "</div>";
+       git_footer_html();
+}
+
 sub git_tree {
        if (!defined $hash) {
                $hash = git_read_head($project);
@@ -1668,6 +1678,7 @@ sub git_tree {
                              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") .
 #                            " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") .
                              " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
+                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") .
                              "</td>\n";
                } elsif ($t_type eq "tree") {
                        print "<td class=\"list\">" .
index 44eba5f..12493fb 100644 (file)
@@ -490,7 +490,7 @@ static int setup_index(struct alt_base *repo, unsigned char *sha1)
 {
        struct packed_git *new_pack;
        if (has_pack_file(sha1))
-               return 0; // don't list this as something we can get
+               return 0; /* don't list this as something we can get */
 
        if (fetch_index(repo, sha1))
                return -1;
@@ -570,7 +570,7 @@ static void process_alternates_response(void *callback_data)
                                                 base[serverlen - 1] != '/');
                                        i += 3;
                                }
-                               // If the server got removed, give up.
+                               /* If the server got removed, give up. */
                                okay = strchr(base, ':') - base + 3 <
                                        serverlen;
                        } else if (alt_req->http_specific) {
@@ -581,7 +581,7 @@ static void process_alternates_response(void *callback_data)
                                        okay = 1;
                                }
                        }
-                       // skip 'objects' at end
+                       /* skip 'objects' at end */
                        if (okay) {
                                target = xmalloc(serverlen + posn - i - 6);
                                strlcpy(target, base, serverlen);
diff --git a/mktag.c b/mktag.c
index f0fe528..27f4c4f 100644 (file)
--- a/mktag.c
+++ b/mktag.c
@@ -17,7 +17,7 @@
  * in that size, you're doing something wrong.
  */
 
-// Some random size
+/* Some random size */
 #define MAXSIZE (8192)
 
 /*
@@ -123,7 +123,8 @@ int main(int argc, char **argv)
                die("could not read from stdin");
        }
 
-       // Verify it for some basic sanity: it needs to start with "object <sha1>\ntype\ntagger "
+       /* Verify it for some basic sanity: it needs to start with
+          "object <sha1>\ntype\ntagger " */
        if (verify_tag(buffer, size) < 0)
                die("invalid tag signature file");
 
index 6a23f2d..083d067 100644 (file)
@@ -5,7 +5,7 @@
 #include "refs.h"
 
 static const char name_rev_usage[] =
-       "git-name-rev [--tags] ( --all | --stdin | commitish [commitish...] )\n";
+       "git-name-rev [--tags] ( --all | --stdin | committish [committish...] )\n";
 
 typedef struct rev_name {
        const char *tip_name;
index b486ea5..04a48b9 100644 (file)
@@ -28,7 +28,7 @@ struct object_entry {
        struct object_entry *delta;     /* delta base object */
        struct packed_git *in_pack;     /* already in pack */
        unsigned int in_pack_offset;
-       struct object_entry *delta_child; /* delitified objects who bases me */
+       struct object_entry *delta_child; /* deltified objects who bases me */
        struct object_entry *delta_sibling; /* other deltified objects who
                                             * uses the same base as me
                                             */
@@ -39,7 +39,7 @@ struct object_entry {
 };
 
 /*
- * Objects we are going to pack are colected in objects array (dynamically
+ * Objects we are going to pack are collected in objects array (dynamically
  * expanded).  nr_objects & nr_alloc controls this array.  They are stored
  * in the order we see -- typically rev-list --objects order that gives us
  * nice "minimum seek" order.
diff --git a/pager.c b/pager.c
index 2d186e8..bb14e99 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -5,6 +5,8 @@
  * something different on Windows, for example.
  */
 
+int pager_in_use;
+
 static void run_pager(const char *pager)
 {
        execlp(pager, pager, NULL);
@@ -24,6 +26,8 @@ void setup_pager(void)
        else if (!*pager || !strcmp(pager, "cat"))
                return;
 
+       pager_in_use = 1; /* means we are emitting to terminal */
+
        if (pipe(fd) < 0)
                return;
        pid = fork();
index f591d98..140cb53 100644 (file)
@@ -62,7 +62,7 @@
  * computation of W[t+4].
  *
  * The first 16 rounds use W values loaded directly from memory, while the
- * remianing 64 use values computed from those first 16.  We preload
+ * remaining 64 use values computed from those first 16.  We preload
  * 4 values before starting, so there are three kinds of rounds:
  * - The first 12 (all f0) also load the W values from memory.
  * - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.
index 3c32aae..a50d361 100644 (file)
@@ -748,7 +748,7 @@ int read_cache(void)
                die("index file open failed (%s)", strerror(errno));
        }
 
-       size = 0; // avoid gcc warning
+       size = 0; /* avoid gcc warning */
        map = MAP_FAILED;
        if (!fstat(fd, &st)) {
                size = st.st_size;
diff --git a/refs.c b/refs.c
index 713ca46..2d9c1dc 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -362,7 +362,7 @@ static int log_ref_write(struct ref_lock *lock,
        int logfd, written, oflags = O_APPEND | O_WRONLY;
        unsigned maxlen, len;
        char *logrec;
-       const char *comitter;
+       const char *committer;
 
        if (log_all_ref_updates) {
                if (safe_create_leading_directories(lock->log_file) < 0)
@@ -380,23 +380,23 @@ static int log_ref_write(struct ref_lock *lock,
        }
 
        setup_ident();
-       comitter = git_committer_info(1);
+       committer = git_committer_info(1);
        if (msg) {
-               maxlen = strlen(comitter) + strlen(msg) + 2*40 + 5;
+               maxlen = strlen(committer) + strlen(msg) + 2*40 + 5;
                logrec = xmalloc(maxlen);
                len = snprintf(logrec, maxlen, "%s %s %s\t%s\n",
                        sha1_to_hex(lock->old_sha1),
                        sha1_to_hex(sha1),
-                       comitter,
+                       committer,
                        msg);
        }
        else {
-               maxlen = strlen(comitter) + 2*40 + 4;
+               maxlen = strlen(committer) + 2*40 + 4;
                logrec = xmalloc(maxlen);
                len = snprintf(logrec, maxlen, "%s %s %s\n",
                        sha1_to_hex(lock->old_sha1),
                        sha1_to_hex(sha1),
-                       comitter);
+                       committer);
        }
        written = len <= maxlen ? write(logfd, logrec, len) : -1;
        free(logrec);
index 0eb5132..fdfe05a 100644 (file)
@@ -94,7 +94,7 @@ static int read_pack_info_file(const char *infofile)
 
        fp = fopen(infofile, "r");
        if (!fp)
-               return 1; /* nonexisting is not an error. */
+               return 1; /* nonexistent is not an error. */
 
        while (fgets(line, sizeof(line), fp)) {
                int len = strlen(line);
index bc35808..459430a 100644 (file)
@@ -453,7 +453,7 @@ int use_packed_git(struct packed_git *p)
 {
        if (!p->pack_size) {
                struct stat st;
-               // We created the struct before we had the pack
+               /* We created the struct before we had the pack */
                stat(p->pack_name, &st);
                if (!S_ISREG(st.st_mode))
                        die("packfile %s not a regular file", p->pack_name);
@@ -1504,7 +1504,7 @@ static void *repack_object(const unsigned char *sha1, unsigned long *objsize)
        int hdrlen;
        void *buf;
 
-       // need to unpack and recompress it by itself
+       /* need to unpack and recompress it by itself */
        unpacked = read_packed_sha1(sha1, type, &len);
 
        hdrlen = sprintf(hdr, "%s %lu", type, len) + 1;
@@ -1660,7 +1660,7 @@ int has_sha1_file(const unsigned char *sha1)
 
 /*
  * reads from fd as long as possible into a supplied buffer of size bytes.
- * If neccessary the buffer's size is increased using realloc()
+ * If necessary the buffer's size is increased using realloc()
  *
  * returns 0 if anything went fine and -1 otherwise
  *
index 1e59cd2..28f7fd9 100644 (file)
@@ -68,7 +68,7 @@ int fetch(unsigned char *sha1)
        struct object_list *temp;
 
        if (memcmp(sha1, in_transit->item->sha1, 20)) {
-               // we must have already fetched it to clean the queue
+               /* we must have already fetched it to clean the queue */
                return has_sha1_file(sha1) ? 0 : -1;
        }
        prefetches--;
@@ -85,7 +85,7 @@ int fetch(unsigned char *sha1)
                if (read(fd_in, &remote, 1) < 1)
                        return -1;
        }
-       //fprintf(stderr, "Got %d\n", remote);
+       /* fprintf(stderr, "Got %d\n", remote); */
        if (remote < 0)
                return remote;
        ret = write_sha1_from_fd(sha1, fd_in, conn_buf, 4096, &conn_buf_posn);
index 632c55f..8983509 100644 (file)
@@ -11,6 +11,7 @@ TAR ?= $(TAR)
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
 
 T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+TSVN = $(wildcard t91[0-9][0-9]-*.sh)
 
 ifdef NO_PYTHON
        GIT_TEST_OPTS += --no-python
@@ -24,6 +25,15 @@ $(T):
 clean:
        rm -fr trash
 
+# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
+full-svn-test:
+       $(MAKE) $(TSVN) GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
+       $(MAKE) $(TSVN) GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
+       $(MAKE) $(TSVN) GIT_SVN_NO_LIB=1 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
+                                                       LC_ALL=en_US.UTF-8
+       $(MAKE) $(TSVN) GIT_SVN_NO_LIB=0 GIT_SVN_NO_OPTIMIZE_COMMITS=0 \
+                                                       LC_ALL=en_US.UTF-8
+
 .PHONY: $(T) clean
 .NOTPARALLEL:
 
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
new file mode 100644 (file)
index 0000000..29a1e72
--- /dev/null
@@ -0,0 +1,50 @@
+. ./test-lib.sh
+
+if test -n "$NO_SVN_TESTS"
+then
+       test_expect_success 'skipping git-svn tests, NO_SVN_TESTS defined' :
+       test_done
+       exit
+fi
+
+GIT_DIR=$PWD/.git
+GIT_SVN_DIR=$GIT_DIR/svn/git-svn
+SVN_TREE=$GIT_SVN_DIR/svn-tree
+
+perl -e 'use SVN::Core' >/dev/null 2>&1
+if test $? -ne 0
+then
+   echo 'Perl SVN libraries not found, tests requiring those will be skipped'
+   GIT_SVN_NO_LIB=1
+fi
+
+svnadmin >/dev/null 2>&1
+if test $? -ne 1
+then
+    test_expect_success 'skipping git-svn tests, svnadmin not found' :
+    test_done
+    exit
+fi
+
+svn >/dev/null 2>&1
+if test $? -ne 1
+then
+    test_expect_success 'skipping git-svn tests, svn not found' :
+    test_done
+    exit
+fi
+
+svnrepo=$PWD/svnrepo
+
+set -e
+
+if svnadmin create --help | grep fs-type >/dev/null
+then
+       svnadmin create --fs-type fsfs "$svnrepo"
+else
+       svnadmin create "$svnrepo"
+fi
+
+svnrepo="file://$svnrepo/test-git-svn"
+
+
index 916ee15..dd9caad 100755 (executable)
@@ -31,7 +31,7 @@ test_expect_success 'cloning with reference' \
 
 cd "$base_dir"
 
-test_expect_success 'existance of info/alternates' \
+test_expect_success 'existence of info/alternates' \
 'test `wc -l <C/.git/objects/info/alternates` = 2'
 
 cd "$base_dir"
index 097d037..2e1b48a 100755 (executable)
@@ -81,7 +81,7 @@ test_valid_repo"
 
 cd "$base_dir"
 
-test_expect_failure 'that info/alternates is neccessary' \
+test_expect_failure 'that info/alternates is necessary' \
 'cd C &&
 rm .git/objects/info/alternates &&
 test_valid_repo'
index 693de9b..7831e34 100755 (executable)
@@ -154,7 +154,7 @@ test_sequence()
        test_bisection_diff 0 $_bisect_option u5 ^U
        
 #
-# the following illustrate's Linus' binary bug blatt idea. 
+# the following illustrates Linus' binary bug blatt idea.
 #
 # assume the bug is actually at l3, but you don't know that - all you know is that l3 is broken
 # and it wasn't broken before
index 2623813..8f7366d 100755 (executable)
@@ -4,7 +4,7 @@
 #
 
 # See http://marc.theaimsgroup.com/?l=git&m=111463358500362&w=2 for a
-# nice decription of what this is about.
+# nice description of what this is about.
 
 
 test_description='Test criss-cross merge'
old mode 100644 (file)
new mode 100755 (executable)
similarity index 98%
rename from contrib/git-svn/t/t0000-contrib-git-svn.sh
rename to t/t9100-git-svn-basic.sh
index b482bb6..bf1d638
@@ -3,7 +3,7 @@
 # Copyright (c) 2006 Eric Wong
 #
 
-test_description='git-svn tests'
+test_description='git-svn basic tests'
 GIT_SVN_LC_ALL=$LC_ALL
 
 case "$LC_ALL" in
@@ -17,6 +17,8 @@ esac
 
 . ./lib-git-svn.sh
 
+echo 'define NO_SVN_TESTS to skip git-svn tests'
+
 mkdir import
 cd import
 
old mode 100644 (file)
new mode 100755 (executable)
similarity index 100%
rename from contrib/git-svn/t/t0001-contrib-git-svn-props.sh
rename to t/t9101-git-svn-props.sh
old mode 100644 (file)
new mode 100755 (executable)
similarity index 100%
rename from contrib/git-svn/t/t0002-deep-rmdir.sh
rename to t/t9102-git-svn-deep-rmdir.sh
old mode 100644 (file)
new mode 100755 (executable)
similarity index 100%
rename from contrib/git-svn/t/t0003-graft-branches.sh
rename to t/t9103-git-svn-graft-branches.sh
old mode 100644 (file)
new mode 100755 (executable)
similarity index 100%
rename from contrib/git-svn/t/t0004-follow-parent.sh
rename to t/t9104-git-svn-follow-parent.sh
old mode 100644 (file)
new mode 100755 (executable)
similarity index 100%
rename from contrib/git-svn/t/t0005-commit-diff.sh
rename to t/t9105-git-svn-commit-diff.sh
index d7a8f0a..76d5ac2 100644 (file)
@@ -60,7 +60,7 @@ then
                        echo "Changes since $prev:"
                        git rev-list --pretty $prev..$3 | $short
                        echo ---
-                       git diff $prev..$3 | diffstat -p1
+                       git diff --stat $prev..$3
                        echo ---
                fi
                ;;
@@ -75,7 +75,7 @@ else
        base=$(git-merge-base "$2" "$3")
        case "$base" in
        "$2")
-               git diff "$3" "^$base" | diffstat -p1
+               git diff --stat "$3" "^$base"
                echo
                echo "New commits:"
                ;;
index ed7ad20..d76e76a 100644 (file)
@@ -84,7 +84,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
                 * We need to extent the diagonal "domain" by one. If the next
                 * values exits the box boundaries we need to change it in the
                 * opposite direction because (max - min) must be a power of two.
-                * Also we initialize the extenal K value to -1 so that we can
+                * Also we initialize the external K value to -1 so that we can
                 * avoid extra conditions check inside the core loop.
                 */
                if (fmin > dmin)
@@ -119,7 +119,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
                 * We need to extent the diagonal "domain" by one. If the next
                 * values exits the box boundaries we need to change it in the
                 * opposite direction because (max - min) must be a power of two.
-                * Also we initialize the extenal K value to -1 so that we can
+                * Also we initialize the external K value to -1 so that we can
                 * avoid extra conditions check inside the core loop.
                 */
                if (bmin > dmin)
@@ -405,7 +405,7 @@ static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
        /*
         * This is the same of what GNU diff does. Move back and forward
         * change groups for a consistent and pretty diff output. This also
-        * helps in finding joineable change groups and reduce the diff size.
+        * helps in finding joinable change groups and reduce the diff size.
         */
        for (ix = ixo = 0;;) {
                /*