Imported Upstream version 2.6.4 upstream/2.6.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:15:35 +0000 (15:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:15:35 +0000 (15:15 +0900)
41 files changed:
Documentation/RelNotes/2.6.4.txt [new file with mode: 0644]
Documentation/diff-options.txt
Documentation/git-check-ignore.txt
Documentation/git-rebase.txt
Documentation/git-update-index.txt
Documentation/git.txt
GIT-VERSION-GEN
Makefile
RelNotes
block-sha1/sha1.h
builtin/commit.c
builtin/count-objects.c
builtin/gc.c
cache.h
compat/apple-common-crypto.h
compat/sha1-chunked.c [new file with mode: 0644]
compat/sha1-chunked.h [new file with mode: 0644]
configure.ac
contrib/completion/git-prompt.sh
contrib/rerere-train.sh
git-difftool.perl
git-filter-branch.sh
git-p4.py
git-rebase--interactive.sh
git-rebase.sh
git.c
http.c
path.c
ppc/sha1.h
sha1_file.c
t/t3420-rebase-autostash.sh
t/t5304-prune.sh
t/t5571-pre-push-hook.sh
t/t5813-proto-disable-ssh.sh
t/t7003-filter-branch.sh
t/t7800-difftool.sh
t/t9800-git-p4-basic.sh
t/t9807-git-p4-submit.sh
t/t9903-bash-prompt.sh
transport.c
wt-status.c

diff --git a/Documentation/RelNotes/2.6.4.txt b/Documentation/RelNotes/2.6.4.txt
new file mode 100644 (file)
index 0000000..b0256a2
--- /dev/null
@@ -0,0 +1,63 @@
+Git v2.6.4 Release Notes
+========================
+
+Fixes since v2.6.3
+------------------
+
+ * The "configure" script did not test for -lpthread correctly, which
+   upset some linkers.
+
+ * Add support for talking http/https over socks proxy.
+
+ * Portability fix for Windows, which may rewrite $SHELL variable using
+   non-POSIX paths.
+
+ * We now consistently allow all hooks to ignore their standard input,
+   rather than having git complain of SIGPIPE.
+
+ * Fix shell quoting in contrib script.
+
+ * Test portability fix for a topic in v2.6.1.
+
+ * Allow tilde-expansion in some http config variables.
+
+ * Give a useful special case "diff/show --word-diff-regex=." as an
+   example in the documentation.
+
+ * Fix for a corner case in filter-branch.
+
+ * Make git-p4 work on a detached head.
+
+ * Documentation clarification for "check-ignore" without "--verbose".
+
+ * Just like the working tree is cleaned up when the user cancelled
+   submission in P4Submit.applyCommit(), clean up the mess if "p4
+   submit" fails.
+
+ * Having a leftover .idx file without corresponding .pack file in
+   the repository hurts performance; "git gc" learned to prune them.
+
+ * The code to prepare the working tree side of temporary directory
+   for the "dir-diff" feature forgot that symbolic links need not be
+   copied (or symlinked) to the temporary area, as the code already
+   special cases and overwrites them.  Besides, it was wrong to try
+   computing the object name of the target of symbolic link, which may
+   not even exist or may be a directory.
+
+ * There was no way to defeat a configured rebase.autostash variable
+   from the command line, as "git rebase --no-autostash" was missing.
+
+ * Allow "git interpret-trailers" to run outside of a Git repository.
+
+ * Produce correct "dirty" marker for shell prompts, even when we
+   are on an orphan or an unborn branch.
+
+ * Some corner cases have been fixed in string-matching done in "git
+   status".
+
+ * Apple's common crypto implementation of SHA1_Update() does not take
+   more than 4GB at a time, and we now have a compile-time workaround
+   for it.
+
+Also contains typofixes, documentation updates and trivial code
+clean-ups.
index d56ca90..306b7e3 100644 (file)
@@ -267,6 +267,9 @@ expression to make sure that it matches all non-whitespace characters.
 A match that contains a newline is silently truncated(!) at the
 newline.
 +
 A match that contains a newline is silently truncated(!) at the
 newline.
 +
+For example, `--word-diff-regex=.` will treat each character as a word
+and, correspondingly, show differences character by character.
++
 The regex can also be set via a diff driver or configuration option, see
 linkgit:gitattributes[1] or linkgit:git-config[1].  Giving it explicitly
 overrides any diff driver or configuration setting.  Diff drivers
 The regex can also be set via a diff driver or configuration option, see
 linkgit:gitattributes[1] or linkgit:git-config[1].  Giving it explicitly
 overrides any diff driver or configuration setting.  Diff drivers
index 59531ab..e94367a 100644 (file)
@@ -16,10 +16,9 @@ DESCRIPTION
 -----------
 
 For each pathname given via the command-line or from a file via
 -----------
 
 For each pathname given via the command-line or from a file via
-`--stdin`, show the pattern from .gitignore (or other input files to
-the exclude mechanism) that decides if the pathname is excluded or
-included.  Later patterns within a file take precedence over earlier
-ones.
+`--stdin`, check whether the file is excluded by .gitignore (or other
+input files to the exclude mechanism) and output the path if it is
+excluded.
 
 By default, tracked files are not shown at all since they are not
 subject to exclude rules; but see `--no-index'.
 
 By default, tracked files are not shown at all since they are not
 subject to exclude rules; but see `--no-index'.
@@ -32,7 +31,8 @@ OPTIONS
 
 -v, --verbose::
        Also output details about the matching pattern (if any)
 
 -v, --verbose::
        Also output details about the matching pattern (if any)
-       for each given pathname.
+       for each given pathname. For precedence rules within and
+       between exclude sources, see linkgit:gitignore[5].
 
 --stdin::
        Read pathnames from the standard input, one per line,
 
 --stdin::
        Read pathnames from the standard input, one per line,
index bccfdf7..6cca8bb 100644 (file)
@@ -434,7 +434,8 @@ If the '--autosquash' option is enabled by default using the
 configuration variable `rebase.autoSquash`, this option can be
 used to override and disable this setting.
 
 configuration variable `rebase.autoSquash`, this option can be
 used to override and disable this setting.
 
---[no-]autostash::
+--autostash::
+--no-autostash::
        Automatically create a temporary stash before the operation
        begins, and apply it after the operation ends.  This means
        that you can run rebase on a dirty worktree.  However, use
        Automatically create a temporary stash before the operation
        begins, and apply it after the operation ends.  This means
        that you can run rebase on a dirty worktree.  However, use
index 1a296bc..3df9c26 100644 (file)
@@ -17,6 +17,7 @@ SYNOPSIS
             [--[no-]assume-unchanged]
             [--[no-]skip-worktree]
             [--ignore-submodules]
             [--[no-]assume-unchanged]
             [--[no-]skip-worktree]
             [--ignore-submodules]
+            [--[no-|force-]untracked-cache]
             [--really-refresh] [--unresolve] [--again | -g]
             [--info-only] [--index-info]
             [-z] [--stdin] [--index-version <n>]
             [--really-refresh] [--unresolve] [--again | -g]
             [--info-only] [--index-info]
             [-z] [--stdin] [--index-version <n>]
index c2e2a94..cbf157b 100644 (file)
@@ -43,9 +43,10 @@ unreleased) version of Git, that is available from the 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v2.6.3/git.html[documentation for release 2.6.3]
+* link:v2.6.4/git.html[documentation for release 2.6.4]
 
 * release notes for
 
 * release notes for
