Imported Upstream version 2.4.7 upstream/2.4.7
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:15:17 +0000 (15:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:15:17 +0000 (15:15 +0900)
21 files changed:
Documentation/RelNotes/2.4.7.txt [new file with mode: 0644]
Documentation/git-branch.txt
Documentation/git-checkout.txt
Documentation/git-rev-list.txt
Documentation/git.txt
Documentation/pretty-options.txt
GIT-VERSION-GEN
RelNotes
builtin/index-pack.c
builtin/rev-list.c
cache.h
config.c
fsck.c
git-rebase--am.sh
http.c
pager.c
sha1_file.c
strbuf.c
strbuf.h
t/t5310-pack-bitmaps.sh
t/test-lib.sh

diff --git a/Documentation/RelNotes/2.4.7.txt b/Documentation/RelNotes/2.4.7.txt
new file mode 100644 (file)
index 0000000..b3ac412
--- /dev/null
@@ -0,0 +1,53 @@
+Git v2.4.7 Release Notes
+========================
+
+Fixes since v2.4.6
+------------------
+
+ * A minor regression to "git fsck" in v2.2 era was fixed; it
+   complained about a body-less tag object when it lacked a
+   separator empty line after its header to separate it with a
+   non-existent body.
+
+ * We used to ask libCURL to use the most secure authentication method
+   available when talking to an HTTP proxy only when we were told to
+   talk to one via configuration variables.  We now ask libCURL to
+   always use the most secure authentication method, because the user
+   can tell libCURL to use an HTTP proxy via an environment variable
+   without using configuration variables.
+
+ * When you say "!<ENTER>" while running say "git log", you'd confuse
+   yourself in the resulting shell, that may look as if you took
+   control back to the original shell you spawned "git log" from but
+   that isn't what is happening.  To that new shell, we leaked
+   GIT_PAGER_IN_USE environment variable that was meant as a local
+   communication between the original "Git" and subprocesses that was
+   spawned by it after we launched the pager, which caused many
+   "interesting" things to happen, e.g. "git diff | cat" still paints
+   its output in color by default.
+
+   Stop leaking that environment variable to the pager's half of the
+   fork; we only need it on "Git" side when we spawn the pager.
+
+ * Avoid possible ssize_t to int truncation.
+
+ * "git config" failed to update the configuration file when the
+   underlying filesystem is incapable of renaming a file that is still
+   open.
+
+ * A minor bugfix when pack bitmap is used with "rev-list --count".
+
+ * An ancient test framework enhancement to allow color was not
+   entirely correct; this makes it work even when tput needs to read
+   from the ~/.terminfo under the user's real HOME directory.
+
+ * Fix a small bug in our use of umask() return value.
+
+ * "git rebase" did not exit with failure when format-patch it invoked
+   failed for whatever reason.
+
+ * Disable "have we lost a race with competing repack?" check while
+   receiving a huge object transfer that runs index-pack.
+
+Also contains typofixes, documentation updates and trivial code
+clean-ups.
index 359619b..a67138a 100644 (file)
@@ -81,7 +81,7 @@ OPTIONS
        `--track` or `--set-upstream`.
 
 -D::
-       Delete a branch irrespective of its merged status.
+       Shortcut for `--delete --force`.
 
 -l::
 --create-reflog::
@@ -95,13 +95,17 @@ OPTIONS
 --force::
        Reset <branchname> to <startpoint> if <branchname> exists
        already. Without `-f` 'git branch' refuses to change an existing branch.
+       In combination with `-d` (or `--delete`), allow deleting the
+       branch irrespective of its merged status. In combination with
+       `-m` (or `--move`), allow renaming the branch even if the new
+       branch name already exists.
 
 -m::
 --move::
        Move/rename a branch and the corresponding reflog.
 
 -M::
-       Move/rename a branch even if the new branch name already exists.
+       Shortcut for `--move --force`.
 
 --color[=<when>]::
        Color branches to highlight current, local, and
index d504108..7540e02 100644 (file)
@@ -3,7 +3,7 @@ git-checkout(1)
 
 NAME
 ----
-git-checkout - Checkout a branch or paths to the working tree
+git-checkout - Switch branches or restore working tree files
 
 SYNOPSIS
 --------
@@ -89,6 +89,10 @@ Omitting <branch> detaches HEAD at the tip of the current branch.
        (i.e.  commit, tag or tree) to update the index for the given
        paths before updating the working tree.
 +
+'git checkout' with <paths> or `--patch` is used to restore modified or
+deleted paths to their original contents from the index or replace paths
+with the contents from a named <tree-ish> (most often a commit-ish).
++
 The index may contain unmerged entries because of a previous failed merge.
 By default, if you try to check out such an entry from the index, the
 checkout operation will fail and nothing will be checked out.
index b10ea60..7b49c85 100644 (file)
@@ -56,6 +56,7 @@ SYNOPSIS
             [ --reverse ]
             [ --walk-reflogs ]
             [ --no-walk ] [ --do-walk ]
+            [ --count ]
             [ --use-bitmap-index ]
             <commit>... [ \-- <paths>... ]
 
index 35bd3b5..bd298a4 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.4.6/git.html[documentation for release 2.4.6]
+* link:v2.4.7/git.html[documentation for release 2.4.7]
 
 * release notes for
+  link:RelNotes/2.4.7.txt[2.4.7],
   link:RelNotes/2.4.6.txt[2.4.6],
   link:RelNotes/2.4.5.txt[2.4.5],
   link:RelNotes/2.4.4.txt[2.4.4],
index 74aa01a..642af6e 100644 (file)
@@ -37,7 +37,10 @@ people using 80-column terminals.
        in their encoding header; this option can be used to tell the
        command to re-code the commit log message in the encoding
        preferred by the user.  For non plumbing commands this
-       defaults to UTF-8.
+       defaults to UTF-8. Note that if an object claims to be encoded
+       in `X` and we are outputting in `X`, we will output the object
+       verbatim; this means that invalid sequences in the original
+       commit may be copied to the output.
 
 --notes[=<ref>]::
        Show the notes (see linkgit:git-notes[1]) that annotate the
index 7a6c205..b767c3a 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.4.6
+DEF_VER=v2.4.7
 
 LF='
 '
index 1b21ae8..ee13f43 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.4.6.txt
\ No newline at end of file
+Documentation/RelNotes/2.4.7.txt
\ No newline at end of file
index cf654df..723fe8e 100644 (file)
@@ -730,7 +730,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
        assert(data || obj_entry);
 
        read_lock();
-       collision_test_needed = has_sha1_file(sha1);
+       collision_test_needed = has_sha1_file_with_flags(sha1, HAS_SHA1_QUICK);
        read_unlock();
 
        if (collision_test_needed && !data) {
index ff84a82..c0b4b53 100644 (file)
@@ -42,6 +42,7 @@ static const char rev_list_usage[] =
 "    --abbrev=<n> | --no-abbrev\n"
 "    --abbrev-commit\n"
 "    --left-right\n"
+"    --count\n"
 "  special purpose:\n"
 "    --bisect\n"
 "    --bisect-vars\n"
@@ -355,7 +356,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
        if (bisect_list)
                revs.limited = 1;
 
-       if (use_bitmap_index) {
+       if (use_bitmap_index && !revs.prune) {
                if (revs.count && !revs.left_right && !revs.cherry_mark) {
                        uint32_t commit_count;
                        if (!prepare_bitmap_walk(&revs)) {
diff --git a/cache.h b/cache.h
index badf3da..4427945 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -901,8 +901,17 @@ extern int has_sha1_pack(const unsigned char *sha1);
  * Return true iff we have an object named sha1, whether local or in
  * an alternate object database, and whether packed or loose.  This
  * function does not respect replace references.
+ *
+ * If the QUICK flag is set, do not re-check the pack directory
+ * when we cannot find the object (this means we may give a false
+ * negative answer if another process is simultaneously repacking).
  */
-extern int has_sha1_file(const unsigned char *sha1);
+#define HAS_SHA1_QUICK 0x1
+extern int has_sha1_file_with_flags(const unsigned char *sha1, int flags);
+static inline int has_sha1_file(const unsigned char *sha1)
+{
+       return has_sha1_file_with_flags(sha1, 0);
+}
 
 /*
  * Return true iff an alternate object database has a loose object
index 27a73c8..69824eb 100644 (file)
--- a/config.c
+++ b/config.c
@@ -2116,6 +2116,9 @@ int git_config_set_multivar_in_file(const char *config_filename,
                                          contents_sz - copy_begin) <
                            contents_sz - copy_begin)
                                goto write_err_out;
+
+               munmap(contents, contents_sz);
+               contents = NULL;
        }
 
        if (commit_lock_file(lock) < 0) {
diff --git a/fsck.c b/fsck.c
index 10bcb65..24b2a5f 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -241,8 +241,8 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
        return retval;
 }
 
-static int require_end_of_header(const void *data, unsigned long size,
-       struct object *obj, fsck_error error_func)
+static int verify_headers(const void *data, unsigned long size,
+                         struct object *obj, fsck_error error_func)
 {
        const char *buffer = (const char *)data;
        unsigned long i;
@@ -258,6 +258,15 @@ static int require_end_of_header(const void *data, unsigned long size,
                }
        }
 
+       /*
+        * We did not find double-LF that separates the header
+        * and the body.  Not having a body is not a crime but
+        * we do want to see the terminating LF for the last header
+        * line.
+        */
+       if (size && buffer[size - 1] == '\n')
+               return 0;
+
        return error_func(obj, FSCK_ERROR, "unterminated header");
 }
 
@@ -308,7 +317,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
        unsigned parent_count, parent_line_count = 0;
        int err;
 
-       if (require_end_of_header(buffer, size, &commit->object, error_func))
+       if (verify_headers(buffer, size, &commit->object, error_func))
                return -1;
 
        if (!skip_prefix(buffer, "tree ", &buffer))
@@ -387,7 +396,7 @@ static int fsck_tag_buffer(struct tag *tag, const char *data,
                }
        }
 
-       if (require_end_of_header(buffer, size, &tag->object, error_func))
+       if (verify_headers(buffer, size, &tag->object, error_func))
                goto done;
 
        if (!skip_prefix(buffer, "object ", &buffer)) {
index f923732..9ae898b 100644 (file)
@@ -78,7 +78,7 @@ else
 
                As a result, git cannot rebase them.
                EOF
-               return $?
+               return $ret
        fi
 
        git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
diff --git a/http.c b/http.c
index 4b179f6..9a7e089 100644 (file)
--- a/http.c
+++ b/http.c
@@ -406,10 +406,10 @@ static CURL *get_curl_handle(void)
 
        if (curl_http_proxy) {
                curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy);
+       }
 #if LIBCURL_VERSION_NUM >= 0x070a07
-               curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
+       curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
 #endif
-       }
 
        set_curl_keepalive(result);
 
diff --git a/pager.c b/pager.c
index 98b2682..070dc11 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -78,6 +78,7 @@ void setup_pager(void)
                argv_array_push(&pager_process.env_array, "LESS=FRX");
        if (!getenv("LV"))
                argv_array_push(&pager_process.env_array, "LV=-c");
+       argv_array_push(&pager_process.env_array, "GIT_PAGER_IN_USE");
        if (start_command(&pager_process))
                return;
 
index 56c69ce..a68ae18 100644 (file)
@@ -443,6 +443,7 @@ void prepare_alt_odb(void)
        read_info_alternates(get_object_directory(), 0);
 }
 
+/* Returns 1 if we have successfully freshened the file, 0 otherwise. */
 static int freshen_file(const char *fn)
 {
        struct utimbuf t;
@@ -450,11 +451,18 @@ static int freshen_file(const char *fn)
        return !utime(fn, &t);
 }
 
+/*
+ * All of the check_and_freshen functions return 1 if the file exists and was
+ * freshened (if freshening was requested), 0 otherwise. If they return
+ * 0, you should not assume that it is safe to skip a write of the object (it
+ * either does not exist on disk, or has a stale mtime and may be subject to
+ * pruning).
+ */
 static int check_and_freshen_file(const char *fn, int freshen)
 {
        if (access(fn, F_OK))
                return 0;
-       if (freshen && freshen_file(fn))
+       if (freshen && !freshen_file(fn))
                return 0;
        return 1;
 }
@@ -3084,7 +3092,7 @@ int has_sha1_pack(const unsigned char *sha1)
        return find_pack_entry(sha1, &e);
 }
 
-int has_sha1_file(const unsigned char *sha1)
+int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
 {
        struct pack_entry e;
 
@@ -3092,6 +3100,8 @@ int has_sha1_file(const unsigned char *sha1)
                return 1;
        if (has_loose_object(sha1))
                return 1;
+       if (flags & HAS_SHA1_QUICK)
+               return 0;
        reprepare_packed_git();
        return find_pack_entry(sha1, &e);
 }
index 88cafd4..b4da9f5 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -481,9 +481,10 @@ int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
        return 0;
 }
 
