Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Wed, 3 Jun 2009 07:49:40 +0000 (00:49 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 3 Jun 2009 07:49:40 +0000 (00:49 -0700)
* maint:
blame: correctly handle a path that used to be a directory
add -i: do not dump patch during application
Update draft release notes for 1.6.3.2
grep: fix colouring of matches with zero length
Documentation: teach stash/pop workflow instead of stash/apply
Change xdl_merge to generate output even for null merges
t6023: merge-file fails to output anything for a degenerate merge

Documentation/RelNotes-1.6.3.2.txt
builtin-blame.c
git-add--interactive.perl
grep.c
t/t6023-merge-file.sh
t/t8003-blame.sh
xdiff/xmerge.c
index a3fceebb118301ab08597fb2d89d560ae084d547..0b48d1a1dfba79d5fe5c85d5cee9327a7ab11a5e 100644 (file)
@@ -8,44 +8,56 @@ Fixes since v1.6.3.1
    casting the (char *) pointer to (int *); GCC 4.4 did not like this,
    and aborted compilation.
 
- * http-push had a small use-after-free bug.
-
- * command completion code in bash did not reliably detect that we are
-   in a bare repository.
-
- * "git for-each-ref" had a segfaulting bug when dealing with a tag object
-   created by an ancient git.
-
  * Some unlink(2) failures went undiagnosed.
 
  * The "recursive" merge strategy misbehaved when faced rename/delete
    conflicts while coming up with an intermediate merge base.
 
+ * The low-level merge algorithm did not handle a degenerate case of
+   merging a file with itself using itself as the common ancestor
+   gracefully.  It should produce the file itself, but instead
+   produced an empty result.
+
  * GIT_TRACE mechanism segfaulted when tracing a shell-quoted aliases.
 
+ * OpenBSD also uses st_ctimspec in "struct stat", instead of "st_ctim".
+
+ * With NO_CROSS_DIRECTORY_HARDLINKS, "make install" can be told not to
+   create hardlinks between $(gitexecdir)/git-$builtin_commands and
+   $(bindir)/git.
+
+ * command completion code in bash did not reliably detect that we are
+   in a bare repository.
+
  * "git add ." in an empty directory complained that pathspec "." did not
    match anything, which may be technically correct, but not useful.  We
    silently make it a no-op now.
 
+ * "git add -p" (and "patch" action in "git add -i") was broken when
+   the first hunk that adds a line at the top was split into two and
+   both halves are marked to be used.
+
+ * "git for-each-ref" had a segfaulting bug when dealing with a tag object
+   created by an ancient git.
+
  * "git format-patch -k" still added patch numbers if format.numbered
    configuration was set.
 
- * OpenBSD also uses st_ctimspec in "struct stat", instead of "st_ctim".
+ * "git grep --color ''" did not terminate.
 
- * With NO_CROSS_DIRECTORY_HARDLINKS, "make install" can be told not to
-   create hardlinks between $(gitexecdir)/git-$builtin_commands and
-   $(bindir)/git.
+ * http-push had a small use-after-free bug.
 
  * "git push" was converting OFS_DELTA pack representation into less
    efficient REF_DELTA representation unconditionally upon transfer,
    making the transferred data unnecessarily larger.
 
+ * "git remote show origin" segfaulted when origin was still empty.
+
 Many other general usability updates around help text, diagnostic messages
 and documentation are included as well.
 
 ---
 exec >/var/tmp/1
-O=v1.6.3.1-51-g2a1feb9
+O=v1.6.3.1-68-g456cb4c
 echo O=$(git describe maint)
 git shortlog --no-merges $O..maint
-
index 9dc333591045b4232e47eec32488e5a2104540c7..0c2d29a43005e0afe7c0b0754499a37156e235ef 100644 (file)
@@ -362,18 +362,28 @@ static struct origin *find_origin(struct scoreboard *sb,
                               "", &diff_opts);
        diffcore_std(&diff_opts);
 
-       /* It is either one entry that says "modified", or "created",
-        * or nothing.
-        */
        if (!diff_queued_diff.nr) {
                /* The path is the same as parent */
                porigin = get_origin(sb, parent, origin->path);
                hashcpy(porigin->blob_sha1, origin->blob_sha1);
-       }
-       else if (diff_queued_diff.nr != 1)
-               die("internal error in blame::find_origin");
-       else {
-               struct diff_filepair *p = diff_queued_diff.queue[0];
+       } else {
+               /*
+                * Since origin->path is a pathspec, if the parent
+                * commit had it as a directory, we will see a whole
+                * bunch of deletion of files in the directory that we
+                * do not care about.
+                */
+               int i;
+               struct diff_filepair *p = NULL;
+               for (i = 0; i < diff_queued_diff.nr; i++) {
+                       const char *name;
+                       p = diff_queued_diff.queue[i];
+                       name = p->one->path ? p->one->path : p->two->path;
+                       if (!strcmp(name, origin->path))
+                               break;
+               }
+               if (!p)
+                       die("internal error in blame::find_origin");
                switch (p->status) {
                default:
                        die("internal error in blame::find_origin (%c)",
index a06172c69f59391a04b75a3866a3fbcb98a21ba0..df9f231635d2bc53073375971c1383966e2a140b 100755 (executable)
@@ -1317,7 +1317,6 @@ sub patch_update_file {
                open $fh, '| git apply --cached --recount';
                for (@{$head->{TEXT}}, @result) {
                        print $fh $_;
-                       print STDERR $_;
                }
                if (!close $fh) {
                        for (@{$head->{TEXT}}, @result) {
diff --git a/grep.c b/grep.c
index cc6d5b04c15b670c55bdb9e2089e0b71f72453cc..7bf4a60ac7704e16abe9054296c1e0e77c984344 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -500,6 +500,8 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
 
                *eol = '\0';
                while (next_match(opt, bol, eol, ctx, &match, eflags)) {
+                       if (match.rm_so == match.rm_eo)
+                               break;
                        printf("%.*s%s%.*s%s",
                               (int)match.rm_so, bol,
                               opt->color_match,
index f8942bc8908fb92b1b11580e3554a81377dc3ba1..7dcf39191476f272431e19e10ebb299d6aa55bb1 100755 (executable)
@@ -54,6 +54,12 @@ deduxit me super semitas jusitiae,
 EOF
 printf "propter nomen suum." >> new4.txt
 
+test_expect_success 'merge with no changes' '
+       cp orig.txt test.txt &&
+       git merge-file test.txt orig.txt orig.txt &&
+       test_cmp test.txt orig.txt
+'
+
 cp new1.txt test.txt
 test_expect_success "merge without conflict" \
        "git merge-file test.txt orig.txt new2.txt"
index 966bb0a61a89ed63dec085338d3c45f766a7f777..13c25f1d528ca1ec90575e42e0393accff5d8f35 100755 (executable)
@@ -129,4 +129,19 @@ test_expect_success 'blame wholesale copy and more' '
 
 '
 
+test_expect_success 'blame path that used to be a directory' '
+       mkdir path &&
+       echo A A A A A >path/file &&
+       echo B B B B B >path/elif &&
+       git add path &&
+       test_tick &&
+       git commit -m "path was a directory" &&
+       rm -fr path &&
+       echo A A A A A >path &&
+       git add path &&
+       test_tick &&
+       git commit -m "path is a regular file" &&
+       git blame HEAD^.. -- path
+'
+
 test_done
index d9737f04c220645aa762d79ff14a84855721ffda..1cb65a95166a8cb60af590118f59d78aa4d24b74 100644 (file)
@@ -563,23 +563,22 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, const char *name1,
                return -1;
        }
        status = 0;
-       if (xscr1 || xscr2) {
-               if (!xscr1) {
-                       result->ptr = xdl_malloc(mf2->size);
-                       memcpy(result->ptr, mf2->ptr, mf2->size);
-                       result->size = mf2->size;
-               } else if (!xscr2) {
-                       result->ptr = xdl_malloc(mf1->size);
-                       memcpy(result->ptr, mf1->ptr, mf1->size);
-                       result->size = mf1->size;
-               } else {
-                       status = xdl_do_merge(&xe1, xscr1, name1,
-                                             &xe2, xscr2, name2,
-                                             flags, xpp, result);
-               }
-               xdl_free_script(xscr1);
-               xdl_free_script(xscr2);
+       if (!xscr1) {
+               result->ptr = xdl_malloc(mf2->size);
+               memcpy(result->ptr, mf2->ptr, mf2->size);
+               result->size = mf2->size;
+       } else if (!xscr2) {
+               result->ptr = xdl_malloc(mf1->size);
+               memcpy(result->ptr, mf1->ptr, mf1->size);
+               result->size = mf1->size;
+       } else {
+               status = xdl_do_merge(&xe1, xscr1, name1,
+                                     &xe2, xscr2, name2,
+                                     flags, xpp, result);
        }
+       xdl_free_script(xscr1);
+       xdl_free_script(xscr2);
+
        xdl_free_env(&xe1);
        xdl_free_env(&xe2);