+  link:RelNotes/2.6.4.txt[2.6.4],
   link:RelNotes/2.6.3.txt[2.6.3],
   link:RelNotes/2.6.2.txt[2.6.2],
   link:RelNotes/2.6.1.txt[2.6.1],
   link:RelNotes/2.6.3.txt[2.6.3],
   link:RelNotes/2.6.2.txt[2.6.2],
   link:RelNotes/2.6.1.txt[2.6.1],
@@ -1056,7 +1057,7 @@ of clones and fetches.
        cloning of shallow repositories.
        See 'GIT_TRACE' for available trace output options.
 
        cloning of shallow repositories.
        See 'GIT_TRACE' for available trace output options.
 
-GIT_LITERAL_PATHSPECS::
+'GIT_LITERAL_PATHSPECS'::
        Setting this variable to `1` will cause Git to treat all
        pathspecs literally, rather than as glob patterns. For example,
        running `GIT_LITERAL_PATHSPECS=1 git log -- '*.c'` will search
        Setting this variable to `1` will cause Git to treat all
        pathspecs literally, rather than as glob patterns. For example,
        running `GIT_LITERAL_PATHSPECS=1 git log -- '*.c'` will search
@@ -1065,15 +1066,15 @@ GIT_LITERAL_PATHSPECS::
        literal paths to Git (e.g., paths previously given to you by
        `git ls-tree`, `--raw` diff output, etc).
 
        literal paths to Git (e.g., paths previously given to you by
        `git ls-tree`, `--raw` diff output, etc).
 
-GIT_GLOB_PATHSPECS::
+'GIT_GLOB_PATHSPECS'::
        Setting this variable to `1` will cause Git to treat all
        pathspecs as glob patterns (aka "glob" magic).
 
        Setting this variable to `1` will cause Git to treat all
        pathspecs as glob patterns (aka "glob" magic).
 
-GIT_NOGLOB_PATHSPECS::
+'GIT_NOGLOB_PATHSPECS'::
        Setting this variable to `1` will cause Git to treat all
        pathspecs as literal (aka "literal" magic).
 
        Setting this variable to `1` will cause Git to treat all
        pathspecs as literal (aka "literal" magic).
 
-GIT_ICASE_PATHSPECS::
+'GIT_ICASE_PATHSPECS'::
        Setting this variable to `1` will cause Git to treat all
        pathspecs as case-insensitive.
 
        Setting this variable to `1` will cause Git to treat all
        pathspecs as case-insensitive.
 
@@ -1087,7 +1088,7 @@ GIT_ICASE_PATHSPECS::
        variable when it is invoked as the top level command by the
        end user, to be recorded in the body of the reflog.
 
        variable when it is invoked as the top level command by the
        end user, to be recorded in the body of the reflog.
 
-`GIT_REF_PARANOIA`::
+'GIT_REF_PARANOIA'::
        If set to `1`, include broken or badly named refs when iterating
        over lists of refs. In a normal, non-corrupted repository, this
        does nothing. However, enabling it may help git to detect and
        If set to `1`, include broken or badly named refs when iterating
        over lists of refs. In a normal, non-corrupted repository, this
        does nothing. However, enabling it may help git to detect and
@@ -1098,7 +1099,7 @@ GIT_ICASE_PATHSPECS::
        an operation has touched every ref (e.g., because you are
        cloning a repository to make a backup).
 
        an operation has touched every ref (e.g., because you are
        cloning a repository to make a backup).
 
-`GIT_ALLOW_PROTOCOL`::
+'GIT_ALLOW_PROTOCOL'::
        If set, provide a colon-separated list of protocols which are
        allowed to be used with fetch/push/clone. This is useful to
        restrict recursive submodule initialization from an untrusted
        If set, provide a colon-separated list of protocols which are
        allowed to be used with fetch/push/clone. This is useful to
        restrict recursive submodule initialization from an untrusted
index abfdd9c..f2a001f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.6.3
+DEF_VER=v2.6.4
 
 LF='
 '
 
 LF='
 '
index 944d2c3..37e2d9e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -144,6 +144,10 @@ all::
 # Define PPC_SHA1 environment variable when running make to make use of
 # a bundled SHA1 routine optimized for PowerPC.
 #
 # Define PPC_SHA1 environment variable when running make to make use of
 # a bundled SHA1 routine optimized for PowerPC.
 #
+# Define SHA1_MAX_BLOCK_SIZE to limit the amount of data that will be hashed
+# in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO
+# wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.
+#
 # Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
 #
 # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
 # Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
 #
 # Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
@@ -1340,6 +1344,11 @@ ifdef NO_POSIX_GOODIES
        BASIC_CFLAGS += -DNO_POSIX_GOODIES
 endif
 
        BASIC_CFLAGS += -DNO_POSIX_GOODIES
 endif
 
+ifdef APPLE_COMMON_CRYPTO
+       # Apple CommonCrypto requires chunking
+       SHA1_MAX_BLOCK_SIZE = 1024L*1024L*1024L
+endif
+
 ifdef BLK_SHA1
        SHA1_HEADER = "block-sha1/sha1.h"
        LIB_OBJS += block-sha1/sha1.o
 ifdef BLK_SHA1
        SHA1_HEADER = "block-sha1/sha1.h"
        LIB_OBJS += block-sha1/sha1.o
@@ -1358,6 +1367,10 @@ endif
 endif
 endif
 
 endif
 endif
 
+ifdef SHA1_MAX_BLOCK_SIZE
+       LIB_OBJS += compat/sha1-chunked.o
+       BASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE="$(SHA1_MAX_BLOCK_SIZE)"
+endif
 ifdef NO_PERL_MAKEMAKER
        export NO_PERL_MAKEMAKER
 endif
 ifdef NO_PERL_MAKEMAKER
        export NO_PERL_MAKEMAKER
 endif
index 21b4dd6..1a01ab8 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.6.3.txt
\ No newline at end of file
+Documentation/RelNotes/2.6.4.txt
\ No newline at end of file
index b864df6..4df6747 100644 (file)
@@ -16,7 +16,7 @@ void blk_SHA1_Init(blk_SHA_CTX *ctx);
 void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);
 void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);
 
 void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);
 void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);
 