-int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
+ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 {
-       int fd, len;
+       int fd;
+       ssize_t len;
 
        fd = open(path, O_RDONLY);
        if (fd < 0)
index 1883494..1ea9d0b 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -364,7 +364,7 @@ extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
  * Read the contents of a file, specified by its path. The third argument
  * can be used to give a hint about the file size, to avoid reallocs.
  */
-extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
+extern ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint);
 
 /**
  * Read the target of a symbolic link, specified by its path.  The third
index 6003490..d446706 100755 (executable)
@@ -53,6 +53,12 @@ rev_list_tests() {
                test_cmp expect actual
        '
 
+       test_expect_success "counting commits with limiting ($state)" '
+               git rev-list --count HEAD -- 1.t >expect &&
+               git rev-list --use-bitmap-index --count HEAD -- 1.t >actual &&
+               test_cmp expect actual
+       '
+
        test_expect_success "enumerate --objects ($state)" '
                git rev-list --objects --use-bitmap-index HEAD >tmp &&
                cut -d" " -f1 <tmp >tmp2 &&
index 4ea99a2..05efbad 100644 (file)
@@ -15,9 +15,6 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see http://www.gnu.org/licenses/ .
 
-# Keep the original TERM for say_color
-ORIGINAL_TERM=$TERM
-
 # Test the binaries we have just built.  The tests are kept in
 # t/ subdirectory and are run in 'trash directory' subdirectory.
 if test -z "$TEST_DIRECTORY"
@@ -68,12 +65,12 @@ done,*)
 esac
 
 # For repeatability, reset the environment to known value.
+# TERM is sanitized below, after saving color control sequences.
 LANG=C
 LC_ALL=C
 PAGER=cat
 TZ=UTC
-TERM=dumb
-export LANG LC_ALL PAGER TERM TZ
+export LANG LC_ALL PAGER TZ
 EDITOR=:
 # A call to "unset" with no arguments causes at least Solaris 10
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
@@ -181,8 +178,14 @@ export _x05 _x40 _z40 LF u200c
 # This test checks if command xyzzy does the right thing...
 # '
 # . ./test-lib.sh
+test "x$TERM" != "xdumb" && (
+               test -t 1 &&
+               tput bold >/dev/null 2>&1 &&
+               tput setaf 1 >/dev/null 2>&1 &&
+               tput sgr0 >/dev/null 2>&1
+       ) &&
+       color=t
 
-unset color
 while test "$#" -ne 0
 do
        case "$1" in
@@ -253,6 +256,44 @@ then
        verbose=t
 fi
 
+if test -n "$color"
+then
+       # Save the color control sequences now rather than run tput
+       # each time say_color() is called.  This is done for two
+       # reasons:
+       #   * TERM will be changed to dumb
+       #   * HOME will be changed to a temporary directory and tput
+       #     might need to read ~/.terminfo from the original HOME
+       #     directory to get the control sequences
+       # Note:  This approach assumes the control sequences don't end
+       # in a newline for any terminal of interest (command
+       # substitutions strip trailing newlines).  Given that most
+       # (all?) terminals in common use are related to ECMA-48, this
+       # shouldn't be a problem.
+       say_color_error=$(tput bold; tput setaf 1) # bold red
+       say_color_skip=$(tput setaf 4) # blue
+       say_color_warn=$(tput setaf 3) # brown/yellow
+       say_color_pass=$(tput setaf 2) # green
+       say_color_info=$(tput setaf 6) # cyan
+       say_color_reset=$(tput sgr0)
+       say_color_="" # no formatting for normal text
+       say_color () {
+               test -z "$1" && test -n "$quiet" && return
+               eval "say_color_color=\$say_color_$1"
+               shift
+               printf "%s\\n" "$say_color_color$*$say_color_reset"
+       }
+else
+       say_color() {
+               test -z "$1" && test -n "$quiet" && return
+               shift
+               printf "%s\n" "$*"
+       }
+fi
+
+TERM=dumb
+export TERM
+
 error () {
        say_color error "error: $*"
        GIT_EXIT_OK=t
@@ -829,52 +870,6 @@ HOME="$TRASH_DIRECTORY"
 GNUPGHOME="$HOME/gnupg-home-not-used"
 export HOME GNUPGHOME
 
-# run the tput tests *after* changing HOME (in case ncurses needs
-# ~/.terminfo for $TERM)
-test -n "${color+set}" || test "x$ORIGINAL_TERM" != "xdumb" && (
-               TERM=$ORIGINAL_TERM &&
-               export TERM &&
-               test -t 1 &&
-               tput bold >/dev/null 2>&1 &&
-               tput setaf 1 >/dev/null 2>&1 &&
-               tput sgr0 >/dev/null 2>&1
-       ) &&
-       color=t
-
-if test -n "$color"
-then
-       say_color () {
-               (
-               TERM=$ORIGINAL_TERM
-               export TERM
-               case "$1" in
-               error)
-                       tput bold; tput setaf 1;; # bold red
-               skip)
-                       tput setaf 4;; # blue
-               warn)
-                       tput setaf 3;; # brown/yellow
-               pass)
-                       tput setaf 2;; # green
-               info)
-                       tput setaf 6;; # cyan
-               *)
-                       test -n "$quiet" && return;;
-               esac
-               shift
-               printf "%s" "$*"
-               tput sgr0
-               echo
-               )
-       }
-else
-       say_color() {
-               test -z "$1" && test -n "$quiet" && return
-               shift
-               printf "%s\n" "$*"
-       }
-fi
-
 if test -z "$TEST_NO_CREATE_REPO"
 then
        test_create_repo "$TRASH_DIRECTORY"