Merge branch 'nd/maint-hide-checkout-index-from-error' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 14 Dec 2010 15:36:00 +0000 (07:36 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 14 Dec 2010 15:36:00 +0000 (07:36 -0800)
* nd/maint-hide-checkout-index-from-error:
entry.c: remove "checkout-index" from error messages

81 files changed:
Documentation/CodingGuidelines
Documentation/RelNotes/1.7.0.8.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.1.3.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.2.4.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.3.3.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.3.4.txt [new file with mode: 0644]
Documentation/config.txt
Documentation/git-add.txt
Documentation/git-cherry-pick.txt
Documentation/git-commit.txt
Documentation/git-pull.txt
Documentation/git-revert.txt
Documentation/git-rm.txt
Documentation/git-send-email.txt
Documentation/gitattributes.txt
Documentation/gitignore.txt
GIT-VERSION-GEN
INSTALL
RelNotes
builtin.h
builtin/add.c
builtin/apply.c
builtin/blame.c
builtin/cat-file.c
builtin/merge-file.c
builtin/merge.c
builtin/pack-objects.c
builtin/revert.c
builtin/tag.c
builtin/verify-tag.c
config.c
contrib/completion/git-completion.bash
contrib/examples/git-svnimport.perl
contrib/fast-import/import-directories.perl
contrib/hooks/post-receive-email
diff.c
environment.c
git-add--interactive.perl
git-archimport.perl
git-cvsexportcommit.perl
git-cvsimport.perl
git-cvsserver.perl
git-difftool.perl
git-rebase.sh
git-relink.perl
git-send-email.perl
git-svn.perl
gitweb/gitweb.perl
http.c
perl/Git.pm
reflog-walk.c
revision.c
setup.c
sha1_name.c
t/gitweb-lib.sh
t/lib-httpd.sh
t/lib-httpd/apache.conf
t/lib-httpd/passwd [new file with mode: 0644]
t/t1412-reflog-loop.sh [new file with mode: 0755]
t/t3407-rebase-abort.sh
t/t3501-revert-cherry-pick.sh
t/t4018-diff-funcname.sh
t/t4019-diff-wserror.sh
t/t4120-apply-popt.sh
t/t4132-apply-removal.sh
t/t4135-apply-weird-filenames.sh
t/t4135/damaged-tz.diff [new file with mode: 0644]
t/t4135/funny-tz.diff [new file with mode: 0644]
t/t4202-log.sh
t/t5550-http-fetch.sh
t/t5551-http-fetch.sh
t/t6023-merge-file.sh
t/t7004-tag.sh
t/t7006/test-terminal.perl
t/t7607-merge-overwrite.sh
t/t8006-blame-textconv.sh
t/t8007-cat-file-textconv.sh
t/t9700/test.pl
tag.c
tag.h
userdiff.c
index 09ffc46563cba1057b37ba4a5701858fb95c5dda..46f8a3fab13f71623ef6dbc4239067e8daa9dc59 100644 (file)
@@ -31,6 +31,10 @@ But if you must have a list of rules, here they are.
 
 For shell scripts specifically (not exhaustive):
 
+ - We use tabs for indentation.
+
+ - Case arms are indented at the same depth as case and esac lines.
+
  - We prefer $( ... ) for command substitution; unlike ``, it
    properly nests.  It should have been the way Bourne spelled
    it from day one, but unfortunately isn't.
diff --git a/Documentation/RelNotes/1.7.0.8.txt b/Documentation/RelNotes/1.7.0.8.txt
new file mode 100644 (file)
index 0000000..7f05b48
--- /dev/null
@@ -0,0 +1,10 @@
+Git v1.7.0.8 Release Notes
+==========================
+
+This is primarily to backport support for the new "add.ignoreErrors"
+name given to the existing "add.ignore-errors" configuration variable.
+
+The next version, Git 1.7.4, and future versions, will support both
+old and incorrect name and the new corrected name, but without this
+backport, users who want to use the new name "add.ignoreErrors" in
+their repositories cannot use older versions of Git.
diff --git a/Documentation/RelNotes/1.7.1.3.txt b/Documentation/RelNotes/1.7.1.3.txt
new file mode 100644 (file)
index 0000000..5b18518
--- /dev/null
@@ -0,0 +1,10 @@
+Git v1.7.1.3 Release Notes
+==========================
+
+This is primarily to backport support for the new "add.ignoreErrors"
+name given to the existing "add.ignore-errors" configuration variable.
+
+The next version, Git 1.7.4, and future versions, will support both
+old and incorrect name and the new corrected name, but without this
+backport, users who want to use the new name "add.ignoreErrors" in
+their repositories cannot use older versions of Git.
diff --git a/Documentation/RelNotes/1.7.2.4.txt b/Documentation/RelNotes/1.7.2.4.txt
new file mode 100644 (file)
index 0000000..f7950a4
--- /dev/null
@@ -0,0 +1,10 @@
+Git v1.7.2.4 Release Notes
+==========================
+
+This is primarily to backport support for the new "add.ignoreErrors"
+name given to the existing "add.ignore-errors" configuration variable.
+
+The next version, Git 1.7.4, and future versions, will support both
+old and incorrect name and the new corrected name, but without this
+backport, users who want to use the new name "add.ignoreErrors" in
+their repositories cannot use older versions of Git.
diff --git a/Documentation/RelNotes/1.7.3.3.txt b/Documentation/RelNotes/1.7.3.3.txt
new file mode 100644 (file)
index 0000000..9b2b244
--- /dev/null
@@ -0,0 +1,54 @@
+Git v1.7.3.3 Release Notes
+==========================
+
+In addition to the usual fixes, this release also includes support for
+the new "add.ignoreErrors" name given to the existing "add.ignore-errors"
+configuration variable.
+
+The next version, Git 1.7.4, and future versions, will support both
+old and incorrect name and the new corrected name, but without this
+backport, users who want to use the new name "add.ignoreErrors" in
+their repositories cannot use older versions of Git.
+
+Fixes since v1.7.3.2
+--------------------
+
+ * "git apply" segfaulted when a bogus input is fed to it.
+
+ * Running "git cherry-pick --ff" on a root commit segfaulted.
+
+ * "diff", "blame" and friends incorrectly applied textconv filters to
+   symlinks.
+
+ * Highlighting of whitespace breakage in "diff" output was showing
+   incorrect amount of whitespaces when blank-at-eol is set and the line
+   consisted only of whitespaces and a TAB.
+
+ * "diff" was overly inefficient when trying to find the line to use for
+   the function header (i.e. equivalent to --show-c-function of GNU diff).
+
+ * "git imap-send" depends on libcrypto but our build rule relied on the
+   linker to implicitly link it via libssl, which was wrong.
+
+ * "git merge-file" can be called from within a subdirectory now.
+
+ * "git repack -f" expanded and recompressed non-delta objects in the
+   existing pack, which was wasteful.  Use new "-F" option if you really
+   want to (e.g. when changing the pack.compression level).
+
+ * "git rev-list --format="...%x00..." incorrectly chopped its output
+   at NUL.
+
+ * "git send-email" did not correctly remove duplicate mail addresses from
+   the Cc: header that appear on the To: header.
+
+ * The completion script (in contrib/completion) ignored lightweight tags
+   in __git_ps1().
+
+ * "git-blame" mode (in contrib/emacs) didn't say (require 'format-spec)
+   even though it depends on it; it didn't work with Emacs 22 or older
+   unless Gnus is used.
+
+ * "git-p4" (in contrib/) did not correctly handle deleted files.
+
+Other minor fixes and documentation updates are also included.
diff --git a/Documentation/RelNotes/1.7.3.4.txt b/Documentation/RelNotes/1.7.3.4.txt
new file mode 100644 (file)
index 0000000..925178f
--- /dev/null
@@ -0,0 +1,32 @@
+Git v1.7.3.4 Release Notes
+==========================
+
+Fixes since v1.7.3.3
+--------------------
+
+ * Smart HTTP transport used to incorrectly retry redirected POST
+   request with GET request.
+
+ * "git apply" did not correctly handle patches that only change modes
+   if told to apply while stripping leading paths with -p option.
+
+ * "git apply" can deal with patches with timezone formatted with a
+   colon between the hours and minutes part (e.g. "-08:00" instead of
+   "-0800").
+
+ * "git cherry-pick" or "git revert" refused to work when a path that
+   would be modified by the operation was stat-dirty without a real
+   difference in the contents of the file.
+
+ * "git diff --check" reported an incorrect line number for added
+   blank lines at the end of file.
+
+ * Setting log.decorate configuration variable to "0" or "1" to mean
+   "false" or "true" did not work.
+
+ * "git tag -v" did not work with GPG signatures in rfc1991 mode.
+
+ * The post-receive-email sample hook was accidentally broken in 1.7.3.3
+   update.
+
+Other minor fixes and documentation updates are also included.
index e6a8f27f2602582a6ed8da8f059a30201f16fa70..3fd4b626fa84deb317709f11782534f36df36033 100644 (file)
@@ -548,9 +548,13 @@ core.sparseCheckout::
        linkgit:git-read-tree[1] for more information.
 
 add.ignore-errors::
+add.ignoreErrors::
        Tells 'git add' to continue adding files when some files cannot be
        added due to indexing errors. Equivalent to the '--ignore-errors'
-       option of linkgit:git-add[1].
+       option of linkgit:git-add[1].  Older versions of git accept only
+       `add.ignore-errors`, which does not follow the usual naming
+       convention for configuration variables.  Newer versions of git
+       honor `add.ignoreErrors` as well.
 
 alias.*::
        Command aliases for the linkgit:git[1] command wrapper - e.g.
index 73378b2bef8405f54c661e8c9745057b5b243f4d..54aaaeb41b969be4c79a2a8072bc6daca469ca8d 100644 (file)
@@ -92,9 +92,11 @@ See ``Interactive mode'' for details.
        edit it.  After the editor was closed, adjust the hunk headers
        and apply the patch to the index.
 +
-*NOTE*: Obviously, if you change anything else than the first character
-on lines beginning with a space or a minus, the patch will no longer
-apply.
+The intent of this option is to pick and choose lines of the patch to
+apply, or even to modify the contents of lines to be staged. This can be
+quicker and more flexible than using the interactive hunk selector.
+However, it is easy to confuse oneself and create a patch that does not
+apply to the index. See EDITING PATCHES below.
 
 -u::
 --update::
@@ -295,6 +297,78 @@ diff::
   This lets you review what will be committed (i.e. between
   HEAD and index).
 