-#define git_SHA_CTX    blk_SHA_CTX
-#define git_SHA1_Init  blk_SHA1_Init
-#define git_SHA1_Update        blk_SHA1_Update
-#define git_SHA1_Final blk_SHA1_Final
+#define platform_SHA_CTX       blk_SHA_CTX
+#define platform_SHA1_Init     blk_SHA1_Init
+#define platform_SHA1_Update   blk_SHA1_Update
+#define platform_SHA1_Final    blk_SHA1_Final
index dca09e2..f2a8b78 100644 (file)
@@ -32,6 +32,7 @@
 #include "sequencer.h"
 #include "notes-utils.h"
 #include "mailmap.h"
 #include "sequencer.h"
 #include "notes-utils.h"
 #include "mailmap.h"
+#include "sigchain.h"
 
 static const char * const builtin_commit_usage[] = {
        N_("git commit [<options>] [--] <pathspec>..."),
 
 static const char * const builtin_commit_usage[] = {
        N_("git commit [<options>] [--] <pathspec>..."),
@@ -1537,8 +1538,10 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
                return code;
        n = snprintf(buf, sizeof(buf), "%s %s\n",
                     sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
                return code;
        n = snprintf(buf, sizeof(buf), "%s %s\n",
                     sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
+       sigchain_push(SIGPIPE, SIG_IGN);
        write_in_full(proc.in, buf, n);
        close(proc.in);
        write_in_full(proc.in, buf, n);
        close(proc.in);
+       sigchain_pop(SIGPIPE);
        return finish_command(&proc);
 }
 
        return finish_command(&proc);
 }
 
index ad0c799..ba92919 100644 (file)
@@ -15,9 +15,31 @@ static int verbose;
 static unsigned long loose, packed, packed_loose;
 static off_t loose_size;
 
 static unsigned long loose, packed, packed_loose;
 static off_t loose_size;
 
-static void real_report_garbage(const char *desc, const char *path)
+static const char *bits_to_msg(unsigned seen_bits)
+{
+       switch (seen_bits) {
+       case 0:
+               return "no corresponding .idx or .pack";
+       case PACKDIR_FILE_GARBAGE:
+               return "garbage found";
+       case PACKDIR_FILE_PACK:
+               return "no corresponding .idx";
+       case PACKDIR_FILE_IDX:
+               return "no corresponding .pack";
+       case PACKDIR_FILE_PACK|PACKDIR_FILE_IDX:
+       default:
+               return NULL;
+       }
+}
+
+static void real_report_garbage(unsigned seen_bits, const char *path)
 {
        struct stat st;
 {
        struct stat st;
+       const char *desc = bits_to_msg(seen_bits);
+
+       if (!desc)
+               return;
+
        if (!stat(path, &st))
                size_garbage += st.st_size;
        warning("%s: %s", desc, path);
        if (!stat(path, &st))
                size_garbage += st.st_size;
        warning("%s: %s", desc, path);
@@ -27,7 +49,7 @@ static void real_report_garbage(const char *desc, const char *path)
 static void loose_garbage(const char *path)
 {
        if (verbose)
 static void loose_garbage(const char *path)
 {
        if (verbose)
-               report_garbage("garbage found", path);
+               report_garbage(PACKDIR_FILE_GARBAGE, path);
 }
 
 static int count_loose(const unsigned char *sha1, const char *path, void *data)
 }
 
 static int count_loose(const unsigned char *sha1, const char *path, void *data)
index cb13ab7..42258fe 100644 (file)
@@ -46,6 +46,22 @@ static struct argv_array rerere = ARGV_ARRAY_INIT;
 static struct tempfile pidfile;
 static struct lock_file log_lock;
 
 static struct tempfile pidfile;
 static struct lock_file log_lock;
 
+static struct string_list pack_garbage = STRING_LIST_INIT_DUP;
+
+static void clean_pack_garbage(void)
+{
+       int i;
+       for (i = 0; i < pack_garbage.nr; i++)
+               unlink_or_warn(pack_garbage.items[i].string);
+       string_list_clear(&pack_garbage, 0);
+}
+
+static void report_pack_garbage(unsigned seen_bits, const char *path)
+{
+       if (seen_bits == PACKDIR_FILE_IDX)
+               string_list_append(&pack_garbage, path);
+}
+
 static void git_config_date_string(const char *key, const char **output)
 {
        if (git_config_get_string_const(key, output))
 static void git_config_date_string(const char *key, const char **output)
 {
        if (git_config_get_string_const(key, output))
@@ -416,6 +432,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        if (run_command_v_opt(rerere.argv, RUN_GIT_CMD))
                return error(FAILED_RUN, rerere.argv[0]);
 
        if (run_command_v_opt(rerere.argv, RUN_GIT_CMD))
                return error(FAILED_RUN, rerere.argv[0]);
 
+       report_garbage = report_pack_garbage;
+       reprepare_packed_git();
+       if (pack_garbage.nr > 0)
+               clean_pack_garbage();
+
        if (auto_gc && too_many_loose_objects())
                warning(_("There are too many unreachable loose objects; "
                        "run 'git prune' to remove them."));
        if (auto_gc && too_many_loose_objects())
                warning(_("There are too many unreachable loose objects; "
                        "run 'git prune' to remove them."));
diff --git a/cache.h b/cache.h
index a9aaa03..6f53962 100644 (file)
--- a/cache.h
+++ b/cache.h
 #include "string-list.h"
 
 #include SHA1_HEADER
 #include "string-list.h"
 
 #include SHA1_HEADER
-#ifndef git_SHA_CTX
-#define git_SHA_CTX    SHA_CTX
-#define git_SHA1_Init  SHA1_Init
-#define git_SHA1_Update        SHA1_Update
-#define git_SHA1_Final SHA1_Final
+#ifndef platform_SHA_CTX
+/*
+ * platform's underlying implementation of SHA-1; could be OpenSSL,
+ * blk_SHA, Apple CommonCrypto, etc...  Note that including
+ * SHA1_HEADER may have already defined platform_SHA_CTX for our
+ * own implementations like block-sha1 and ppc-sha1, so we list
+ * the default for OpenSSL compatible SHA-1 implementations here.
+ */
+#define platform_SHA_CTX       SHA_CTX
+#define platform_SHA1_Init     SHA1_Init
+#define platform_SHA1_Update   SHA1_Update
+#define platform_SHA1_Final            SHA1_Final
+#endif
+
+#define git_SHA_CTX            platform_SHA_CTX
+#define git_SHA1_Init          platform_SHA1_Init
+#define git_SHA1_Update                platform_SHA1_Update
+#define git_SHA1_Final         platform_SHA1_Final
+
+#ifdef SHA1_MAX_BLOCK_SIZE
+#include "compat/sha1-chunked.h"
+#undef git_SHA1_Update
+#define git_SHA1_Update                git_SHA1_Update_Chunked
 #endif
 
 #include <zlib.h>
 #endif
 
 #include <zlib.h>
@@ -1258,8 +1276,11 @@ struct pack_entry {
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
 
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
 
-/* A hook for count-objects to report invalid files in pack directory */
-extern void (*report_garbage)(const char *desc, const char *path);
+/* A hook to report invalid files in pack directory */
+#define PACKDIR_FILE_PACK 1
+#define PACKDIR_FILE_IDX 2
+#define PACKDIR_FILE_GARBAGE 4
+extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
 extern void prepare_packed_git(void);
 extern void reprepare_packed_git(void);
 
 extern void prepare_packed_git(void);
 extern void reprepare_packed_git(void);
index c8b9b0e..d3fb264 100644 (file)
 #undef TYPE_BOOL
 #endif
 
 #undef TYPE_BOOL
 #endif
 
+#ifndef SHA1_MAX_BLOCK_SIZE
+#error Using Apple Common Crypto library requires setting SHA1_MAX_BLOCK_SIZE
+#endif
+
 #ifdef APPLE_LION_OR_NEWER
 #define git_CC_error_check(pattern, err) \
        do { \
 #ifdef APPLE_LION_OR_NEWER
 #define git_CC_error_check(pattern, err) \
        do { \
diff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c
new file mode 100644 (file)
index 0000000..6adfcfd
--- /dev/null
@@ -0,0 +1,19 @@
+#include "cache.h"
+
+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len)
+{
+       size_t nr;
+       size_t total = 0;
+       const char *cdata = (const char*)data;
+
+       while (len) {
+               nr = len;
+               if (nr > SHA1_MAX_BLOCK_SIZE)
+                       nr = SHA1_MAX_BLOCK_SIZE;
+               platform_SHA1_Update(c, cdata, nr);
+               total += nr;
+               cdata += nr;
+               len -= nr;
+       }
+       return total;
+}
diff --git a/compat/sha1-chunked.h b/compat/sha1-chunked.h
new file mode 100644 (file)
index 0000000..7b2df28
--- /dev/null
@@ -0,0 +1,2 @@
+
+int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len);
index fd22d41..1f55009 100644 (file)
@@ -1149,7 +1149,12 @@ elif test -z "$PTHREAD_CFLAGS"; then
   # would then trigger compiler warnings on every single file we compile.
   for opt in "" -mt -pthread -lpthread; do
      old_CFLAGS="$CFLAGS"
   # would then trigger compiler warnings on every single file we compile.
   for opt in "" -mt -pthread -lpthread; do
      old_CFLAGS="$CFLAGS"
-     CFLAGS="$opt $CFLAGS"
+     old_LIBS="$LIBS"
+     case "$opt" in
+        -l*)  LIBS="$opt $LIBS" ;;
+        *)    CFLAGS="$opt $CFLAGS" ;;
+     esac
+
      AC_MSG_CHECKING([for POSIX Threads with '$opt'])
      AC_LINK_IFELSE([PTHREADTEST_SRC],
        [AC_MSG_RESULT([yes])
      AC_MSG_CHECKING([for POSIX Threads with '$opt'])
      AC_LINK_IFELSE([PTHREADTEST_SRC],
        [AC_MSG_RESULT([yes])
@@ -1161,6 +1166,7 @@ elif test -z "$PTHREAD_CFLAGS"; then
        ],
        [AC_MSG_RESULT([no])])
       CFLAGS="$old_CFLAGS"
        ],
        [AC_MSG_RESULT([no])])
       CFLAGS="$old_CFLAGS"
+      LIBS="$old_LIBS"
   done
   if test $threads_found != yes; then
     AC_CHECK_LIB([pthread], [pthread_create],
   done
   if test $threads_found != yes; then
     AC_CHECK_LIB([pthread], [pthread_create],
index 07b52be..64219e6 100644 (file)
@@ -476,10 +476,9 @@ __git_ps1 ()
                if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
                   [ "$(git config --bool bash.showDirtyState)" != "false" ]
                then
                if [ -n "${GIT_PS1_SHOWDIRTYSTATE-}" ] &&
                   [ "$(git config --bool bash.showDirtyState)" != "false" ]
                then
-                       git diff --no-ext-diff --quiet --exit-code || w="*"
-                       if [ -n "$short_sha" ]; then
-                               git diff-index --cached --quiet HEAD -- || i="+"
-                       else
+                       git diff --no-ext-diff --quiet || w="*"
+                       git diff --no-ext-diff --cached --quiet || i="+"
+                       if [ -z "$short_sha" ] && [ -z "$i" ]; then
                                i="#"
                        fi
                fi
                                i="#"
                        fi
                fi
index 36b6fee..52ad9e4 100755 (executable)
@@ -7,7 +7,7 @@ USAGE="$me rev-list-args"
 
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
 
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
-. $(git --exec-path)/git-sh-setup
+. "$(git --exec-path)/git-sh-setup"
 require_work_tree
 cd_to_toplevel
 
 require_work_tree
 cd_to_toplevel
 
index 7df7c8a..488d14b 100755 (executable)
@@ -70,9 +70,7 @@ sub use_wt_file
        my ($repo, $workdir, $file, $sha1) = @_;
        my $null_sha1 = '0' x 40;
 
        my ($repo, $workdir, $file, $sha1) = @_;
        my $null_sha1 = '0' x 40;
 
-       if (! -e "$workdir/$file") {
-               # If the file doesn't exist in the working tree, we cannot
-               # use it.
+       if (-l "$workdir/$file" || ! -e _) {
                return (0, $null_sha1);
        }
 
                return (0, $null_sha1);
        }
 
index fff8093..ad24c8d 100755 (executable)
@@ -319,7 +319,7 @@ while read commit parents; do
                        die "tree filter failed: $filter_tree"
 
                (
                        die "tree filter failed: $filter_tree"
 
                (
-                       git diff-index -r --name-only --ignore-submodules $commit &&
+                       git diff-index -r --name-only --ignore-submodules $commit -- &&
                        git ls-files --others
                ) > "$tempdir"/tree-state || exit
                git update-index --add --replace --remove --stdin \
                        git ls-files --others
                ) > "$tempdir"/tree-state || exit
                git update-index --add --replace --remove --stdin \
index 36c5c55..a79b6d8 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -190,14 +190,16 @@ def p4_has_move_command():
     # assume it failed because @... was invalid changelist
     return True
 
     # assume it failed because @... was invalid changelist
     return True
 
-def system(cmd):
+def system(cmd, ignore_error=False):
     expand = isinstance(cmd,basestring)
     if verbose:
         sys.stderr.write("executing %s\n" % str(cmd))
     retcode = subprocess.call(cmd, shell=expand)
     expand = isinstance(cmd,basestring)
     if verbose:
         sys.stderr.write("executing %s\n" % str(cmd))
     retcode = subprocess.call(cmd, shell=expand)
-    if retcode:
+    if retcode and not ignore_error:
         raise CalledProcessError(retcode, cmd)
 
         raise CalledProcessError(retcode, cmd)
 
+    return retcode
+
 def p4_system(cmd):
     """Specifically invoke p4 as the system command. """
     real_cmd = p4_build_cmd(cmd)
 def p4_system(cmd):
     """Specifically invoke p4 as the system command. """
     real_cmd = p4_build_cmd(cmd)
@@ -540,7 +542,12 @@ def p4Where(depotPath):
     return clientPath
 
 def currentGitBranch():
     return clientPath
 
 def currentGitBranch():
-    return read_pipe("git name-rev HEAD").split(" ")[1].strip()
+    retcode = system(["git", "symbolic-ref", "-q", "HEAD"], ignore_error=True)
+    if retcode != 0:
+        # on a detached head
+        return None
+    else:
+        return read_pipe(["git", "name-rev", "HEAD"]).split(" ")[1].strip()
 
 def isValidGitDir(path):
     if (os.path.exists(path + "/HEAD")
 
 def isValidGitDir(path):
     if (os.path.exists(path + "/HEAD")
@@ -1536,44 +1543,47 @@ class P4Submit(Command, P4UserMap):
         #
         # Let the user edit the change description, then submit it.
         #
         #
         # Let the user edit the change description, then submit it.
         #
-        if self.edit_template(fileName):
-            # read the edited message and submit
-            ret = True
-            tmpFile = open(fileName, "rb")
-            message = tmpFile.read()
-            tmpFile.close()
-            if self.isWindows:
-                message = message.replace("\r\n", "\n")
-            submitTemplate = message[:message.index(separatorLine)]
-            p4_write_pipe(['submit', '-i'], submitTemplate)
-
-            if self.preserveUser:
-                if p4User:
-                    # Get last changelist number. Cannot easily get it from
-                    # the submit command output as the output is
-                    # unmarshalled.
-                    changelist = self.lastP4Changelist()
-                    self.modifyChangelistUser(changelist, p4User)
-
-            # The rename/copy happened by applying a patch that created a
-            # new file.  This leaves it writable, which confuses p4.
-            for f in pureRenameCopy:
-                p4_sync(f, "-f")
+        submitted = False
 
 
-        else:
+        try:
+            if self.edit_template(fileName):
+                # read the edited message and submit
+                tmpFile = open(fileName, "rb")
+                message = tmpFile.read()
+                tmpFile.close()
+                if self.isWindows:
+                    message = message.replace("\r\n", "\n")
+                submitTemplate = message[:message.index(separatorLine)]
+                p4_write_pipe(['submit', '-i'], submitTemplate)
+
+                if self.preserveUser:
+                    if p4User:
+                        # Get last changelist number. Cannot easily get it from
+                        # the submit command output as the output is
+                        # unmarshalled.
+                        changelist = self.lastP4Changelist()
+                        self.modifyChangelistUser(changelist, p4User)
+
+                # The rename/copy happened by applying a patch that created a
+                # new file.  This leaves it writable, which confuses p4.
+                for f in pureRenameCopy:
+                    p4_sync(f, "-f")
+                submitted = True
+
+        finally:
             # skip this patch
             # skip this patch
-            ret = False
-            print "Submission cancelled, undoing p4 changes."
-            for f in editedFiles:
-                p4_revert(f)
-            for f in filesToAdd:
-                p4_revert(f)
-                os.remove(f)
-            for f in filesToDelete:
-                p4_revert(f)
+            if not submitted:
+                print "Submission cancelled, undoing p4 changes."
+                for f in editedFiles:
+                    p4_revert(f)
+                for f in filesToAdd:
+                    p4_revert(f)
+                    os.remove(f)
+                for f in filesToDelete:
+                    p4_revert(f)
 
         os.remove(fileName)
 
         os.remove(fileName)
-        return ret
+        return submitted
 
     # Export git tags as p4 labels. Create a p4 label and then tag
     # with that.
 
     # Export git tags as p4 labels. Create a p4 label and then tag
     # with that.
@@ -1649,8 +1659,6 @@ class P4Submit(Command, P4UserMap):
     def run(self, args):
         if len(args) == 0:
             self.master = currentGitBranch()
     def run(self, args):
         if len(args) == 0:
             self.master = currentGitBranch()
-            if len(self.master) == 0 or not gitBranchExists("refs/heads/%s" % self.master):
-                die("Detecting current git branch failed!")
         elif len(args) == 1:
             self.master = args[0]
             if not branchExists(self.master):
         elif len(args) == 1:
             self.master = args[0]
             if not branchExists(self.master):
@@ -1658,9 +1666,10 @@ class P4Submit(Command, P4UserMap):
         else:
             return False
 
         else:
             return False
 
-        allowSubmit = gitConfig("git-p4.allowSubmit")
-        if len(allowSubmit) > 0 and not self.master in allowSubmit.split(","):
-            die("%s is not in git-p4.allowSubmit" % self.master)
+        if self.master:
+            allowSubmit = gitConfig("git-p4.allowSubmit")
+            if len(allowSubmit) > 0 and not self.master in allowSubmit.split(","):
+                die("%s is not in git-p4.allowSubmit" % self.master)
 
         [upstream, settings] = findUpstreamBranchPoint()
         self.depotPath = settings['depot-paths'][0]
 
         [upstream, settings] = findUpstreamBranchPoint()
         self.depotPath = settings['depot-paths'][0]
@@ -1728,7 +1737,12 @@ class P4Submit(Command, P4UserMap):
         self.check()
 
         commits = []
         self.check()
 
         commits = []
-        for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (self.origin, self.master)]):
+        if self.master:
+            commitish = self.master
+        else:
+            commitish = 'HEAD'
+
+        for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (self.origin, commitish)]):
             commits.append(line.strip())
         commits.reverse()
 
             commits.append(line.strip())
         commits.reverse()
 
index 30edb17..b938a6d 100644 (file)
@@ -610,7 +610,7 @@ do_next () {
                read -r command rest < "$todo"
                mark_action_done
                printf 'Executing: %s\n' "$rest"
                read -r command rest < "$todo"
                mark_action_done
                printf 'Executing: %s\n' "$rest"
-               ${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution
+               "${SHELL:-@SHELL_PATH@}" -c "$rest" # Actual execution
                status=$?
                # Run in subshell because require_clean_work_tree can die.
                dirty=f
                status=$?
                # Run in subshell because require_clean_work_tree can die.
                dirty=f
index 1757404..af7ba5f 100755 (executable)
@@ -14,7 +14,7 @@ git-rebase --continue | --abort | --skip | --edit-todo
  Available options are
 v,verbose!         display a diffstat of what changed upstream
 q,quiet!           be quiet. implies --no-stat
  Available options are
 v,verbose!         display a diffstat of what changed upstream
 q,quiet!           be quiet. implies --no-stat
-autostash!         automatically stash/stash pop before and after
+autostash          automatically stash/stash pop before and after
 fork-point         use 'merge-base --fork-point' to refine upstream
 onto=!             rebase onto given branch instead of upstream
 p,preserve-merges! try to recreate merges instead of ignoring them
 fork-point         use 'merge-base --fork-point' to refine upstream
 onto=!             rebase onto given branch instead of upstream
 p,preserve-merges! try to recreate merges instead of ignoring them
@@ -292,6 +292,9 @@ do
        --autostash)
                autostash=true
                ;;
        --autostash)
                autostash=true
                ;;
+       --no-autostash)
+               autostash=false
+               ;;
        --verbose)
                verbose=t
                diffstat=t
        --verbose)
                verbose=t
                diffstat=t
diff --git a/git.c b/git.c
index 5feba41..40f9df0 100644 (file)
--- a/git.c
+++ b/git.c
@@ -417,7 +417,7 @@ static struct cmd_struct commands[] = {
        { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
        { "init", cmd_init_db, NO_SETUP },
        { "init-db", cmd_init_db, NO_SETUP },
        { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
        { "init", cmd_init_db, NO_SETUP },
        { "init-db", cmd_init_db, NO_SETUP },
-       { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP },
+       { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY },
        { "log", cmd_log, RUN_SETUP },
        { "ls-files", cmd_ls_files, RUN_SETUP },
        { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
        { "log", cmd_log, RUN_SETUP },
        { "ls-files", cmd_ls_files, RUN_SETUP },
        { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
diff --git a/http.c b/http.c
index 0f924a8..c29ce81 100644 (file)
--- a/http.c
+++ b/http.c
@@ -215,10 +215,10 @@ static int http_options(const char *var, const char *value, void *cb)
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070908
        if (!strcmp("http.sslcapath", var))
 #endif
 #if LIBCURL_VERSION_NUM >= 0x070908
        if (!strcmp("http.sslcapath", var))
-               return git_config_string(&ssl_capath, var, value);
+               return git_config_pathname(&ssl_capath, var, value);
 #endif
        if (!strcmp("http.sslcainfo", var))
 #endif
        if (!strcmp("http.sslcainfo", var))
-               return git_config_string(&ssl_cainfo, var, value);
+               return git_config_pathname(&ssl_cainfo, var, value);
        if (!strcmp("http.sslcertpasswordprotected", var)) {
                ssl_cert_password_required = git_config_bool(var, value);
                return 0;
        if (!strcmp("http.sslcertpasswordprotected", var)) {
                ssl_cert_password_required = git_config_bool(var, value);
                return 0;
@@ -465,6 +465,17 @@ static CURL *get_curl_handle(void)
 
        if (curl_http_proxy) {
                curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
 
        if (curl_http_proxy) {
                curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
+#if LIBCURL_VERSION_NUM >= 0x071800
+               if (starts_with(curl_http_proxy, "socks5"))
+                       curl_easy_setopt(result,
+                               CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+               else if (starts_with(curl_http_proxy, "socks4a"))
+                       curl_easy_setopt(result,
+                               CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4A);
+               else if (starts_with(curl_http_proxy, "socks"))
+                       curl_easy_setopt(result,
+                               CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
+#endif
        }
 #if LIBCURL_VERSION_NUM >= 0x070a07
        curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
        }
 #if LIBCURL_VERSION_NUM >= 0x070a07
        curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
diff --git a/path.c b/path.c
index 56317a6..38f2ebd 100644 (file)
--- a/path.c
+++ b/path.c
@@ -147,7 +147,7 @@ void report_linked_checkout_garbage(void)
                strbuf_setlen(&sb, len);
                strbuf_addstr(&sb, path);
                if (file_exists(sb.buf))
                strbuf_setlen(&sb, len);
                strbuf_addstr(&sb, path);
                if (file_exists(sb.buf))
-                       report_garbage("unused in linked checkout", sb.buf);
+                       report_garbage(PACKDIR_FILE_GARBAGE, sb.buf);
        }
        strbuf_release(&sb);
 }
        }
        strbuf_release(&sb);
 }
index c405f73..9b24b32 100644 (file)
@@ -19,7 +19,7 @@ int ppc_SHA1_Init(ppc_SHA_CTX *c);
 int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *p, unsigned long n);
 int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c);
 
 int ppc_SHA1_Update(ppc_SHA_CTX *c, const void *p, unsigned long n);
 int ppc_SHA1_Final(unsigned char *hash, ppc_SHA_CTX *c);
 
-#define git_SHA_CTX    ppc_SHA_CTX
-#define git_SHA1_Init  ppc_SHA1_Init
-#define git_SHA1_Update        ppc_SHA1_Update
-#define git_SHA1_Final ppc_SHA1_Final
+#define platform_SHA_CTX       ppc_SHA_CTX
+#define platform_SHA1_Init     ppc_SHA1_Init
+#define platform_SHA1_Update   ppc_SHA1_Update
+#define platform_SHA1_Final    ppc_SHA1_Final
index 40a0169..4160e68 100644 (file)
@@ -1228,27 +1228,16 @@ void install_packed_git(struct packed_git *pack)
        packed_git = pack;
 }
 
        packed_git = pack;
 }
 
-void (*report_garbage)(const char *desc, const char *path);
+void (*report_garbage)(unsigned seen_bits, const char *path);
 
 static void report_helper(const struct string_list *list,
                          int seen_bits, int first, int last)
 {
 
 static void report_helper(const struct string_list *list,
                          int seen_bits, int first, int last)
 {
-       const char *msg;
-       switch (seen_bits) {
-       case 0:
-               msg = "no corresponding .idx or .pack";
-               break;
-       case 1:
-               msg = "no corresponding .idx";
-               break;
-       case 2:
-               msg = "no corresponding .pack";
-               break;
-       default:
+       if (seen_bits == (PACKDIR_FILE_PACK|PACKDIR_FILE_IDX))
                return;
                return;
-       }
+
        for (; first < last; first++)
        for (; first < last; first++)
-               report_garbage(msg, list->items[first].string);
+               report_garbage(seen_bits, list->items[first].string);
 }
 
 static void report_pack_garbage(struct string_list *list)
 }
 
 static void report_pack_garbage(struct string_list *list)
@@ -1271,7 +1260,7 @@ static void report_pack_garbage(struct string_list *list)
                if (baselen == -1) {
                        const char *dot = strrchr(path, '.');
                        if (!dot) {
                if (baselen == -1) {
                        const char *dot = strrchr(path, '.');
                        if (!dot) {
-                               report_garbage("garbage found", path);
+                               report_garbage(PACKDIR_FILE_GARBAGE, path);
                                continue;
                        }
                        baselen = dot - path + 1;
                                continue;
                        }
                        baselen = dot - path + 1;
@@ -1343,7 +1332,7 @@ static void prepare_packed_git_one(char *objdir, int local)
                    ends_with(de->d_name, ".keep"))
                        string_list_append(&garbage, path.buf);
                else
                    ends_with(de->d_name, ".keep"))
                        string_list_append(&garbage, path.buf);
                else
-                       report_garbage("garbage found", path.buf);
+                       report_garbage(PACKDIR_FILE_GARBAGE, path.buf);
        }
        closedir(dir);
        report_pack_garbage(&garbage);
        }
        closedir(dir);
        report_pack_garbage(&garbage);
index d783f03..944154b 100755 (executable)
@@ -37,6 +37,16 @@ testrebase() {
        type=$1
        dotest=$2
 
        type=$1
        dotest=$2
 
+       test_expect_success "rebase$type: dirty worktree, --no-autostash" '
+               test_config rebase.autostash true &&
+               git reset --hard &&
+               git checkout -b rebased-feature-branch feature-branch &&
+               test_when_finished git branch -D rebased-feature-branch &&
+               test_when_finished git checkout feature-branch &&
+               echo dirty >>file3 &&
+               test_must_fail git rebase$type --no-autostash unrelated-onto-branch
+       '
+
        test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" '
                test_config rebase.autostash true &&
                git reset --hard &&
        test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" '
                test_config rebase.autostash true &&
                git reset --hard &&
index 023d7c6..def203c 100755 (executable)
@@ -219,6 +219,7 @@ test_expect_success 'gc: prune old objects after local clone' '
 
 test_expect_success 'garbage report in count-objects -v' '
        test_when_finished "rm -f .git/objects/pack/fake*" &&
 
 test_expect_success 'garbage report in count-objects -v' '
        test_when_finished "rm -f .git/objects/pack/fake*" &&
+       test_when_finished "rm -f .git/objects/pack/foo*" &&
        : >.git/objects/pack/foo &&
        : >.git/objects/pack/foo.bar &&
        : >.git/objects/pack/foo.keep &&
        : >.git/objects/pack/foo &&
        : >.git/objects/pack/foo.bar &&
        : >.git/objects/pack/foo.keep &&
@@ -244,6 +245,26 @@ EOF
        test_cmp expected actual
 '
 
        test_cmp expected actual
 '
 
+test_expect_success 'clean pack garbage with gc' '
+       test_when_finished "rm -f .git/objects/pack/fake*" &&
+       test_when_finished "rm -f .git/objects/pack/foo*" &&
+       : >.git/objects/pack/foo.keep &&
+       : >.git/objects/pack/foo.pack &&
+       : >.git/objects/pack/fake.idx &&
+       : >.git/objects/pack/fake2.keep &&
+       : >.git/objects/pack/fake2.idx &&
+       : >.git/objects/pack/fake3.keep &&
+       git gc &&
+       git count-objects -v 2>stderr &&
+       grep "^warning:" stderr | sort >actual &&
+       cat >expected <<\EOF &&
+warning: no corresponding .idx or .pack: .git/objects/pack/fake3.keep
+warning: no corresponding .idx: .git/objects/pack/foo.keep
+warning: no corresponding .idx: .git/objects/pack/foo.pack
+EOF
+       test_cmp expected actual
+'
+
 test_expect_success 'prune .git/shallow' '
        SHA1=`echo hi|git commit-tree HEAD^{tree}` &&
        echo $SHA1 >.git/shallow &&
 test_expect_success 'prune .git/shallow' '
        SHA1=`echo hi|git commit-tree HEAD^{tree}` &&
        echo $SHA1 >.git/shallow &&
index 6f9916a..ba975bb 100755 (executable)
@@ -109,23 +109,20 @@ test_expect_success 'push to URL' '
        diff expected actual
 '
 
        diff expected actual
 '
 
-# Test that filling pipe buffers doesn't cause failure
-# Too slow to leave enabled for general use
-if false
-then
-       printf 'parent1\nrepo1\n' >expected
-       nr=1000
-       while test $nr -lt 2000
-       do
-               nr=$(( $nr + 1 ))
-               git branch b/$nr $COMMIT3
-               echo "refs/heads/b/$nr $COMMIT3 refs/heads/b/$nr $_z40" >>expected
-       done
-
-       test_expect_success 'push many refs' '
-               git push parent1 "refs/heads/b/*:refs/heads/b/*" &&
-               diff expected actual
-       '
-fi
+test_expect_success 'set up many-ref tests' '
+       {
+               nr=1000
+               while test $nr -lt 2000
+               do
+                       nr=$(( $nr + 1 ))
+                       echo "create refs/heads/b/$nr $COMMIT3"
+               done
+       } | git update-ref --stdin
+'
+
+test_expect_success 'sigpipe does not cause pre-push hook failure' '
+       echo "exit 0" | write_script "$HOOK" &&
+       git push parent1 "refs/heads/b/*:refs/heads/b/*"
+'
 
 test_done
 
 test_done
index ad877d7..a954ead 100755 (executable)
@@ -14,7 +14,7 @@ test_expect_success 'setup repository to clone' '
 '
 
 test_proto "host:path" ssh "remote:repo.git"
 '
 
 test_proto "host:path" ssh "remote:repo.git"
-test_proto "ssh://" ssh "ssh://remote/$PWD/remote/repo.git"
-test_proto "git+ssh://" ssh "git+ssh://remote/$PWD/remote/repo.git"
+test_proto "ssh://" ssh "ssh://remote$PWD/remote/repo.git"
+test_proto "git+ssh://" ssh "git+ssh://remote$PWD/remote/repo.git"
 
 test_done
 
 test_done
index 377c648..869e0bf 100755 (executable)
@@ -418,4 +418,11 @@ test_expect_success 'filter commit message without trailing newline' '
        test_cmp expect actual
 '
 
        test_cmp expect actual
 '
 
+test_expect_success 'tree-filter deals with object name vs pathname ambiguity' '
+       test_when_finished "git reset --hard original" &&
+       ambiguous=$(git rev-list -1 HEAD) &&
+       git filter-branch --tree-filter "mv file.t $ambiguous" HEAD^.. &&
+       git show HEAD:$ambiguous
+'
+
 test_done
 test_done
index ea35a02..a771cf7 100755 (executable)
@@ -504,4 +504,23 @@ test_expect_success PERL 'difftool properly honors gitlink and core.worktree' '
        )
 '
 
        )
 '
 
