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.
 +
+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
index 59531ab..e94367a 100644 (file)
@@ -16,10 +16,9 @@ DESCRIPTION
 -----------
 
 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'.
@@ -32,7 +31,8 @@ OPTIONS
 
 -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,
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.
 
---[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
index 1a296bc..3df9c26 100644 (file)
@@ -17,6 +17,7 @@ SYNOPSIS
             [--[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>]
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:
 
-* 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
+  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],
@@ -1056,7 +1057,7 @@ of clones and fetches.
        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
@@ -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).
 
-GIT_GLOB_PATHSPECS::
+'GIT_GLOB_PATHSPECS'::
        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).
 
-GIT_ICASE_PATHSPECS::
+'GIT_ICASE_PATHSPECS'::
        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.
 
-`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
@@ -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).
 
-`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
index abfdd9c..f2a001f 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.6.3
+DEF_VER=v2.6.4
 
 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 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).
@@ -1340,6 +1344,11 @@ ifdef NO_POSIX_GOODIES
        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
@@ -1358,6 +1367,10 @@ 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
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);
 
-#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 "sigchain.h"
 
 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));
+       sigchain_push(SIGPIPE, SIG_IGN);
        write_in_full(proc.in, buf, n);
        close(proc.in);
+       sigchain_pop(SIGPIPE);
        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 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;
+       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);
@@ -27,7 +49,7 @@ static void real_report_garbage(const char *desc, const char *path)
 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)
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 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))
@@ -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]);
 
+       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."));
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
-#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>
@@ -1258,8 +1276,11 @@ struct pack_entry {
 
 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);
index c8b9b0e..d3fb264 100644 (file)
 #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 { \
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"
-     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])
@@ -1161,6 +1166,7 @@ elif test -z "$PTHREAD_CFLAGS"; then
        ],
        [AC_MSG_RESULT([no])])
       CFLAGS="$old_CFLAGS"
+      LIBS="$old_LIBS"
   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
-                       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
index 36b6fee..52ad9e4 100755 (executable)
@@ -7,7 +7,7 @@ USAGE="$me rev-list-args"
 
 SUBDIRECTORY_OK=Yes
 OPTIONS_SPEC=
-. $(git --exec-path)/git-sh-setup
+. "$(git --exec-path)/git-sh-setup"
 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;
 
-       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);
        }
 
index fff8093..ad24c8d 100755 (executable)
@@ -319,7 +319,7 @@ while read commit parents; do
                        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 \
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
 
-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)
-    if retcode:
+    if retcode and not ignore_error:
         raise CalledProcessError(retcode, cmd)
 
+    return retcode
+
 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 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")
@@ -1536,44 +1543,47 @@ class P4Submit(Command, P4UserMap):
         #
         # 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
-            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)
-        return ret
+        return submitted
 
     # 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()
-            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):
@@ -1658,9 +1666,10 @@ class P4Submit(Command, P4UserMap):
         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]
@@ -1728,7 +1737,12 @@ class P4Submit(Command, P4UserMap):
         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()
 
index 30edb17..b938a6d 100644 (file)
@@ -610,7 +610,7 @@ do_next () {
                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
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
-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
@@ -292,6 +292,9 @@ do
        --autostash)
                autostash=true
                ;;
+       --no-autostash)
+               autostash=false
+               ;;
        --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 },
-       { "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 },
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))
-               return git_config_string(&ssl_capath, var, value);
+               return git_config_pathname(&ssl_capath, var, value);
 #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;
@@ -465,6 +465,17 @@ static CURL *get_curl_handle(void)
 
        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);
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))
-                       report_garbage("unused in linked checkout", sb.buf);
+                       report_garbage(PACKDIR_FILE_GARBAGE, sb.buf);
        }
        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);
 
-#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;
 }
 
-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)
 {
-       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;
-       }
+
        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)
@@ -1271,7 +1260,7 @@ static void report_pack_garbage(struct string_list *list)
                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;
@@ -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
-                       report_garbage("garbage found", path.buf);
+                       report_garbage(PACKDIR_FILE_GARBAGE, path.buf);
        }
        closedir(dir);
        report_pack_garbage(&garbage);
index d783f03..944154b 100755 (executable)
@@ -37,6 +37,16 @@ testrebase() {
        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 &&
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_when_finished "rm -f .git/objects/pack/foo*" &&
        : >.git/objects/pack/foo &&
        : >.git/objects/pack/foo.bar &&
        : >.git/objects/pack/foo.keep &&
@@ -244,6 +245,26 @@ EOF
        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 &&
index 6f9916a..ba975bb 100755 (executable)
@@ -109,23 +109,20 @@ test_expect_success 'push to URL' '
        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
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 "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
index 377c648..869e0bf 100755 (executable)
@@ -418,4 +418,11 @@ test_expect_success 'filter commit message without trailing newline' '
        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
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
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
 '
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 &&
-               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_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 &&
-               cd otherrepo &&
                __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 "sigchain.h"
 
 /* rsync support */
 
@@ -1126,6 +1127,8 @@ static int run_pre_push_hook(struct transport *transport,
                return -1;
        }
 
+       sigchain_push(SIGPIPE, SIG_IGN);
+
        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));
 
-               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;
                }
        }
@@ -1151,6 +1156,8 @@ static int run_pre_push_hook(struct transport *transport,
        if (!ret)
                ret = x;
 
+       sigchain_pop(SIGPIPE);
+
        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);
-       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. */
+               strbuf_reset(&cb->buf);
                strbuf_addstr(&cb->buf,
                              find_unique_abbrev(nsha1, DEFAULT_ABBREV));
-               return 1;
        }
-       strbuf_add(&cb->buf, target, end - target);
        return 1;
 }