+
+EDITING PATCHES
+---------------
+
+Invoking `git add -e` or selecting `e` from the interactive hunk
+selector will open a patch in your editor; after the editor exits, the
+result is applied to the index. You are free to make arbitrary changes
+to the patch, but note that some changes may have confusing results, or
+even result in a patch that cannot be applied.  If you want to abort the
+operation entirely (i.e., stage nothing new in the index), simply delete
+all lines of the patch. The list below describes some common things you
+may see in a patch, and which editing operations make sense on them.
+
+--
+added content::
+
+Added content is represented by lines beginning with "{plus}". You can
+prevent staging any addition lines by deleting them.
+
+removed content::
+
+Removed content is represented by lines beginning with "-". You can
+prevent staging their removal by converting the "-" to a " " (space).
+
+modified content::
+
+Modified content is represented by "-" lines (removing the old content)
+followed by "{plus}" lines (adding the replacement content). You can
+prevent staging the modification by converting "-" lines to " ", and
+removing "{plus}" lines. Beware that modifying only half of the pair is
+likely to introduce confusing changes to the index.
+--
+
+There are also more complex operations that can be performed. But beware
+that because the patch is applied only to the index and not the working
+tree, the working tree will appear to "undo" the change in the index.
+For example, introducing a a new line into the index that is in neither
+the HEAD nor the working tree will stage the new line for commit, but
+the line will appear to be reverted in the working tree.
+
+Avoid using these constructs, or do so with extreme caution.
+
+--
+removing untouched content::
+
+Content which does not differ between the index and working tree may be
+shown on context lines, beginning with a " " (space).  You can stage
+context lines for removal by converting the space to a "-". The
+resulting working tree file will appear to re-add the content.
+
+modifying existing content::
+
+One can also modify context lines by staging them for removal (by
+converting " " to "-") and adding a "{plus}" line with the new content.
+Similarly, one can modify "{plus}" lines for existing additions or
+modifications. In all cases, the new modification will appear reverted
+in the working tree.
+
+new content::
+
+You may also add new content that does not exist in the patch; simply
+add new lines, each starting with "{plus}". The addition will appear
+reverted in the working tree.
+--
+
+There are also several operations which should be avoided entirely, as
+they will make the patch impossible to apply:
+
+* adding context (" ") or removal ("-") lines
+* deleting context or removal lines
+* modifying the contents of context or removal lines
+
 SEE ALSO
 --------
 linkgit:git-status[1]
index 3c96fa8c86c34df2dced6cd9ec8a391ee3b7208e..73008705ebe304c8d2a2d089e9328be369c50fc6 100644 (file)
@@ -92,7 +92,7 @@ git cherry-pick ^HEAD master::
        Apply the changes introduced by all commits that are ancestors
        of master but not of HEAD to produce new commits.
 
-git cherry-pick master\~4 master~2::
+git cherry-pick master{tilde}4 master{tilde}2::
 
        Apply the changes introduced by the fifth and third last
        commits pointed to by master and create 2 new commits with
index 42fb1f57b21d7c355d3df6be07329c478786a9a7..ec7b577b85ae5a320b1006380f5abd03946ba44b 100644 (file)
@@ -11,8 +11,8 @@ SYNOPSIS
 'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
           [(-c | -C) <commit>] [-F <file> | -m <msg>] [--reset-author]
           [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>]
-          [--date=<date>] [--cleanup=<mode>] [--status | --no-status] [--]
-          [[-i | -o ]<file>...]
+          [--date=<date>] [--cleanup=<mode>] [--status | --no-status]
+          [-i | -o] [--] [<file>...]
 
 DESCRIPTION
 -----------
index e1b0bd2868e5f4c489f698038c4d4aaae7740c52..abbc3eb3e0ee208a13237cde5ae3d00d962ad62e 100644 (file)
@@ -27,8 +27,8 @@ With `--rebase`, it runs 'git rebase' instead of 'git merge'.
 passed to linkgit:git-fetch[1].  <refspec> can name an
 arbitrary remote ref (for example, the name of a tag) or even
 a collection of refs with corresponding remote tracking branches