+test_expect_success PERL,SYMLINKS 'difftool --dir-diff symlinked directories' '
+       git init dirlinks &&
+       (
+               cd dirlinks &&
+               git config diff.tool checktrees &&
+               git config difftool.checktrees.cmd "echo good" &&
+               mkdir foo &&
+               : >foo/bar &&
+               git add foo/bar &&
+               test_commit symlink-one &&
+               ln -s foo link &&
+               git add link &&
+               test_commit symlink-two &&
+               echo good >expect &&
+               git difftool --tool=checktrees --dir-diff HEAD~ >actual &&
+               test_cmp expect actual
+       )
+'
+
 test_done
 test_done
index 90d41ed..0730f18 100755 (executable)
@@ -241,6 +241,22 @@ test_expect_success 'unresolvable host in P4PORT should display error' '
        )
 '
 
        )
 '
 
+test_expect_success 'submit from detached head' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$git" &&
+               git checkout p4/master &&
+               >detached_head_test &&
+               git add detached_head_test &&
+               git commit -m "add detached_head" &&
+               git config git-p4.skipSubmitEdit true &&
+               git p4 submit &&
+               git p4 rebase &&
+               git log p4/master | grep detached_head
+       )
+'
+
 test_expect_success 'kill p4d' '
        kill_p4d
 '
 test_expect_success 'kill p4d' '
        kill_p4d
 '
