Imported Upstream version 2.4.2 upstream/2.4.2
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:15:08 +0000 (15:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:15:08 +0000 (15:15 +0900)
18 files changed:
Documentation/RelNotes/2.4.2.txt [new file with mode: 0644]
Documentation/git-hash-object.txt
Documentation/git.txt
GIT-VERSION-GEN
RelNotes
builtin/hash-object.c
cache.h
contrib/completion/git-completion.bash
daemon.c
exec_cmd.c
git-filter-branch.sh
git-rebase.sh
git-stash.sh
revision.c
sha1_file.c
t/t1007-hash-object.sh
t/t3903-stash.sh
t/t7003-filter-branch.sh

diff --git a/Documentation/RelNotes/2.4.2.txt b/Documentation/RelNotes/2.4.2.txt
new file mode 100644 (file)
index 0000000..250cdc4
--- /dev/null
@@ -0,0 +1,45 @@
+Git v2.4.2 Release Notes
+========================
+
+Fixes since v2.4.1
+------------------
+
+ * "git rev-list --objects $old --not --all" to see if everything that
+   is reachable from $old is already connected to the existing refs
+   was very inefficient.
+
+ * "hash-object --literally" introduced in v2.2 was not prepared to
+   take a really long object type name.
+
+ * "git rebase --quiet" was not quite quiet when there is nothing to
+   do.
+
+ * The completion for "log --decorate=" parameter value was incorrect.
+
+ * "filter-branch" corrupted commit log message that ends with an
+   incomplete line on platforms with some "sed" implementations that
+   munge such a line.  Work it around by avoiding to use "sed".
+
+ * "git daemon" fails to build from the source under NO_IPV6
+   configuration (regression in 2.4).
+
+ * "git stash pop/apply" forgot to make sure that not just the working
+   tree is clean but also the index is clean. The latter is important
+   as a stash application can conflict and the index will be used for
+   conflict resolution.
+
+ * We have prepended $GIT_EXEC_PATH and the path "git" is installed in
+   (typically "/usr/bin") to $PATH when invoking subprograms and hooks
+   for almost eternity, but the original use case the latter tried to
+   support was semi-bogus (i.e. install git to /opt/foo/git and run it
+   without having /opt/foo on $PATH), and more importantly it has
+   become less and less relevant as Git grew more mainstream (i.e. the
+   users would _want_ to have it on their $PATH).  Stop prepending the
+   path in which "git" is installed to users' $PATH, as that would
+   interfere the command search order people depend on (e.g. they may
+   not like versions of programs that are unrelated to Git in /usr/bin
+   and want to override them by having different ones in /usr/local/bin
+   and have the latter directory earlier in their $PATH).
+
+Also contains typofixes, documentation updates and trivial code
+clean-ups.
index 02c1f12..0c75f3b 100644 (file)
@@ -9,7 +9,7 @@ git-hash-object - Compute object ID and optionally creates a blob from a file
 SYNOPSIS
 --------
 [verse]
-'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin] [--] <file>...
+'git hash-object' [-t <type>] [-w] [--path=<file>|--no-filters] [--stdin [--literally]] [--] <file>...
 'git hash-object' [-t <type>] [-w] --stdin-paths [--no-filters] < <list-of-paths>
 
 DESCRIPTION
@@ -51,7 +51,13 @@ OPTIONS
        Hash the contents as is, ignoring any input filter that would
        have been chosen by the attributes mechanism, including the end-of-line
        conversion. If the file is read from standard input then this
-       is always implied, unless the --path option is given.
+       is always implied, unless the `--path` option is given.
+
+--literally::
+       Allow `--stdin` to hash any garbage into a loose object which might not
+       otherwise pass standard object parsing or git-fsck checks. Useful for
+       stress-testing Git itself or reproducing characteristics of corrupt or
+       bogus objects encountered in the wild.
 
 GIT
 ---
index 5808df6..f582742 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.1/git.html[documentation for release 2.4.1]
+* link:v2.4.2/git.html[documentation for release 2.4.2]
 
 * release notes for
+  link:RelNotes/2.4.2.txt[2.4.2],
   link:RelNotes/2.4.1.txt[2.4.1],
   link:RelNotes/2.4.0.txt[2.4].
 
index 6dd8e04..c4a6631 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.4.1
+DEF_VER=v2.4.2
 
 LF='
 '
index 17b2de7..f43dfd9 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.4.1.txt
\ No newline at end of file
+Documentation/RelNotes/2.4.2.txt
\ No newline at end of file
index 207b90c..07fef3c 100644 (file)
@@ -22,10 +22,8 @@ static int hash_literally(unsigned char *sha1, int fd, const char *type, unsigne
 
        if (strbuf_read(&buf, fd, 4096) < 0)
                ret = -1;
-       else if (flags & HASH_WRITE_OBJECT)
-               ret = write_sha1_file(buf.buf, buf.len, type, sha1);
        else
-               ret = hash_sha1_file(buf.buf, buf.len, type, sha1);
+               ret = hash_sha1_file_literally(buf.buf, buf.len, type, sha1, flags);
        strbuf_release(&buf);
        return ret;
 }
diff --git a/cache.h b/cache.h
index eabde38..e42be4b 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -874,6 +874,7 @@ static inline const unsigned char *lookup_replace_object_extended(const unsigned
 extern int sha1_object_info(const unsigned char *, unsigned long *);
 extern int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1);
 extern int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *return_sha1);
+extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
 extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
 extern int force_object_loose(const unsigned char *sha1, time_t mtime);
 extern int git_open_noatime(const char *name);
index 5944c82..eae9dce 100644 (file)
@@ -1448,7 +1448,7 @@ _git_log ()
                return
                ;;
        --decorate=*)
-               __gitcomp "long short" "" "${cur##--decorate=}"
+               __gitcomp "full short no" "" "${cur##--decorate=}"
                return
                ;;
        --*)
index 9ee2187..4be1091 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -633,7 +633,7 @@ static void lookup_hostname(struct hostinfo *hi)
                char **ap;
                static char addrbuf[HOST_NAME_MAX + 1];
 
-               hent = gethostbyname(hostname.buf);
+               hent = gethostbyname(hi->hostname.buf);
                if (hent) {
                        ap = hent->h_addr_list;
                        memset(&sa, 0, sizeof sa);
index 8ab37b5..e85f0fd 100644 (file)
@@ -96,7 +96,6 @@ void setup_path(void)
        struct strbuf new_path = STRBUF_INIT;
 
        add_path(&new_path, git_exec_path());
-       add_path(&new_path, argv0_path);
 
        if (old_path)
                strbuf_addstr(&new_path, old_path);
index e6e99f5..5b3f63d 100755 (executable)
@@ -346,7 +346,15 @@ while read commit parents; do
                                die "parent filter failed: $filter_parent"
        fi
 
-       sed -e '1,/^$/d' <../commit | \
+       {
+               while read -r header_line && test -n "$header_line"
+               do
+                       # skip header lines...
+                       :;
+               done
+               # and output the actual commit message
+               cat
+       } <../commit |
                eval "$filter_msg" > ../message ||
                        die "msg filter failed: $filter_msg"
        workdir=$workdir @SHELL_PATH@ -c "$filter_commit" "git commit-tree" \
index 55da9db..90854e3 100755 (executable)
@@ -582,7 +582,7 @@ then
                # Lazily switch to the target branch if needed...
                test -z "$switch_to" ||
                GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to" \
-                       git checkout "$switch_to" --
+                       git checkout -q "$switch_to" --
                say "$(eval_gettext "Current branch \$branch_name is up to date.")"
                finish_rebase
                exit 0
index d4cf818..cc28368 100755 (executable)
@@ -442,6 +442,8 @@ apply_stash () {
        assert_stash_like "$@"
 
        git update-index -q --refresh || die "$(gettext "unable to refresh index")"
+       git diff-index --cached --quiet --ignore-submodules HEAD -- ||
+               die "$(gettext "Cannot apply stash: Your index contains uncommitted changes.")"
 
        # current index state
        c_tree=$(git write-tree) ||
index 6399a04..7ddbaa0 100644 (file)
@@ -345,14 +345,24 @@ static struct commit *handle_commit(struct rev_info *revs,
        die("%s is unknown object", name);
 }
 
-static int everybody_uninteresting(struct commit_list *orig)
+static int everybody_uninteresting(struct commit_list *orig,
+                                  struct commit **interesting_cache)
 {
        struct commit_list *list = orig;
+
+       if (*interesting_cache) {
+               struct commit *commit = *interesting_cache;
+               if (!(commit->object.flags & UNINTERESTING))
+                       return 0;
+       }
+
        while (list) {
                struct commit *commit = list->item;
                list = list->next;
                if (commit->object.flags & UNINTERESTING)
                        continue;
+               if (interesting_cache)
+                       *interesting_cache = commit;
                return 0;
        }
        return 1;
@@ -940,7 +950,8 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
 /* How many extra uninteresting commits we want to see.. */
 #define SLOP 5
 
-static int still_interesting(struct commit_list *src, unsigned long date, int slop)
+static int still_interesting(struct commit_list *src, unsigned long date, int slop,
+                            struct commit **interesting_cache)
 {
        /*
         * No source list at all? We're definitely done..
@@ -959,7 +970,7 @@ static int still_interesting(struct commit_list *src, unsigned long date, int sl
         * Does the source list still have interesting commits in
         * it? Definitely not done..
         */
-       if (!everybody_uninteresting(src))
+       if (!everybody_uninteresting(src, interesting_cache))
                return SLOP;
 
        /* Ok, we're closing in.. */
@@ -1078,6 +1089,7 @@ static int limit_list(struct rev_info *revs)
        struct commit_list *newlist = NULL;
        struct commit_list **p = &newlist;
        struct commit_list *bottom = NULL;
+       struct commit *interesting_cache = NULL;
 
        if (revs->ancestry_path) {
                bottom = collect_bottom_commits(list);
@@ -1094,6 +1106,9 @@ static int limit_list(struct rev_info *revs)
                list = list->next;
                free(entry);
 
+               if (commit == interesting_cache)
+                       interesting_cache = NULL;
+
                if (revs->max_age != -1 && (commit->date < revs->max_age))
                        obj->flags |= UNINTERESTING;
                if (add_parents_to_list(revs, commit, &list, NULL) < 0)
@@ -1102,7 +1117,7 @@ static int limit_list(struct rev_info *revs)
                        mark_parents_uninteresting(commit);
                        if (revs->show_all)
                                p = &commit_list_insert(commit, p)->next;
-                       slop = still_interesting(list, date, slop);
+                       slop = still_interesting(list, date, slop, &interesting_cache);
                        if (slop)
                                continue;
                        /* If showing all, add the whole pending list to the end */
index f860d67..47f56f2 100644 (file)
@@ -3009,9 +3009,8 @@ static int freshen_packed_object(const unsigned char *sha1)
        return 1;
 }
 
-int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *returnsha1)
+int write_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1)
 {
-       unsigned char sha1[20];
        char hdr[32];
        int hdrlen;
 
@@ -3019,13 +3018,32 @@ int write_sha1_file(const void *buf, unsigned long len, const char *type, unsign
         * it out into .git/objects/??/?{38} file.
         */
        write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen);
-       if (returnsha1)
-               hashcpy(returnsha1, sha1);
        if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
                return 0;
        return write_loose_object(sha1, hdr, hdrlen, buf, len, 0);
 }
 
+int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type,
+                            unsigned char *sha1, unsigned flags)
+{
+       char *header;
+       int hdrlen, status = 0;
+
+       /* type string, SP, %lu of the length plus NUL must fit this */
+       header = xmalloc(strlen(type) + 32);
+       write_sha1_file_prepare(buf, len, type, sha1, header, &hdrlen);
+
+       if (!(flags & HASH_WRITE_OBJECT))
+               goto cleanup;
+       if (freshen_packed_object(sha1) || freshen_loose_object(sha1))
+               goto cleanup;
+       status = write_loose_object(sha1, header, hdrlen, buf, len, 0);
+
+cleanup:
+       free(header);
+       return status;
+}
+
 int force_object_loose(const unsigned char *sha1, time_t mtime)
 {
        void *buf;
index ebb3a69..7d2baa1 100755 (executable)
@@ -209,4 +209,15 @@ test_expect_success 'hash-object complains about truncated type name' '
        test_must_fail git hash-object -t bl --stdin </dev/null
 '
 
+test_expect_success '--literally' '
+       t=1234567890 &&
+       echo example | git hash-object -t $t --literally --stdin
+'
+
+test_expect_success '--literally with extra-long type' '
+       t=12345678901234567890123456789012345678901234567890 &&
+       t="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" &&
+       echo example | git hash-object -t $t --literally --stdin
+'
+
 test_done
index 1e29962..0746eee 100755 (executable)
@@ -10,6 +10,8 @@ test_description='Test git stash'
 test_expect_success 'stash some dirty working directory' '
        echo 1 > file &&
        git add file &&
+       echo unrelated >other-file &&
+       git add other-file &&
        test_tick &&
        git commit -m initial &&
        echo 2 > file &&
@@ -43,10 +45,15 @@ test_expect_success 'applying bogus stash does nothing' '
        test_cmp expect file
 '
 
+test_expect_success 'apply requires a clean index' '
+       test_when_finished "git reset --hard" &&
+       echo changed >other-file &&
+       git add other-file &&
+       test_must_fail git stash apply
+'
+
 test_expect_success 'apply does not need clean working directory' '
        echo 4 >other-file &&
-       git add other-file &&
-       echo 5 >other-file &&
        git stash apply &&
        echo 3 >expect &&
        test_cmp expect file
@@ -695,8 +702,8 @@ test_expect_success 'setup stash with index and worktree changes' '
 '
 
 test_expect_success 'stash list implies --first-parent -m' '
-       cat >expect <<-\EOF &&
-       stash@{0}: WIP on master: b27a2bc subdir
+       cat >expect <<-EOF &&
+       stash@{0}
 
        diff --git a/file b/file
        index 257cc56..d26b33d 100644
@@ -706,13 +713,13 @@ test_expect_success 'stash list implies --first-parent -m' '
        -foo
        +working
        EOF
-       git stash list -p >actual &&
+       git stash list --format=%gd -p >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'stash list --cc shows combined diff' '
        cat >expect <<-\EOF &&
-       stash@{0}: WIP on master: b27a2bc subdir
+       stash@{0}
 
        diff --cc file
        index 257cc56,9015a7a..d26b33d
@@ -723,7 +730,7 @@ test_expect_success 'stash list --cc shows combined diff' '
         -index
        ++working
        EOF
-       git stash list -p --cc >actual &&
+       git stash list --format=%gd -p --cc >actual &&
        test_cmp expect actual
 '
 
index 66643e4..855afda 100755 (executable)
@@ -394,4 +394,14 @@ test_expect_success 'replace submodule revision' '
        test $orig_head != `git show-ref --hash --head HEAD`
 '
 
+test_expect_success 'filter commit message without trailing newline' '
+       git reset --hard original &&
+       commit=$(printf "no newline" | git commit-tree HEAD^{tree}) &&
+       git update-ref refs/heads/no-newline $commit &&
+       git filter-branch -f refs/heads/no-newline &&
+       echo $commit >expect &&
+       git rev-parse refs/heads/no-newline >actual &&
+       test_cmp expect actual
+'
+
 test_done