-(e.g., refs/heads/*:refs/remotes/origin/*), but usually it is
-the name of a branch in the remote repository.
+(e.g., refs/heads/{asterisk}:refs/remotes/origin/{asterisk}),
+but usually it is the name of a branch in the remote repository.
 
 Default values for <repository> and <branch> are read from the
 "remote" and "merge" configuration for the current branch
index f40984d144e4ca276f84fc81a74c4ae726dcf497..752fc88e768e4b8e1afddad4bdd7833cf20978c7 100644 (file)
@@ -87,7 +87,7 @@ git revert HEAD~3::
        Revert the changes specified by the fourth last commit in HEAD
        and create a new commit with the reverted changes.
 
-git revert -n master\~5..master~2::
+git revert -n master{tilde}5..master{tilde}2::
 
        Revert the changes done by commits from the fifth last commit
        in master (included) to the third last commit in master
index 71e3d9fc23ab6f1c181c47ebb7c9483950a9e9a6..0adbe8b1f8e6e992a1f991fbdba4deffbd6e15b0 100644 (file)
@@ -89,8 +89,8 @@ the paths that have disappeared from the filesystem. However,
 depending on the use case, there are several ways that can be
 done.
 
-Using "git commit -a"
-~~~~~~~~~~~~~~~~~~~~~
+Using ``git commit -a''
+~~~~~~~~~~~~~~~~~~~~~~~
 If you intend that your next commit should record all modifications
 of tracked files in the working tree and record all removals of
 files that have been removed from the working tree with `rm`
@@ -98,8 +98,8 @@ files that have been removed from the working tree with `rm`
 automatically notice and record all removals.  You can also have a
 similar effect without committing by using `git add -u`.
 
-Using "git add -A"
-~~~~~~~~~~~~~~~~~~
+Using ``git add -A''
+~~~~~~~~~~~~~~~~~~~~
 When accepting a new code drop for a vendor branch, you probably
 want to record both the removal of paths and additions of new paths
 as well as modifications of existing paths.
@@ -111,8 +111,8 @@ tree using this command:
 git ls-files -z | xargs -0 rm -f
 ----------------
 
-and then "untar" the new code in the working tree. Alternately
-you could "rsync" the changes into the working tree.
+and then untar the new code in the working tree. Alternately
+you could 'rsync' the changes into the working tree.
 
 After that, the easiest way to record all removals, additions, and
 modifications in the working tree is:
index c283084272090c28d5529d200a1147c9f57c639b..adbca12b1ec173dc8e69c4c354b3df4e7682767a 100644 (file)
@@ -292,6 +292,9 @@ have been specified, in which case default to 'compose'.
 Default is the value of 'sendemail.validate'; if this is not set,
 default to '--validate'.
 
+--force::
+       Send emails even if safety checks would prevent it.
+
 
 CONFIGURATION
 -------------
index e5a27d875eb63dbfeccbf5357983f5c94668ffeb..fbf507a7ee3694f99fb236347fc0c7f352b7e50e 100644 (file)
@@ -477,6 +477,8 @@ patterns are available:
 
 - `csharp` suitable for source code in the C# language.
 
+- `fortran` suitable for source code in the Fortran language.
+
 - `html` suitable for HTML/XHTML documents.
 
 - `java` suitable for source code in the Java language.
index 7dc2e8b0bcdfb189724ef9b2204f4e624e3be589..8416f3445a5e5d3b583733136d4211b8d0bd4084 100644 (file)
@@ -14,11 +14,8 @@ DESCRIPTION
 
 A `gitignore` file specifies intentionally untracked files that
 git should ignore.
-Note that all the `gitignore` files really concern only files
-that are not already tracked by git;
-in order to ignore uncommitted changes in already tracked files,
-please refer to the 'git update-index --assume-unchanged'
-documentation.
+Files already tracked by git are not affected; see the NOTES
+below for details.
 
 Each line in a `gitignore` file specifies a pattern.
 When deciding whether to ignore a path, git normally checks
@@ -62,7 +59,8 @@ files specified by command-line options.  Higher-level git
 tools, such as 'git status' and 'git add',
 use patterns from the sources specified above.
 
-Patterns have the following format:
+PATTERN FORMAT
+--------------
 
  - A blank line matches no files, so it can serve as a separator
    for readability.
@@ -98,7 +96,20 @@ Patterns have the following format:
    For example, "/{asterisk}.c" matches "cat-file.c" but not
    "mozilla-sha1/sha1.c".
 
-An example:
+NOTES
+-----
+
+The purpose of gitignore files is to ensure that certain files
+not tracked by git remain untracked.
+
+To ignore uncommitted changes in a file that is already tracked,
+use 'git update-index {litdd}assume-unchanged'.
+
+To stop tracking a file that is currently tracked, use
+'git rm --cached'.
+
+EXAMPLES
+--------
 
 --------------------------------------------------------------
     $ git status
@@ -140,6 +151,11 @@ Another example:
 The second .gitignore prevents git from ignoring
 `arch/foo/kernel/vmlinux.lds.S`.
 
+SEE ALSO
+--------
+linkgit:git-rm[1], linkgit:git-update-index[1],
+linkgit:gitrepository-layout[5]
+
 Documentation
 -------------
 Documentation by David Greaves, Junio C Hamano, Josh Triplett,
index 9ff9e51205ca14aef2f0e2c5936d14f715f1ea61..702306acd2c10d1cbe04c26bf3b89bafadb256f7 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.3.2
+DEF_VER=v1.7.3.3
 
 LF='
 '
diff --git a/INSTALL b/INSTALL
index 59200b730ec00a63f981691f7fd37f2eacb11653..10a1cba643cc9e6cc9a441708b1d43f468fb8383 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -67,10 +67,10 @@ Issues of note:
        - A POSIX-compliant shell is required to run many scripts needed
          for everyday use (e.g. "bisect", "pull").
 
-       - "Perl" is needed to use some of the features (e.g. preparing a
-         partial commit using "git add -i/-p", interacting with svn
-         repositories with "git svn").  If you can live without these, use
-         NO_PERL.
+       - "Perl" version 5.8 or later is needed to use some of the
+         features (e.g. preparing a partial commit using "git add -i/-p",
+         interacting with svn repositories with "git svn").  If you can
+         live without these, use NO_PERL.
 
        - "openssl" library is used by git-imap-send to use IMAP over SSL.
          If you don't need it, use NO_OPENSSL.
index c2b0d4d1266e8f3b104133da35cfcc2ec4ad97a6..a6103a01d82cdaf8081e14cd359b42b0e5098544 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.3.2.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.3.4.txt
\ No newline at end of file
index 0398d247400e55f2a2ededc054902374c7516d5b..9bf69eee0cb99fd4a8c66ee2f2bdecafe02b3b0b 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -35,7 +35,7 @@ void finish_copy_notes_for_rewrite(struct notes_rewrite_cfg *c);
 
 extern int check_pager_config(const char *cmd);
 
-extern int textconv_object(const char *path, const unsigned char *sha1, char **buf, unsigned long *buf_size);
+extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size);
 
 extern int cmd_add(int argc, const char **argv, const char *prefix);
 extern int cmd_annotate(int argc, const char **argv, const char *prefix);
index 56a4e0af6b35ea9f6d86accad27a1c87bc5ad0d9..3a5fca51590db53747f8712f733aa01e5840d8fb 100644 (file)
@@ -331,7 +331,8 @@ static struct option builtin_add_options[] = {
 
 static int add_config(const char *var, const char *value, void *cb)
 {
-       if (!strcasecmp(var, "add.ignore-errors")) {
+       if (!strcasecmp(var, "add.ignoreerrors") ||
+           !strcasecmp(var, "add.ignore-errors")) {
                ignore_add_errors = git_config_bool(var, value);
                return 0;
        }
index f051e66dcc5260e4e7ecb28c36e2c6da8e823d6b..b719f41482ee3be39d91a30f93eeabaf9d96be55 100644 (file)
@@ -449,7 +449,7 @@ static char *find_name_gnu(const char *line, char *def, int p_value)
        return squash_slash(strbuf_detach(&name, NULL));
 }
 
-static size_t tz_len(const char *line, size_t len)
+static size_t sane_tz_len(const char *line, size_t len)
 {
        const char *tz, *p;
 
@@ -467,6 +467,24 @@ static size_t tz_len(const char *line, size_t len)
        return line + len - tz;
 }
 
+static size_t tz_with_colon_len(const char *line, size_t len)
+{
+       const char *tz, *p;
+
+       if (len < strlen(" +08:00") || line[len - strlen(":00")] != ':')
+               return 0;
+       tz = line + len - strlen(" +08:00");
+
+       if (tz[0] != ' ' || (tz[1] != '+' && tz[1] != '-'))
+               return 0;
+       p = tz + 2;
+       if (!isdigit(*p++) || !isdigit(*p++) || *p++ != ':' ||
+           !isdigit(*p++) || !isdigit(*p++))
+               return 0;
+
+       return line + len - tz;
+}
+
 static size_t date_len(const char *line, size_t len)
 {
        const char *date, *p;
@@ -561,7 +579,9 @@ static size_t diff_timestamp_len(const char *line, size_t len)
        if (!isdigit(end[-1]))
                return 0;
 
-       n = tz_len(line, end - line);
+       n = sane_tz_len(line, end - line);
+       if (!n)
+               n = tz_with_colon_len(line, end - line);
        end -= n;
 
        n = short_time_len(line, end - line);
@@ -733,8 +753,8 @@ static int has_epoch_timestamp(const char *nameline)
                " "
                "[0-2][0-9]:[0-5][0-9]:00(\\.0+)?"
                " "
-               "([-+][0-2][0-9][0-5][0-9])\n";
-       const char *timestamp = NULL, *cp;
+               "([-+][0-2][0-9]:?[0-5][0-9])\n";
+       const char *timestamp = NULL, *cp, *colon;
        static regex_t *stamp;
        regmatch_t m[10];
        int zoneoffset;
@@ -764,8 +784,11 @@ static int has_epoch_timestamp(const char *nameline)
                return 0;
        }
 
-       zoneoffset = strtol(timestamp + m[3].rm_so + 1, NULL, 10);
-       zoneoffset = (zoneoffset / 100) * 60 + (zoneoffset % 100);
+       zoneoffset = strtol(timestamp + m[3].rm_so + 1, (char **) &colon, 10);
+       if (*colon == ':')
+               zoneoffset = zoneoffset * 60 + strtol(colon + 1, NULL, 10);
+       else
+               zoneoffset = (zoneoffset / 100) * 60 + (zoneoffset % 100);
        if (timestamp[m[3].rm_so] == '-')
                zoneoffset = -zoneoffset;
 
@@ -919,28 +942,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
 static int gitdiff_copysrc(const char *line, struct patch *patch)
 {
        patch->is_copy = 1;
-       patch->old_name = find_name(line, NULL, 0, 0);
+       patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
        return 0;
 }
 
 static int gitdiff_copydst(const char *line, struct patch *patch)
 {
        patch->is_copy = 1;
-       patch->new_name = find_name(line, NULL, 0, 0);
+       patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
        return 0;
 }
 
 static int gitdiff_renamesrc(const char *line, struct patch *patch)
 {
        patch->is_rename = 1;
-       patch->old_name = find_name(line, NULL, 0, 0);
+       patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
        return 0;
 }
 
 static int gitdiff_renamedst(const char *line, struct patch *patch)
 {
        patch->is_rename = 1;
-       patch->new_name = find_name(line, NULL, 0, 0);
+       patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
        return 0;
 }
 
@@ -1025,7 +1048,7 @@ static char *git_header_name(char *line, int llen)
 {
        const char *name;
        const char *second = NULL;
-       size_t len;
+       size_t len, line_len;
 
        line += strlen("diff --git ");
        llen -= strlen("diff --git ");
@@ -1125,6 +1148,10 @@ static char *git_header_name(char *line, int llen)
         * Accept a name only if it shows up twice, exactly the same
         * form.
         */
+       second = strchr(name, '\n');
+       if (!second)
+               return NULL;
+       line_len = second - name;
        for (len = 0 ; ; len++) {
                switch (name[len]) {
                default:
@@ -1132,15 +1159,11 @@ static char *git_header_name(char *line, int llen)
                case '\n':
                        return NULL;
                case '\t': case ' ':
-                       second = name+len;
-                       for (;;) {
-                               char c = *second++;
-                               if (c == '\n')
-                                       return NULL;
-                               if (c == '/')
-                                       break;
-                       }
-                       if (second[len] == '\n' && !memcmp(name, second, len)) {
+                       second = stop_at_slash(name + len, line_len - len);
+                       if (!second)
+                               return NULL;
+                       second++;
+                       if (second[len] == '\n' && !strncmp(name, second, len)) {
                                return xmemdupz(name, len);
                        }
                }
index 101535448f2b0405c280387b63f7ce82fb7dd350..f5fccc1f6767d7386e37f7273c560d0d4491ee91 100644 (file)
@@ -83,6 +83,7 @@ struct origin {
        struct commit *commit;
        mmfile_t file;
        unsigned char blob_sha1[20];
+       unsigned mode;
        char path[FLEX_ARRAY];
 };
 
@@ -92,6 +93,7 @@ struct origin {
  * Return 1 if the conversion succeeds, 0 otherwise.
  */
 int textconv_object(const char *path,
+                   unsigned mode,
                    const unsigned char *sha1,
                    char **buf,
                    unsigned long *buf_size)
@@ -100,7 +102,7 @@ int textconv_object(const char *path,
        struct userdiff_driver *textconv;
 
        df = alloc_filespec(path);
-       fill_filespec(df, sha1, S_IFREG | 0664);
+       fill_filespec(df, sha1, mode);
        textconv = get_textconv(df);
        if (!textconv) {
                free_filespec(df);
@@ -125,7 +127,7 @@ static void fill_origin_blob(struct diff_options *opt,
 
                num_read_blob++;
                if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
-                   textconv_object(o->path, o->blob_sha1, &file->ptr, &file_size))
+                   textconv_object(o->path, o->mode, o->blob_sha1, &file->ptr, &file_size))
                        ;
                else
                        file->ptr = read_sha1_file(o->blob_sha1, &type, &file_size);
@@ -313,21 +315,23 @@ static struct origin *get_origin(struct scoreboard *sb,
  * for an origin is also used to pass the blame for the entire file to
  * the parent to detect the case where a child's blob is identical to
  * that of its parent's.
+ *
+ * This also fills origin->mode for corresponding tree path.
  */
-static int fill_blob_sha1(struct origin *origin)
+static int fill_blob_sha1_and_mode(struct origin *origin)
 {
-       unsigned mode;
        if (!is_null_sha1(origin->blob_sha1))
                return 0;
        if (get_tree_entry(origin->commit->object.sha1,
                           origin->path,
-                          origin->blob_sha1, &mode))
+                          origin->blob_sha1, &origin->mode))
                goto error_out;
        if (sha1_object_info(origin->blob_sha1, NULL) != OBJ_BLOB)
                goto error_out;
        return 0;
  error_out:
        hashclr(origin->blob_sha1);
+       origin->mode = S_IFINVALID;
        return -1;
 }
 
@@ -360,12 +364,14 @@ static struct origin *find_origin(struct scoreboard *sb,
                        /*
                         * If the origin was newly created (i.e. get_origin
                         * would call make_origin if none is found in the
-                        * scoreboard), it does not know the blob_sha1,
+                        * scoreboard), it does not know the blob_sha1/mode,
                         * so copy it.  Otherwise porigin was in the
-                        * scoreboard and already knows blob_sha1.
+                        * scoreboard and already knows blob_sha1/mode.
                         */
-                       if (porigin->refcnt == 1)
+                       if (porigin->refcnt == 1) {
                                hashcpy(porigin->blob_sha1, cached->blob_sha1);
+                               porigin->mode = cached->mode;
+                       }
                        return porigin;
                }
                /* otherwise it was not very useful; free it */
@@ -400,6 +406,7 @@ static struct origin *find_origin(struct scoreboard *sb,
                /* The path is the same as parent */
                porigin = get_origin(sb, parent, origin->path);
                hashcpy(porigin->blob_sha1, origin->blob_sha1);
+               porigin->mode = origin->mode;
        } else {
                /*
                 * Since origin->path is a pathspec, if the parent
@@ -425,6 +432,7 @@ static struct origin *find_origin(struct scoreboard *sb,
                case 'M':
                        porigin = get_origin(sb, parent, origin->path);
                        hashcpy(porigin->blob_sha1, p->one->sha1);
+                       porigin->mode = p->one->mode;
                        break;
                case 'A':
                case 'T':
@@ -444,6 +452,7 @@ static struct origin *find_origin(struct scoreboard *sb,
 
                cached = make_origin(porigin->commit, porigin->path);
                hashcpy(cached->blob_sha1, porigin->blob_sha1);
+               cached->mode = porigin->mode;
                parent->util = cached;
        }
        return porigin;
@@ -486,6 +495,7 @@ static struct origin *find_rename(struct scoreboard *sb,
                    !strcmp(p->two->path, origin->path)) {
                        porigin = get_origin(sb, parent, p->one->path);
                        hashcpy(porigin->blob_sha1, p->one->sha1);
+                       porigin->mode = p->one->mode;
                        break;
                }
        }
@@ -1099,6 +1109,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
 
                        norigin = get_origin(sb, parent, p->one->path);
                        hashcpy(norigin->blob_sha1, p->one->sha1);
+                       norigin->mode = p->one->mode;
                        fill_origin_blob(&sb->revs->diffopt, norigin, &file_p);
                        if (!file_p.ptr)
                                continue;
@@ -2075,7 +2086,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
                switch (st.st_mode & S_IFMT) {
                case S_IFREG:
                        if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
-                           textconv_object(read_from, null_sha1, &buf.buf, &buf_len))
+                           textconv_object(read_from, mode, null_sha1, &buf.buf, &buf_len))
                                buf.len = buf_len;
                        else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
                                die_errno("cannot open or read '%s'", read_from);
@@ -2455,11 +2466,11 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        }
        else {
                o = get_origin(&sb, sb.final, path);
-               if (fill_blob_sha1(o))
+               if (fill_blob_sha1_and_mode(o))
                        die("no such path %s in %s", path, final_commit_name);
 
                if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) &&
-                   textconv_object(path, o->blob_sha1, (char **) &sb.final_buf,
+                   textconv_object(path, o->mode, o->blob_sha1, (char **) &sb.final_buf,
                                    &sb.final_buf_size))
                        ;
                else
index 76ec3fec9279f38520fa4b5b525ce2c03cc9cbb0..94632dbdb400f9a2986d10f06dd16119ce1b4e54 100644 (file)
@@ -143,7 +143,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
                        die("git cat-file --textconv %s: <object> must be <sha1:path>",
                            obj_name);
 
-               if (!textconv_object(obj_context.path, sha1, &buf, &size))
+               if (!textconv_object(obj_context.path, obj_context.mode, sha1, &buf, &size))
                        die("git cat-file --textconv: unable to run textconv on %s",
                            obj_name);
                break;
index b6664d49be9454b703615af4e71f92231e053e07..6c4afb5a38bc954be836c441b9b09b22ef82b132 100644 (file)
@@ -28,6 +28,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
        xmparam_t xmp = {{0}};
        int ret = 0, i = 0, to_stdout = 0;
        int quiet = 0;
+       int prefixlen = 0;
        struct option options[] = {
                OPT_BOOLEAN('p', "stdout", &to_stdout, "send results to standard output"),
                OPT_SET_INT(0, "diff3", &xmp.style, "use a diff3 based merge", XDL_MERGE_DIFF3),
@@ -65,10 +66,14 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
                                     "%s\n", strerror(errno));
        }
 
+       if (prefix)
+               prefixlen = strlen(prefix);
+
        for (i = 0; i < 3; i++) {
+               const char *fname = prefix_filename(prefix, prefixlen, argv[i]);
                if (!names[i])
                        names[i] = argv[i];
-               if (read_mmfile(mmfs + i, argv[i]))
+               if (read_mmfile(mmfs + i, fname))
                        return -1;
                if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
                        return error("Cannot merge binary files: %s\n",
index 5f65c0c8a6eacd4c6d05602ad9de2821ec62a034..d0bd651725648c01e2c4250f2533aed2c8174164 100644 (file)
@@ -233,6 +233,24 @@ static void save_state(void)
                die("not a valid object: %s", buffer.buf);
 }
 
+static void read_empty(unsigned const char *sha1, int verbose)
+{
+       int i = 0;
+       const char *args[7];
+
+       args[i++] = "read-tree";
+       if (verbose)
+               args[i++] = "-v";
+       args[i++] = "-m";
+       args[i++] = "-u";
+       args[i++] = EMPTY_TREE_SHA1_HEX;
+       args[i++] = sha1_to_hex(sha1);
+       args[i] = NULL;
+
+       if (run_command_v_opt(args, RUN_GIT_CMD))
+               die("read-tree failed");
+}
+
 static void reset_hard(unsigned const char *sha1, int verbose)
 {
        int i = 0;
@@ -993,7 +1011,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                        die("%s - not something we can merge", argv[0]);
                update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
                                DIE_ON_ERR);
-               reset_hard(remote_head->sha1, 0);
+               read_empty(remote_head->sha1, 0);
                return 0;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
index f8eba53c82242d0c435524ab9ffab70ba2e2d5ad..3cbeb299d172c51b8ab6940a836efdf8a1a8e4ce 100644 (file)
@@ -1298,9 +1298,23 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
                read_lock();
                src->data = read_sha1_file(src_entry->idx.sha1, &type, &sz);
                read_unlock();
-               if (!src->data)
+               if (!src->data) {
+                       if (src_entry->preferred_base) {
+                               static int warned = 0;
+                               if (!warned++)
+                                       warning("object %s cannot be read",
+                                               sha1_to_hex(src_entry->idx.sha1));
+                               /*
+                                * Those objects are not included in the
+                                * resulting pack.  Be resilient and ignore
+                                * them if they can't be read, in case the
+                                * pack could be created nevertheless.
+                                */
+                               return 0;
+                       }
                        die("object %s cannot be read",
                            sha1_to_hex(src_entry->idx.sha1));
+               }
                if (sz != src_size)
                        die("object %s inconsistent object length (%lu vs %lu)",
                            sha1_to_hex(src_entry->idx.sha1), sz, src_size);
index 57b51e4a0e148062e1945d640b81559d65e4c2ba..bb6e9e83b756b47dae449064ca7762fe3558fc0e 100644 (file)
@@ -547,6 +547,21 @@ static void prepare_revs(struct rev_info *revs)
                die("empty commit set passed");
 }
 
+static void read_and_refresh_cache(const char *me)
+{
+       static struct lock_file index_lock;
+       int index_fd = hold_locked_index(&index_lock, 0);
+       if (read_index_preload(&the_index, NULL) < 0)
+               die("git %s: failed to read the index", me);
+       refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);
+       if (the_index.cache_changed) {
+               if (write_index(&the_index, index_fd) ||
+                   commit_locked_index(&index_lock))
+                       die("git %s: failed to refresh the index", me);
+       }
+       rollback_lock_file(&index_lock);
+}
+
 static int revert_or_cherry_pick(int argc, const char **argv)
 {
        struct rev_info revs;
@@ -567,8 +582,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
                        die("cherry-pick --ff cannot be used with --edit");
        }
 
-       if (read_cache() < 0)
-               die("git %s: failed to read the index", me);
+       read_and_refresh_cache(me);
 
        prepare_revs(&revs);
 
index d311491e492787ae50aa172f51629abea53eec19..617a58f0583049716c7b73577ac6df0e132bebea 100644 (file)
@@ -29,8 +29,6 @@ struct tag_filter {
        struct commit_list *with_commit;
 };
 
-#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
-
 static int show_reference(const char *refname, const unsigned char *sha1,
                          int flag, void *cb_data)
 {
@@ -70,9 +68,9 @@ static int show_reference(const char *refname, const unsigned char *sha1,
                        return 0;
                }
                /* only take up to "lines" lines, and strip the signature */
+               size = parse_signature(buf, size);
                for (i = 0, sp += 2;
-                               i < filter->lines && sp < buf + size &&
-                               prefixcmp(sp, PGP_SIGNATURE "\n");
+                               i < filter->lines && sp < buf + size;
                                i++) {
                        if (i)
                                printf("\n    ");
@@ -242,8 +240,7 @@ static void write_tag_body(int fd, const unsigned char *sha1)
 {
        unsigned long size;
        enum object_type type;
-       char *buf, *sp, *eob;
-       size_t len;
+       char *buf, *sp;
 
        buf = read_sha1_file(sha1, &type, &size);
        if (!buf)
@@ -256,12 +253,7 @@ static void write_tag_body(int fd, const unsigned char *sha1)
                return;
        }
        sp += 2; /* skip the 2 LFs */
-       eob = strstr(sp, "\n" PGP_SIGNATURE "\n");
-       if (eob)
-               len = eob - sp;
-       else
-               len = buf + size - sp;
-       write_or_die(fd, sp, len);
+       write_or_die(fd, sp, parse_signature(sp, buf + size - sp));
 
        free(buf);
 }
index 9f482c29f516bde84023f401b28b133c1e605333..86cac6d715dbc29b3586e84ea28f4083ddb2a1b8 100644 (file)
@@ -17,13 +17,11 @@ static const char * const verify_tag_usage[] = {
                NULL
 };
 
-#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
-
 static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
 {
        struct child_process gpg;
        const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
-       char path[PATH_MAX], *eol;
+       char path[PATH_MAX];
        size_t len;
        int fd, ret;
 
@@ -37,11 +35,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
        close(fd);
 
        /* find the length without signature */
-       len = 0;
-       while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) {
-               eol = memchr(buf + len, '\n', size - len);
-               len += eol ? eol - (buf + len) + 1 : size - len;
-       }
+       len = parse_signature(buf, size);
        if (verbose)
                write_in_full(1, buf, len);
 
index 4b0a82040e7982ab936ed52b2bb3405bc85b80f8..9918b9351d8b8b9b33fea479bd4f4997a5d6528a 100644 (file)
--- a/config.c
+++ b/config.c
@@ -410,7 +410,7 @@ unsigned long git_config_ulong(const char *name, const char *value)
        return ret;
 }
 
-int git_config_maybe_bool(const char *name, const char *value)
+static int git_config_maybe_bool_text(const char *name, const char *value)
 {
        if (!value)
                return 1;
@@ -427,9 +427,21 @@ int git_config_maybe_bool(const char *name, const char *value)
        return -1;
 }
 
+int git_config_maybe_bool(const char *name, const char *value)
+{
+       int v = git_config_maybe_bool_text(name, value);
+       if (0 <= v)
+               return v;
+       if (!strcmp(value, "0"))
+               return 0;
+       if (!strcmp(value, "1"))
+               return 1;
+       return -1;
+}
+
 int git_config_bool_or_int(const char *name, const char *value, int *is_bool)
 {
-       int v = git_config_maybe_bool(name, value);
+       int v = git_config_maybe_bool_text(name, value);
        if (0 <= v) {
                *is_bool = 1;
                return v;
index f83f019ca91a2611f5bd3474ccf6d10081320c4c..d3037fc94eb027e5067b0371da2b33081fd89da5 100755 (executable)
@@ -255,7 +255,7 @@ __git_ps1 ()
                                (describe)
                                        git describe HEAD ;;
                                (* | default)
-                                       git describe --exact-match HEAD ;;
+                                       git describe --tags --exact-match HEAD ;;
                                esac 2>/dev/null)" ||
 
                                b="$(cut -c1-7 "$g/HEAD" 2>/dev/null)..." ||
index 4576c4a862c8ea0565a67eccdae6ef1ac4d9af9a..ead4c04d3f7ca64ed55ff605d7ee8087189a2226 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
 # This tool is copyright (c) 2005, Matthias Urlichs.
 # It is released under the Gnu Public License, version 2.
index 3a5da4ab00f2e29c3244611f40d776293e796e7d..7f3afa5ac4a4ca979a4e5dd63ebc59344f20857b 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 #
 # Copyright 2008-2009 Peter Krefting <peter@softwolves.pp.se>
 #
@@ -140,6 +140,7 @@ =head3 Revision commit message section
 
 # Globals
 use strict;
+use warnings;
 use integer;
 my $crlfmode = 0;
 my @revs;
index 85724bfc08f61d3b928460a8d2ad5ec03cf80b52..f99ea9585014face001849aeeefa5f20e79bc1e2 100755 (executable)
@@ -144,13 +144,13 @@ prep_for_email()
                        short_refname=${refname##refs/remotes/}
                        echo >&2 "*** Push-update of tracking branch, $refname"
                        echo >&2 "***  - no email generated."
-                       exit 0
+                       return 1
                        ;;
                *)
                        # Anything else (is there anything else?)
                        echo >&2 "*** Unknown type of update to $refname ($rev_type)"
                        echo >&2 "***  - no email generated"
-                       return 0
+                       return 1
                        ;;
        esac
 
@@ -166,10 +166,10 @@ prep_for_email()
                esac
                echo >&2 "*** $config_name is not set so no email will be sent"
                echo >&2 "*** for $refname update $oldrev->$newrev"
-               return 0
+               return 1
        fi
 
-       return 1
+       return 0
 }
 
 #
diff --git a/diff.c b/diff.c
index b829c033534f0631dd1a40eb0e2e1097a6f10cf4..8256f313e4a680308a7959bdd6544f5bd461846c 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -2158,7 +2158,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
 
                        ecbdata.ws_rule = data.ws_rule;
                        check_blank_at_eof(&mf1, &mf2, &ecbdata);
-                       blank_at_eof = ecbdata.blank_at_eof_in_preimage;
+                       blank_at_eof = ecbdata.blank_at_eof_in_postimage;
 
                        if (blank_at_eof) {
                                static char *err;
@@ -2391,10 +2391,14 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
        }
        else {
                enum object_type type;
-               if (size_only)
+               if (size_only) {
                        type = sha1_object_info(s->sha1, &s->size);
-               else {
+                       if (type < 0)
+                               die("unable to read %s", sha1_to_hex(s->sha1));
+               } else {
                        s->data = read_sha1_file(s->sha1, &type, &s->size);
+                       if (!s->data)
+                               die("unable to read %s", sha1_to_hex(s->sha1));
                        s->should_free = 1;
                }
        }
index de5581fe51d532231b0121bd2ef2e46669015bda..18aded6dc433ebc19c8b34e8ebcf59979a1985f6 100644 (file)
@@ -87,6 +87,7 @@ const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
 static void setup_git_env(void)
 {
        git_dir = getenv(GIT_DIR_ENVIRONMENT);
+       git_dir = git_dir ? xstrdup(git_dir) : NULL;
        if (!git_dir) {
                git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
                git_dir = git_dir ? xstrdup(git_dir) : NULL;
index 27fc79347af428dd39daa5b550814cc6cf980510..a329c5a1f8c3b63ee6976a8e0e3903a11783324b 100755 (executable)
@@ -1,6 +1,8 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
+use 5.008;
 use strict;
+use warnings;
 use Git;
 
 binmode(STDOUT, ":raw");
@@ -87,6 +89,7 @@ sub colored {
                TARGET => '',
                PARTICIPLE => 'staging',
                FILTER => 'file-only',
+               IS_REVERSE => 0,
        },
        'stash' => {
                DIFF => 'diff-index -p HEAD',
@@ -96,6 +99,7 @@ sub colored {
                TARGET => '',
                PARTICIPLE => 'stashing',
                FILTER => undef,
+               IS_REVERSE => 0,
        },
        'reset_head' => {
                DIFF => 'diff-index -p --cached',
@@ -105,6 +109,7 @@ sub colored {
                TARGET => '',
                PARTICIPLE => 'unstaging',
                FILTER => 'index-only',
+               IS_REVERSE => 1,
        },
        'reset_nothead' => {
                DIFF => 'diff-index -R -p --cached',
@@ -114,6 +119,7 @@ sub colored {
                TARGET => ' to index',
                PARTICIPLE => 'applying',
                FILTER => 'index-only',
+               IS_REVERSE => 0,
        },
        'checkout_index' => {
                DIFF => 'diff-files -p',
@@ -123,6 +129,7 @@ sub colored {
                TARGET => ' from worktree',
                PARTICIPLE => 'discarding',
                FILTER => 'file-only',
+               IS_REVERSE => 1,
        },
        'checkout_head' => {
                DIFF => 'diff-index -p',
@@ -132,6 +139,7 @@ sub colored {
                TARGET => ' from index and worktree',
                PARTICIPLE => 'discarding',
                FILTER => undef,
+               IS_REVERSE => 1,
        },
        'checkout_nothead' => {
                DIFF => 'diff-index -R -p',
@@ -141,6 +149,7 @@ sub colored {
                TARGET => ' to index and worktree',
                PARTICIPLE => 'applying',
                FILTER => undef,
+               IS_REVERSE => 0,
        },
 );
 
@@ -999,10 +1008,12 @@ sub edit_hunk_manually {
        print $fh "# Manual hunk edit mode -- see bottom for a quick guide\n";
        print $fh @$oldtext;
        my $participle = $patch_mode_flavour{PARTICIPLE};
+       my $is_reverse = $patch_mode_flavour{IS_REVERSE};
+       my ($remove_plus, $remove_minus) = $is_reverse ? ('-', '+') : ('+', '-');
        print $fh <<EOF;
 # ---
-# To remove '-' lines, make them ' ' lines (context).
-# To remove '+' lines, delete them.
+# To remove '$remove_minus' lines, make them ' ' lines (context).
+# To remove '$remove_plus' lines, delete them.
 # Lines starting with # will be removed.
 #
 # If the patch applies cleanly, the edited hunk will immediately be
index 98f3ede566a6cb0c902ce84795f7de8f8afbe633..bc32f18d6d9cbf915eb7797817390adbbc111506 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 #
 # This tool is copyright (c) 2005, Martin Langhoff.
 # It is released under the Gnu Public License, version 2.
@@ -54,6 +54,7 @@ =head1 Devel Notes
 
 =cut
 
+use 5.008;
 use strict;
 use warnings;
 use Getopt::Std;
index 59b672213bfc36f95db089f0e13bafc1c2f2ed71..39a426e067c76e01d3f2a0d63243ec494436da46 100755 (executable)
@@ -1,6 +1,8 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
+use 5.008;
 use strict;
+use warnings;
 use Getopt::Std;
 use File::Temp qw(tempdir);
 use Data::Dumper;
index 9e03eee4586ca3b7476b56f66e9dcf6ffe3088cf..249aeaf17557c4b8f05fdd5f1df5c16d65f0f84c 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 
 # This tool is copyright (c) 2005, Matthias Urlichs.
 # It is released under the Gnu Public License, version 2.
@@ -13,6 +13,7 @@
 # The head revision is on branch "origin" by default.
 # You can change that with the '-o' option.
 
+use 5.008;
 use strict;
 use warnings;
 use Getopt::Long;
index e9f3037df351ceed0262a8995f19903464163af8..2822bed1fdf6977cd415461bc48630a4996f7084 100755 (executable)
@@ -15,6 +15,7 @@
 ####
 ####
 
+use 5.008;
 use strict;
 use warnings;
 use bytes;
index adc42de8752fd395707f1e395c61991b3146cebb..e95e4ad973f21dd104950dc6ebb28485844b36f4 100755 (executable)
@@ -10,6 +10,7 @@
 #
 # Any arguments that are unknown to this script are forwarded to 'git diff'.
 
+use 5.008;
 use strict;
 use warnings;
 use Cwd qw(abs_path);
index 10a238ae3cc942bc021db18195b7098e2866c266..6a7e5e0b1884358566544cc8cd0d94c941dac5fc 100755 (executable)
@@ -49,7 +49,8 @@ do_merge=
 dotest="$GIT_DIR"/rebase-merge
 prec=4
 verbose=
-diffstat=$(git config --bool rebase.stat)
+diffstat=
+test "$(git config --bool rebase.stat)" = true && diffstat=t
 git_am_opt=
 rebase_root=
 force_rebase=
@@ -274,15 +275,16 @@ do
                        die "No rebase in progress?"
 
                git rerere clear
-               if test -d "$dotest"
-               then
-                       GIT_QUIET=$(cat "$dotest/quiet")
-                       move_to_original_branch
-               else
-                       dotest="$GIT_DIR"/rebase-apply
-                       GIT_QUIET=$(cat "$dotest/quiet")
-                       move_to_original_branch
-               fi
+
+               test -d "$dotest" || dotest="$GIT_DIR"/rebase-apply
+
+               head_name="$(cat "$dotest"/head-name)" &&
+               case "$head_name" in
+               refs/*)
+                       git symbolic-ref HEAD $head_name ||
+                       die "Could not move back to $head_name"
+                       ;;
+               esac
                git reset --hard $(cat "$dotest/orig-head")
                rm -r "$dotest"
                exit
index c2a0ef8d5a2794a45908cbcfff1b419ebfc17f8e..e136732cea80c1594ac02c93cf246e8c77ff89b8 100755 (executable)
@@ -6,7 +6,7 @@
 #
 # Scan two git object-trees, and hardlink any common objects between them.
 
-use 5.006;
+use 5.008;
 use strict;
 use warnings;
 use Getopt::Long;
index 81b2ea5633a9692f52af67ab8bfd42b68781cf4d..c1d8edbdd324fc1eca7bc475cbf31bd913036682 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
 #
 # Copyright 2002,2005 Greg Kroah-Hartman <greg@kroah.com>
 # Copyright 2005 Ryan Anderson <ryan@michonline.com>
@@ -16,6 +16,7 @@
 #    and second line is the subject of the message.
 #
 
+use 5.008;
 use strict;
 use warnings;
 use Term::ReadLine;
index 18cfb2466d11aa28a795e3dabac70e236061fbe9..757de82161e05b9d12c489efeff05c7fec341fe4 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env perl
 # Copyright (C) 2006, Eric Wong <normalperson@yhbt.net>
 # License: GPL v2 or later
+use 5.008;
 use warnings;
 use strict;
 use vars qw/   $AUTHOR $VERSION
index a85e2f63197649bff4842ea2970448205618c104..e645d4a821f7eab28911f508923abd3e9a9dc53b 100755 (executable)
@@ -7,6 +7,7 @@
 #
 # This program is licensed under the GPLv2
 
+use 5.008;
 use strict;
 use warnings;
 use CGI qw(:standard :escapeHTML -nosticky);
diff --git a/http.c b/http.c
index 0a5011f615bdfade0b69682b177dc97471ac20a3..f582b13b915e58a189086cdec2bab6dbb94eac6a 100644 (file)
--- a/http.c
+++ b/http.c
@@ -2,6 +2,7 @@
 #include "pack.h"
 #include "sideband.h"
 #include "run-command.h"
+#include "url.h"
 
 int data_received;
 int active_requests;
@@ -279,6 +280,11 @@ static CURL *get_curl_handle(void)
        }
 
        curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1);
+#if LIBCURL_VERSION_NUM >= 0x071301
+       curl_easy_setopt(result, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
+#elif LIBCURL_VERSION_NUM >= 0x071101
+       curl_easy_setopt(result, CURLOPT_POST301, 1);
+#endif
 
        if (getenv("GIT_CURL_VERBOSE"))
                curl_easy_setopt(result, CURLOPT_VERBOSE, 1);
@@ -297,7 +303,7 @@ static CURL *get_curl_handle(void)
 
 static void http_auth_init(const char *url)
 {
-       char *at, *colon, *cp, *slash;
+       char *at, *colon, *cp, *slash, *decoded;
        int len;
 
        cp = strstr(url, "://");
@@ -322,16 +328,25 @@ static void http_auth_init(const char *url)
                user_name = xmalloc(len + 1);
                memcpy(user_name, cp, len);
                user_name[len] = '\0';
+               decoded = url_decode(user_name);
+               free(user_name);
+               user_name = decoded;
                user_pass = NULL;
        } else {
                len = colon - cp;
                user_name = xmalloc(len + 1);
                memcpy(user_name, cp, len);
                user_name[len] = '\0';
+               decoded = url_decode(user_name);
+               free(user_name);
+               user_name = decoded;
                len = at - (colon + 1);
                user_pass = xmalloc(len + 1);
                memcpy(user_pass, colon + 1, len);
                user_pass[len] = '\0';
+               decoded = url_decode(user_pass);
+               free(user_pass);
+               user_pass = decoded;
        }
 }
 
index 6cb0dd19344ba1169b23b7e4949033f8a9088a00..205e48aa3a7b912005565ac9c296205a897a1476 100644 (file)
@@ -7,6 +7,7 @@ =head1 NAME
 
 package Git;
 
+use 5.008;
 use strict;
 
 
index 4879615cad7527dc5346cd1a85bd56b9d11e052b..5d81d39a525830f6bacba88143ab6a4552748441 100644 (file)
@@ -239,7 +239,6 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
 
        commit->parents = xcalloc(sizeof(struct commit_list), 1);
        commit->parents->item = commit_info->commit;
-       commit->object.flags &= ~(ADDED | SEEN | SHOWN);
 }
 
 void get_reflog_selector(struct strbuf *sb,
index b1c18906badc5fc4ce3af48daa7c226365e3c08f..ded881263ba0ff703d9fd468e6785270ea68df5f 100644 (file)
@@ -2030,8 +2030,10 @@ static struct commit *get_revision_1(struct rev_info *revs)
                revs->commits = entry->next;
                free(entry);
 
-               if (revs->reflog_info)
+               if (revs->reflog_info) {
                        fake_reflog_parent(revs->reflog_info, commit);
+                       commit->object.flags &= ~(ADDED | SEEN | SHOWN);
+               }
 
                /*
                 * If we haven't done the list limiting, we need to look at
diff --git a/setup.c b/setup.c
index a3b76de2bb1c18e2f3b8cdf5799c3c650b16d027..346ef2eb2d678b742280c0816a09b8ca174ca799 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -46,7 +46,7 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
 {
        static char path[PATH_MAX];
 #ifndef WIN32
-       if (!pfx || !*pfx || is_absolute_path(arg))
+       if (!pfx_len || is_absolute_path(arg))
                return arg;
        memcpy(path, pfx, pfx_len);
        strcpy(path + pfx_len, arg);
@@ -55,7 +55,7 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
        /* don't add prefix to absolute paths, but still replace '\' by '/' */
        if (is_absolute_path(arg))
                pfx_len = 0;
-       else
+       else if (pfx_len)
                memcpy(path, pfx, pfx_len);
        strcpy(path + pfx_len, arg);
        for (p = path + pfx_len; *p; p++)
index 484081de82928108a23a714a76ea88693e56bdd1..3e856b80369c289a3d9399d60ec3be22bbbc6788 100644 (file)
@@ -1069,6 +1069,7 @@ int get_sha1_with_context_1(const char *name, unsigned char *sha1,
                struct cache_entry *ce;
                int pos;
                if (namelen > 2 && name[1] == '/')
+                       /* don't need mode for commit */
                        return get_sha1_oneline(name + 2, sha1);
                if (namelen < 3 ||
                    name[2] != ':' ||
@@ -1096,6 +1097,7 @@ int get_sha1_with_context_1(const char *name, unsigned char *sha1,
                                break;
                        if (ce_stage(ce) == stage) {
                                hashcpy(sha1, ce->sha1);
+                               oc->mode = ce->ce_mode;
                                return 0;
                        }
                        pos++;
index 81ef2a0969d98f05ce22cd8a06fcb55a7af9aee8..1b9523d02f3a8e785b0823a1d58dfaa22837ba39 100644 (file)
@@ -80,7 +80,7 @@ if ! test_have_prereq PERL; then
        test_done
 fi
 
-perl -MEncode -e 'decode_utf8("", Encode::FB_CROAK)' >/dev/null 2>&1 || {
+perl -MEncode -e '$e="";decode_utf8($e, Encode::FB_CROAK)' >/dev/null 2>&1 || {
     skip_all='skipping gitweb tests, perl version is too old'
     test_done
 }
index e733f6516fdf98e48d5c7cd36ecc89d36166eea1..3f24384371bf227126e38da61f3b7efd3961ede8 100644 (file)
@@ -75,12 +75,14 @@ fi
 
 prepare_httpd() {
        mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH"
+       cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH"
 
        ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"
 
        if test -n "$LIB_HTTPD_SSL"
        then
                HTTPD_URL=https://127.0.0.1:$LIB_HTTPD_PORT
+               AUTH_HTTPD_URL=https://user%40host:user%40host@127.0.0.1:$LIB_HTTPD_PORT
 
                RANDFILE_PATH="$HTTPD_ROOT_PATH"/.rnd openssl req \
                        -config "$TEST_PATH/ssl.cnf" \
@@ -92,6 +94,7 @@ prepare_httpd() {
                HTTPD_PARA="$HTTPD_PARA -DSSL"
        else
                HTTPD_URL=http://127.0.0.1:$LIB_HTTPD_PORT
+               AUTH_HTTPD_URL=http://user%40host:user%40host@127.0.0.1:$LIB_HTTPD_PORT
        fi
 
        if test -n "$LIB_HTTPD_DAV" -o -n "$LIB_HTTPD_SVN"
index 4961505d1dd99da529b43abd42522e6a005961b1..0a4cdfa93ece7d8a4177835b5569583c22303564 100644 (file)
@@ -17,8 +17,33 @@ ErrorLog error.log
 <IfModule !mod_env.c>
        LoadModule env_module modules/mod_env.so
 </IfModule>
+<IfModule !mod_rewrite.c>
+       LoadModule rewrite_module modules/mod_rewrite.so
+</IFModule>
+<IfModule !mod_version.c>
+       LoadModule version_module modules/mod_version.so
+</IfModule>
+
+<IfVersion < 2.1>
+<IfModule !mod_auth.c>
+       LoadModule auth_module modules/mod_auth.so
+</IfModule>
+</IfVersion>
+
+<IfVersion >= 2.1>
+<IfModule !mod_auth_basic.c>
+       LoadModule auth_basic_module modules/mod_auth_basic.so
+</IfModule>
+<IfModule !mod_authn_file.c>
+       LoadModule authn_file_module modules/mod_authn_file.so
+</IfModule>
+<IfModule !mod_authz_user.c>
+       LoadModule authz_user_module modules/mod_authz_user.so
+</IfModule>
+</IfVersion>
 
 Alias /dumb/ www/
+Alias /auth/ www/auth/
 
 <Location /smart/>
        SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
@@ -36,6 +61,10 @@ ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/
        Options ExecCGI
 </Files>
 
+RewriteEngine on
+RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301]
+RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302]
+
 <IfDefine SSL>
 LoadModule ssl_module modules/mod_ssl.so
 
@@ -48,6 +77,13 @@ SSLMutex file:ssl_mutex
 SSLEngine On
 </IfDefine>
 
+<Location /auth/>
+       AuthType Basic
+       AuthName "git-auth"
+       AuthUserFile passwd
+       Require valid-user
+</Location>
+
 <IfDefine DAV>
        LoadModule dav_module modules/mod_dav.so
        LoadModule dav_fs_module modules/mod_dav_fs.so
diff --git a/t/lib-httpd/passwd b/t/lib-httpd/passwd
new file mode 100644 (file)
index 0000000..f2fbcad
--- /dev/null
@@ -0,0 +1 @@
+user@host:nKpa8pZUHx/ic
diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh
new file mode 100755 (executable)
index 0000000..7f519e5
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+test_description='reflog walk shows repeated commits again'
+. ./test-lib.sh
+
+test_expect_success 'setup commits' '
+       test_tick &&
+       echo content >file && git add file && git commit -m one &&
+       git tag one &&
+       echo content >>file && git add file && git commit -m two &&
+       git tag two
+'
+
+test_expect_success 'setup reflog with alternating commits' '
+       git checkout -b topic &&
+       git reset one &&
+       git reset two &&
+       git reset one &&
+       git reset two
+'
+
+test_expect_success 'reflog shows all entries' '
+       cat >expect <<-\EOF
+               topic@{0} two: updating HEAD
+               topic@{1} one: updating HEAD
+               topic@{2} two: updating HEAD
+               topic@{3} one: updating HEAD
+               topic@{4} branch: Created from HEAD
+       EOF
+       git log -g --format="%gd %gs" topic >actual &&
+       test_cmp expect actual
+'
+
+test_done
index fbb3f2e0dfcf1a0673dbd2022a4ed843990fce52..e573dc845b3d72004b2a96f344528c68977c52e1 100755 (executable)
@@ -72,6 +72,18 @@ testrebase() {
                test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) &&
                test ! -d "$dotest"
        '
+
+       test_expect_success "rebase$type --abort does not update reflog" '
+               cd "$work_dir" &&
+               # Clean up the state from the previous one
+               git reset --hard pre-rebase &&
+               git reflog show to-rebase > reflog_before &&
+               test_must_fail git rebase$type master &&
+               git rebase --abort &&
+               git reflog show to-rebase > reflog_after &&
+               test_cmp reflog_before reflog_after &&
+               rm reflog_before reflog_after
+       '
 }
 
 testrebase "" .git/rebase-apply
index bc7aedd0484ed5ad1115cac0f22943445d658f47..043954422c82d9afbb318bcb7d1aa5685a391c85 100755 (executable)
@@ -81,6 +81,16 @@ test_expect_success 'revert after renaming branch' '
 
 '
 
+test_expect_success 'cherry-pick on stat-dirty working tree' '
+       git clone . copy &&
+       (
+               cd copy &&
+               git checkout initial &&
+               test-chmtime +40 oops &&
+               git cherry-pick added
+       )
+'
+
 test_expect_success 'revert forbidden on dirty working tree' '
 
        echo content >extra_file &&
index c8e19372b00f128646b809e1f5723d88b58a3f30..0a61b57b5f6f00ae4c0734a34ce45c0ba1fcf098 100755 (executable)
@@ -32,7 +32,7 @@ EOF
 
 sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java
 
-builtin_patterns="bibtex cpp csharp html java objc pascal php python ruby tex"
+builtin_patterns="bibtex cpp csharp fortran html java objc pascal php python ruby tex"
 for p in $builtin_patterns
 do
        test_expect_success "builtin $p pattern compiles" '
index f6d1f1ebab406fcd4f405178ec151149754500b0..87df0aeb59ecb22f07454ce08172f8cfa4940591 100755 (executable)
@@ -178,6 +178,15 @@ test_expect_success 'trailing empty lines (2)' '
 
 '
 
+test_expect_success 'checkdiff shows correct line number for trailing blank lines' '
+
+       printf "a\nb\n" > G &&
+       git add G &&
+       printf "x\nx\nx\na\nb\nc\n\n" > G &&
+       [ "$(git diff --check -- G)" = "G:7: new blank line at EOF." ]
+
+'
+
 test_expect_success 'do not color trailing cr in context' '
        git config --unset core.whitespace
        rm -f .gitattributes &&
index 2b2d00b33410282b6decd0af9118ee3f79489e34..579c9e61054521301464bfc31351040d45966836 100755 (executable)
@@ -56,4 +56,30 @@ test_expect_success 'apply with too large -p and fancy filename' '
        grep "removing 3 leading" err
 '
 
+test_expect_success 'apply (-p2) diff, mode change only' '
+       cat >patch.chmod <<-\EOF &&
+       diff --git a/sub/file1 b/sub/file1
+       old mode 100644
+       new mode 100755
+       EOF
+       chmod 644 file1 &&
+       git apply -p2 patch.chmod &&
+       test -x file1
+'
+
+test_expect_success 'apply (-p2) diff, rename' '
+       cat >patch.rename <<-\EOF &&
+       diff --git a/sub/file1 b/sub/file2
+       similarity index 100%
+       rename from sub/file1
+       rename to sub/file2
+       EOF
+       echo A >expected &&
+
+       cp file1.saved file1 &&
+       rm -f file2 &&
+       git apply -p2 patch.rename &&
+       test_cmp expected file2
+'
+
 test_done
index bb1ffe3b6cfe491137b34993fe2e3bed99908dff..a2bc1cd37d852a9cab79c946bf88ee9dc958b460 100755 (executable)
@@ -30,6 +30,7 @@ test_expect_success setup '
        epocWest="1969-12-31 16:00:00.000000000 -0800" &&
         epocGMT="1970-01-01 00:00:00.000000000 +0000" &&
        epocEast="1970-01-01 09:00:00.000000000 +0900" &&
+       epocWest2="1969-12-31 16:00:00 -08:00" &&
 
        sed -e "s/TS0/$epocWest/" -e "s/TS1/$timeWest/" <c >createWest.patch &&
        sed -e "s/TS0/$epocEast/" -e "s/TS1/$timeEast/" <c >createEast.patch &&
@@ -46,6 +47,7 @@ test_expect_success setup '
        sed -e "s/TS0/$timeWest/" -e "s/TS1/$epocWest/" <d >removeWest.patch &&
        sed -e "s/TS0/$timeEast/" -e "s/TS1/$epocEast/" <d >removeEast.patch &&
        sed -e "s/TS0/$timeGMT/" -e "s/TS1/$epocGMT/" <d >removeGMT.patch &&
+       sed -e "s/TS0/$timeWest/" -e "s/TS1/$epocWest2/" <d >removeWest2.patch &&
 
        echo something >something &&
        >empty
index 1e5aad57ab799819c6f319eaf813149d8bdda136..bf5dc57286493b0b94caf927304e92db11e54f2c 100755 (executable)
@@ -72,4 +72,20 @@ test_expect_success 'whitespace-damaged traditional patch' '
        test_cmp expected postimage.txt
 '
 
+test_expect_success 'traditional patch with colon in timezone' '
+       echo postimage >expected &&
+       reset_preimage &&
+       rm -f "post image.txt" &&
+       git apply "$vector/funny-tz.diff" &&
+       test_cmp expected "post image.txt"
+'
+
+test_expect_success 'traditional, whitespace-damaged, colon in timezone' '
+       echo postimage >expected &&
+       reset_preimage &&
+       rm -f "post image.txt" &&
+       git apply "$vector/damaged-tz.diff" &&
+       test_cmp expected "post image.txt"
+'
+
 test_done
diff --git a/t/t4135/damaged-tz.diff b/t/t4135/damaged-tz.diff
new file mode 100644 (file)
index 0000000..07aaf08
--- /dev/null
@@ -0,0 +1,5 @@
+diff -urN -X /usr/people/jes/exclude-linux linux-2.6.12-rc2-mm3-vanilla/post image.txt linux-2.6.12-rc2-mm3/post image.txt
+--- linux-2.6.12-rc2-mm3-vanilla/post image.txt 1969-12-31 16:00:00 -08:00
++++ linux-2.6.12-rc2-mm3/post image.txt 2005-04-12 02:14:06 -07:00
+@@ -0,0 +1 @@
++postimage
diff --git a/t/t4135/funny-tz.diff b/t/t4135/funny-tz.diff
new file mode 100644 (file)
index 0000000..998e3a8
--- /dev/null
@@ -0,0 +1,5 @@
+diff -urN -X /usr/people/jes/exclude-linux linux-2.6.12-rc2-mm3-vanilla/post image.txt linux-2.6.12-rc2-mm3/post image.txt
+--- linux-2.6.12-rc2-mm3-vanilla/post image.txt        1969-12-31 16:00:00 -08:00
++++ linux-2.6.12-rc2-mm3/post image.txt        2005-04-12 02:14:06 -07:00
+@@ -0,0 +1 @@
++postimage
index 2e513569477bb5efc389a2088a4d896620e50b8f..2043bb8867cec2c2b4a431cca1f5762f10fa5ba5 100755 (executable)
@@ -421,6 +421,15 @@ test_expect_success 'log.decorate configuration' '
        git log --oneline --decorate=full >actual &&
        test_cmp expect.full actual &&
 
+       git config --unset-all log.decorate &&
+       git config log.decorate 1 &&
+       git log --oneline >actual &&
+       test_cmp expect.short actual &&
+       git log --oneline --decorate=full >actual &&
+       test_cmp expect.full actual &&
+       git log --oneline --decorate=no >actual &&
+       test_cmp expect.none actual &&
+
        git config --unset-all log.decorate &&
        git config log.decorate short &&
        git log --oneline >actual &&
index 2fb48d09edb47129d9cea8b9686e46a6d8f35615..8c2ac353b7736c4bce7ed71333284863d9c4e514 100755 (executable)
@@ -34,6 +34,13 @@ test_expect_success 'clone http repository' '
        test_cmp file clone/file
 '
 
+test_expect_success 'clone http repository with authentication' '
+       mkdir "$HTTPD_DOCUMENT_ROOT_PATH/auth/" &&
+       cp -Rf "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" "$HTTPD_DOCUMENT_ROOT_PATH/auth/repo.git" &&
+       git clone $AUTH_HTTPD_URL/auth/repo.git clone-auth &&
+       test_cmp file clone-auth/file
+'
+
 test_expect_success 'fetch changes via http' '
        echo content >>file &&
        git commit -a -m two &&
index fd19121372aecc0806e17e62d639855f391045d3..26d355725f5e8d317c71cb466ea091ec8f741d63 100755 (executable)
@@ -101,5 +101,13 @@ test_expect_success 'used upload-pack service' '
        test_cmp exp act
 '
 
+test_expect_success 'follow redirects (301)' '
+       git clone $HTTPD_URL/smart-redir-perm/repo.git --quiet repo-p
+'
+
+test_expect_success 'follow redirects (302)' '
+       git clone $HTTPD_URL/smart-redir-temp/repo.git --quiet repo-t
+'
+
 stop_httpd
 test_done
index d486d73994cf563063b578ec5e212331e87bf67f..d9f343942c7eb9d1e80e98db2252cb29135544fa 100755 (executable)
@@ -64,6 +64,14 @@ cp new1.txt test.txt
 test_expect_success "merge without conflict" \
        "git merge-file test.txt orig.txt new2.txt"
 
+test_expect_success 'works in subdirectory' '
+       mkdir dir &&
+       cp new1.txt dir/a.txt &&
+       cp orig.txt dir/o.txt &&
+       cp new2.txt dir/b.txt &&
+       ( cd dir && git merge-file a.txt o.txt b.txt )
+'
+
 cp new1.txt test.txt
 test_expect_success "merge without conflict (--quiet)" \
        "git merge-file --quiet test.txt orig.txt new2.txt"
index ac943f5eeecd17dd1edc5834265df9e16e5032f2..6841c23c0a276934928aed65aef4a55cb55370e1 100755 (executable)
@@ -1030,6 +1030,72 @@ test_expect_success GPG \
        test_cmp expect actual
 '
 
+# usage with rfc1991 signatures
+echo "rfc1991" > gpghome/gpg.conf
+get_tag_header rfc1991-signed-tag $commit commit $time >expect
+echo "RFC1991 signed tag" >>expect
+echo '-----BEGIN PGP MESSAGE-----' >>expect
+test_expect_success GPG \
+       'creating a signed tag with rfc1991' '
+       git tag -s -m "RFC1991 signed tag" rfc1991-signed-tag $commit &&
+       get_tag_msg rfc1991-signed-tag >actual &&
+       test_cmp expect actual
+'
+
+cat >fakeeditor <<'EOF'
+#!/bin/sh
+cp "$1" actual
+EOF
+chmod +x fakeeditor
+
+test_expect_success GPG \
+       'reediting a signed tag body omits signature' '
+       echo "RFC1991 signed tag" >expect &&
+       GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&
+       test_cmp expect actual
+'
+
+test_expect_success GPG \
+       'verifying rfc1991 signature' '
+       git tag -v rfc1991-signed-tag
+'
+
+test_expect_success GPG \
+       'list tag with rfc1991 signature' '
+       echo "rfc1991-signed-tag RFC1991 signed tag" >expect &&
+       git tag -l -n1 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n2 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n999 rfc1991-signed-tag >actual &&
+       test_cmp expect actual
+'
+
+rm -f gpghome/gpg.conf
+
+test_expect_success GPG \
+       'verifying rfc1991 signature without --rfc1991' '
+       git tag -v rfc1991-signed-tag
+'
+
+test_expect_success GPG \
+       'list tag with rfc1991 signature without --rfc1991' '
+       echo "rfc1991-signed-tag RFC1991 signed tag" >expect &&
+       git tag -l -n1 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n2 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n999 rfc1991-signed-tag >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success GPG \
+       'reediting a signed tag body omits signature' '
+       echo "RFC1991 signed tag" >expect &&
+       GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&
+       test_cmp expect actual
+'
+
 # try to sign with bad user.signingkey
 git config user.signingkey BobTheMouse
 test_expect_success GPG \
index 73ff80937195f3ee8d4bf647a6c06bef23bb8891..6b5f22ae4a3ca96a22fa0a7d77bac1b59e747b00 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/perl
+use 5.008;
 use strict;
 use warnings;
 use IO::Pty;
index d82349a6a8d6c12c3ca4398a18bd6c1dd42efdc9..3988900fc33f0f5f9cdd416096df619aec2d577e 100755 (executable)
@@ -84,4 +84,20 @@ test_expect_success 'will not overwrite removed file with staged changes' '
        test_cmp important c1.c
 '
 
+cat >expect <<\EOF
+error: Untracked working tree file 'c0.c' would be overwritten by merge.
+fatal: read-tree failed
+EOF
+
+test_expect_success 'will not overwrite untracked file on unborn branch' '
+       git reset --hard c0 &&
+       git rm -fr . &&
+       git checkout --orphan new &&
+       cp important c0.c &&
+       test_must_fail git merge c0 2>out &&
+       test_cmp out expect &&
+       test_path_is_missing .git/MERGE_HEAD &&
+       test_cmp important c0.c
+'
+
 test_done
index 9ad96d4d32390081ba97c336d80b2294cf69dc44..dbf623bce5598860800fa463c26ec8145d6e2400 100755 (executable)
@@ -9,22 +9,29 @@ find_blame() {
 
 cat >helper <<'EOF'
 #!/bin/sh
-sed 's/^/converted: /' "$@"
+grep -q '^bin: ' "$1" || { echo "E: $1 is not \"binary\" file" 1>&2; exit 1; }
+sed 's/^bin: /converted: /' "$1"
 EOF
 chmod +x helper
 
 test_expect_success 'setup ' '
-       echo test 1 >one.bin &&
-       echo test number 2 >two.bin &&
+       echo "bin: test 1" >one.bin &&
+       echo "bin: test number 2" >two.bin &&
+       if test_have_prereq SYMLINKS; then
+               ln -s one.bin symlink.bin
+       fi &&
        git add . &&
        GIT_AUTHOR_NAME=Number1 git commit -a -m First --date="2010-01-01 18:00:00" &&
-       echo test 1 version 2 >one.bin &&
-       echo test number 2 version 2 >>two.bin &&
+       echo "bin: test 1 version 2" >one.bin &&
+       echo "bin: test number 2 version 2" >>two.bin &&
+       if test_have_prereq SYMLINKS; then
+               ln -sf two.bin symlink.bin
+       fi &&
        GIT_AUTHOR_NAME=Number2 git commit -a -m Second --date="2010-01-01 20:00:00"
 '
 
 cat >expected <<EOF
-(Number2 2010-01-01 20:00:00 +0000 1) test 1 version 2
+(Number2 2010-01-01 20:00:00 +0000 1) bin: test 1 version 2
 EOF
 
 test_expect_success 'no filter specified' '
@@ -67,7 +74,7 @@ test_expect_success 'blame --textconv going through revisions' '
 '
 
 test_expect_success 'make a new commit' '
-       echo "test number 2 version 3" >>two.bin &&
+       echo "bin: test number 2 version 3" >>two.bin &&
        GIT_AUTHOR_NAME=Number3 git commit -a -m Third --date="2010-01-01 22:00:00"
 '
 
@@ -77,4 +84,45 @@ test_expect_success 'blame from previous revision' '
        test_cmp expected result
 '
 
+cat >expected <<EOF
+(Number2 2010-01-01 20:00:00 +0000 1) two.bin
+EOF
+
+test_expect_success SYMLINKS 'blame with --no-textconv (on symlink)' '
+       git blame --no-textconv symlink.bin >blame &&
+       find_blame <blame >result &&
+       test_cmp expected result
+'
+
+test_expect_success SYMLINKS 'blame --textconv (on symlink)' '
+       git blame --textconv symlink.bin >blame &&
+       find_blame <blame >result &&
+       test_cmp expected result
+'
+
+# cp two.bin three.bin  and make small tweak
+# (this will direct blame -C -C three.bin to consider two.bin and symlink.bin)
+test_expect_success SYMLINKS 'make another new commit' '
+       cat >three.bin <<\EOF &&
+bin: test number 2
+bin: test number 2 version 2
+bin: test number 2 version 3
+bin: test number 3
+EOF
+       git add three.bin &&
+       GIT_AUTHOR_NAME=Number4 git commit -a -m Fourth --date="2010-01-01 23:00:00"
+'
+
+test_expect_success SYMLINKS 'blame on last commit (-C -C, symlink)' '
+       git blame -C -C three.bin >blame &&
+       find_blame <blame >result &&
+       cat >expected <<\EOF &&
+(Number1 2010-01-01 18:00:00 +0000 1) converted: test number 2
+(Number2 2010-01-01 20:00:00 +0000 2) converted: test number 2 version 2
+(Number3 2010-01-01 22:00:00 +0000 3) converted: test number 2 version 3
+(Number4 2010-01-01 23:00:00 +0000 4) converted: test number 3
+EOF
+       test_cmp expected result
+'
+
 test_done
index 38ac05e4a0b62e9105a400b4583d5504b42b3e7d..78a0085e648b8fa6773b47e86959853cf29ccdf9 100755 (executable)
@@ -5,15 +5,19 @@ test_description='git cat-file textconv support'
 
 cat >helper <<'EOF'
 #!/bin/sh
-sed 's/^/converted: /' "$@"
+grep -q '^bin: ' "$1" || { echo "E: $1 is not \"binary\" file" 1>&2; exit 1; }
+sed 's/^bin: /converted: /' "$1"
 EOF
 chmod +x helper
 
 test_expect_success 'setup ' '
-       echo test >one.bin &&
+       echo "bin: test" >one.bin &&
+       if test_have_prereq SYMLINKS; then
+               ln -s one.bin symlink.bin
+       fi &&
        git add . &&
        GIT_AUTHOR_NAME=Number1 git commit -a -m First --date="2010-01-01 18:00:00" &&
-       echo test version 2 >one.bin &&
+       echo "bin: test version 2" >one.bin &&
        GIT_AUTHOR_NAME=Number2 git commit -a -m Second --date="2010-01-01 20:00:00"
 '
 
@@ -33,7 +37,7 @@ test_expect_success 'setup textconv filters' '
 '
 
 cat >expected <<EOF
-test version 2
+bin: test version 2
 EOF
 
 test_expect_success 'cat-file without --textconv' '
@@ -42,7 +46,7 @@ test_expect_success 'cat-file without --textconv' '
 '
 
 cat >expected <<EOF
-test
+bin: test
 EOF
 
 test_expect_success 'cat-file without --textconv on previous commit' '
@@ -67,4 +71,28 @@ test_expect_success 'cat-file --textconv on previous commit' '
        git cat-file --textconv HEAD^:one.bin >result &&
        test_cmp expected result
 '
+
+test_expect_success SYMLINKS 'cat-file without --textconv (symlink)' '
+       git cat-file blob :symlink.bin >result &&
+       printf "%s" "one.bin" >expected
+       test_cmp expected result
+'
+
+
+test_expect_success SYMLINKS 'cat-file --textconv on index (symlink)' '
+       ! git cat-file --textconv :symlink.bin 2>result &&
+       cat >expected <<\EOF &&
+fatal: git cat-file --textconv: unable to run textconv on :symlink.bin
+EOF
+       test_cmp expected result
+'
+
+test_expect_success SYMLINKS 'cat-file --textconv on HEAD (symlink)' '
+       ! git cat-file --textconv HEAD:symlink.bin 2>result &&
+       cat >expected <<EOF &&
+fatal: git cat-file --textconv: unable to run textconv on HEAD:symlink.bin
+EOF
+       test_cmp expected result
+'
+
 test_done
index 671f38db2bb78c076b281602ca5b87f10fdf4d00..c15ca2d6479a814d7649a38a671a554b6ed8b68f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use lib (split(/:/, $ENV{GITPERLLIB}));
 
-use 5.006002;
+use 5.008;
 use warnings;
 use strict;
 
diff --git a/tag.c b/tag.c
index 28641cf85a0d32357269129f0e8b92bb9e21f399..f789744ccaf5d5fb6f63ba0911a869492affc162 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -4,6 +4,9 @@
 #include "tree.h"
 #include "blob.h"
 
+#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
+#define PGP_MESSAGE "-----BEGIN PGP MESSAGE-----"
+
 const char *tag_type = "tag";
 
 struct object *deref_tag(struct object *o, const char *warn, int warnlen)
@@ -133,3 +136,15 @@ int parse_tag(struct tag *item)
        free(data);
        return ret;
 }
+
+size_t parse_signature(const char *buf, unsigned long size)
+{
+       char *eol;
+       size_t len = 0;
+       while (len < size && prefixcmp(buf + len, PGP_SIGNATURE) &&
+                       prefixcmp(buf + len, PGP_MESSAGE)) {
+               eol = memchr(buf + len, '\n', size - len);
+               len += eol ? eol - (buf + len) + 1 : size - len;
+       }
+       return len;
+}
diff --git a/tag.h b/tag.h
index 47662724a6d7d07eeeacd5c8528d94d750ecf878..85223700396f5ddb00c046a1a9fdb63c92aae40e 100644 (file)
--- a/tag.h
+++ b/tag.h
@@ -16,5 +16,6 @@ extern struct tag *lookup_tag(const unsigned char *sha1);
 extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size);
 extern int parse_tag(struct tag *item);
 extern struct object *deref_tag(struct object *, const char *, int);
+extern size_t parse_signature(const char *buf, unsigned long size);
 
 #endif /* TAG_H */
index e5522159b362811346b4306246391e960a4e7041..f9e05b548c2fdbc349a1d47d81619e266ec9fb83 100644 (file)
@@ -9,7 +9,23 @@ static int drivers_alloc;
 
 #define PATTERNS(name, pattern, word_regex)                    \
        { name, NULL, -1, { pattern, REG_EXTENDED }, word_regex }
+#define IPATTERN(name, pattern, word_regex)                    \
+       { name, NULL, -1, { pattern, REG_EXTENDED | REG_ICASE }, word_regex }
 static struct userdiff_driver builtin_drivers[] = {
+IPATTERN("fortran",
+        "!^([C*]|[ \t]*!)\n"
+        "!^[ \t]*MODULE[ \t]+PROCEDURE[ \t]\n"
+        "^[ \t]*((END[ \t]+)?(PROGRAM|MODULE|BLOCK[ \t]+DATA"
+               "|([^'\" \t]+[ \t]+)*(SUBROUTINE|FUNCTION))[ \t]+[A-Z].*)$",
+        /* -- */
+        "[a-zA-Z][a-zA-Z0-9_]*"
+        "|\\.([Ee][Qq]|[Nn][Ee]|[Gg][TtEe]|[Ll][TtEe]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|[Aa][Nn][Dd]|[Oo][Rr]|[Nn]?[Ee][Qq][Vv]|[Nn][Oo][Tt])\\."
+        /* numbers and format statements like 2E14.4, or ES12.6, 9X.
+         * Don't worry about format statements without leading digits since
+         * they would have been matched above as a variable anyway. */
+        "|[-+]?[0-9.]+([AaIiDdEeFfLlTtXx][Ss]?[-+]?[0-9.]*)?(_[a-zA-Z0-9][a-zA-Z0-9_]*)?"
+        "|//|\\*\\*|::|[/<>=]="
+        "|[^[:space:]]|[\x80-\xff]+"),
 PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
         "[^<>= \t]+|[^[:space:]]|[\x80-\xff]+"),
 PATTERNS("java",
@@ -101,6 +117,7 @@ PATTERNS("csharp",
 { "default", NULL, -1, { NULL, 0 } },
 };
 #undef PATTERNS
+#undef IPATTERN
 
 static struct userdiff_driver driver_true = {
        "diff=true",