index 1f74a88..5931528 100755 (executable)
@@ -389,7 +389,7 @@ test_expect_success 'description with Jobs section and bogus following text' '
        (
                cd "$cli" &&
                p4 revert desc6 &&
        (
                cd "$cli" &&
                p4 revert desc6 &&
-               rm desc6
+               rm -f desc6
        )
 '
 
        )
 '
 
index 6b68777..af82049 100755 (executable)
@@ -273,11 +273,36 @@ test_expect_success 'prompt - dirty status indicator - dirty index and worktree'
        test_cmp expected "$actual"
 '
 
        test_cmp expected "$actual"
 '
 
-test_expect_success 'prompt - dirty status indicator - before root commit' '
-       printf " (master #)" >expected &&
+test_expect_success 'prompt - dirty status indicator - orphan branch - clean' '
+       printf " (orphan #)" >expected &&
+       test_when_finished "git checkout master" &&
+       git checkout --orphan orphan &&
+       git reset --hard &&
+       (
+               GIT_PS1_SHOWDIRTYSTATE=y &&
+               __git_ps1 >"$actual"
+       ) &&
+       test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - orphan branch - dirty index' '
+       printf " (orphan +)" >expected &&
+       test_when_finished "git checkout master" &&
+       git checkout --orphan orphan &&
+       (
+               GIT_PS1_SHOWDIRTYSTATE=y &&
+               __git_ps1 >"$actual"
+       ) &&
+       test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - orphan branch - dirty index and worktree' '
+       printf " (orphan *+)" >expected &&
+       test_when_finished "git checkout master" &&
+       git checkout --orphan orphan &&
+       >file &&
        (
                GIT_PS1_SHOWDIRTYSTATE=y &&
        (
                GIT_PS1_SHOWDIRTYSTATE=y &&
-               cd otherrepo &&
                __git_ps1 >"$actual"
        ) &&
        test_cmp expected "$actual"
                __git_ps1 >"$actual"
        ) &&
        test_cmp expected "$actual"
index 863eb52..37e4f5e 100644 (file)
@@ -15,6 +15,7 @@
 #include "submodule.h"
 #include "string-list.h"
 #include "sha1-array.h"
 #include "submodule.h"
 #include "string-list.h"
 #include "sha1-array.h"
+#include "sigchain.h"
 
 /* rsync support */
 
 
 /* rsync support */
 
@@ -1126,6 +1127,8 @@ static int run_pre_push_hook(struct transport *transport,
                return -1;
        }
 
                return -1;
        }
 
+       sigchain_push(SIGPIPE, SIG_IGN);
+
        strbuf_init(&buf, 256);
 
        for (r = remote_refs; r; r = r->next) {
        strbuf_init(&buf, 256);
 
        for (r = remote_refs; r; r = r->next) {
@@ -1139,8 +1142,10 @@ static int run_pre_push_hook(struct transport *transport,
                         r->peer_ref->name, sha1_to_hex(r->new_sha1),
                         r->name, sha1_to_hex(r->old_sha1));
 
                         r->peer_ref->name, sha1_to_hex(r->new_sha1),
                         r->name, sha1_to_hex(r->old_sha1));
 
-               if (write_in_full(proc.in, buf.buf, buf.len) != buf.len) {
-                       ret = -1;
+               if (write_in_full(proc.in, buf.buf, buf.len) < 0) {
+                       /* We do not mind if a hook does not read all refs. */
+                       if (errno != EPIPE)
+                               ret = -1;
                        break;
                }
        }
                        break;
                }
        }
@@ -1151,6 +1156,8 @@ static int run_pre_push_hook(struct transport *transport,
        if (!ret)
                ret = x;
 
        if (!ret)
                ret = x;
 
+       sigchain_pop(SIGPIPE);
+
        x = finish_command(&proc);
        if (!ret)
                ret = x;
        x = finish_command(&proc);
        if (!ret)
                ret = x;
index 435fc28..ced53dd 100644 (file)
@@ -1317,15 +1317,14 @@ static int grab_1st_switch(unsigned char *osha1, unsigned char *nsha1,
        target += strlen(" to ");
        strbuf_reset(&cb->buf);
        hashcpy(cb->nsha1, nsha1);
        target += strlen(" to ");
        strbuf_reset(&cb->buf);
        hashcpy(cb->nsha1, nsha1);
-       for (end = target; *end && *end != '\n'; end++)
-               ;
-       if (!memcmp(target, "HEAD", end - target)) {
+       end = strchrnul(target, '\n');
+       strbuf_add(&cb->buf, target, end - target);
+       if (!strcmp(cb->buf.buf, "HEAD")) {
                /* HEAD is relative. Resolve it to the right reflog entry. */
                /* HEAD is relative. Resolve it to the right reflog entry. */
+               strbuf_reset(&cb->buf);
                strbuf_addstr(&cb->buf,
                              find_unique_abbrev(nsha1, DEFAULT_ABBREV));
                strbuf_addstr(&cb->buf,
                              find_unique_abbrev(nsha1, DEFAULT_ABBREV));
-               return 1;
        }
        }
-       strbuf_add(&cb->buf, target, end - target);
        return 1;
 }
 
        return 1;
 }