Merge branch 'cc/maint-1.6.0-bisect-fix' into maint-1.6.0
authorJunio C Hamano <gitster@pobox.com>
Fri, 13 Mar 2009 04:48:26 +0000 (21:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 13 Mar 2009 04:48:26 +0000 (21:48 -0700)
* cc/maint-1.6.0-bisect-fix:
  bisect: fix another instance of eval'ed string
  bisect: fix quoting TRIED revs when "bad" commit is also "skip"ped

34 files changed:
Documentation/git-apply.txt
Documentation/git-describe.txt
Documentation/git-diff-files.txt
Documentation/git-fsck.txt
Documentation/githooks.txt
Documentation/technical/api-strbuf.txt
Documentation/user-manual.txt
Makefile
README
builtin-apply.c
builtin-commit.c
builtin-fast-export.c
builtin-fsck.c
builtin-grep.c
builtin-mv.c
cache.h
contrib/examples/README [new file with mode: 0644]
diff.c
dir.c
fast-import.c
git-rebase--interactive.sh
git-repack.sh
git.spec.in
perl/Git.pm
sha1_file.c
sha1_name.c
t/t3001-ls-files-others-exclude.sh
t/t3404-rebase-interactive.sh
t/t3501-revert-cherry-pick.sh
t/t4114-apply-typechange.sh
t/t7001-mv.sh
test-dump-cache-tree.c [moved from dump-cache-tree.c with 100% similarity]
test-path-utils.c
unpack-trees.c

index feb51f1..44e1968 100644 (file)
@@ -147,7 +147,7 @@ discouraged.
        considered whitespace errors.
 +
 By default, the command outputs warning messages but applies the patch.
-When `git-apply is used for statistics and not applying a
+When `git-apply` is used for statistics and not applying a
 patch, it defaults to `nowarn`.
 +
 You can use different `<action>` to control this
index c4dbc2a..59a6fd1 100644 (file)
@@ -38,7 +38,7 @@ OPTIONS
        Automatically implies --tags.
 
 --abbrev=<n>::
-       Instead of using the default 8 hexadecimal digits as the
+       Instead of using the default 7 hexadecimal digits as the
        abbreviated object name, use <n> digits.
 
 --candidates=<n>::
index 5c8c1d9..c526141 100644 (file)
@@ -21,7 +21,10 @@ OPTIONS
 -------
 include::diff-options.txt[]
 
--1 -2 -3 or --base --ours --theirs, and -0::
+-1 --base::
+-2 --ours::
+-3 --theirs::
+-0::
        Diff against the "base" version, "our branch" or "their
        branch" respectively.  With these options, diffs for
        merged entries are not shown.
index d5a7647..287c4fc 100644 (file)
@@ -79,7 +79,8 @@ that aren't readable from any of the specified head nodes.
 
 So for example
 
-       git fsck --unreachable HEAD $(cat .git/refs/heads/*)
+       git fsck --unreachable HEAD \
+               $(git for-each-ref --format="%(objectname)" refs/heads)
 
 will do quite a _lot_ of verification on the tree. There are a few
 extra validity tests to be added (make sure that tree objects are
index 5faaaa5..024abb2 100644 (file)
@@ -86,7 +86,7 @@ This hook is invoked by 'git-commit' right after preparing the
 default log message, and before the editor is started.
 
 It takes one to three parameters.  The first is the name of the file
-that the commit log message.  The second is the source of the commit
+that contains the commit log message.  The second is the source of the commit
 message, and can be: `message` (if a `-m` or `-F` option was
 given); `template` (if a `-t` option was given or the
 configuration option `commit.template` is set); `merge` (if the
index a9668e5..4242dc0 100644 (file)
@@ -21,7 +21,7 @@ allocated memory or not), use `strbuf_detach()` to unwrap a memory
 buffer from its strbuf shell in a safe way. That is the sole supported
 way. This will give you a malloced buffer that you can later `free()`.
 +
-However, it it totally safe to modify anything in the string pointed by
+However, it is totally safe to modify anything in the string pointed by
 the `buf` member, between the indices `0` and `len-1` (inclusive).
 
 . The `buf` member is a byte array that has at least `len + 1` bytes
index 99cb808..2ae88c5 100644 (file)
@@ -1497,7 +1497,7 @@ so on a different branch and then coming back), unstash the
 work-in-progress changes.
 
 ------------------------------------------------
-$ git stash "work in progress for foo feature"
+$ git stash save "work in progress for foo feature"
 ------------------------------------------------
 
 This command will save your changes away to the `stash`, and
index 186a8ef..5de4247 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1301,7 +1301,7 @@ endif
 
 ### Testing rules
 
-TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X
+TEST_PROGRAMS = test-chmtime$X test-dump-cache-tree$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X
 
 all:: $(TEST_PROGRAMS)
 
diff --git a/README b/README
index 548142c..5fa41b7 100644 (file)
--- a/README
+++ b/README
@@ -24,7 +24,7 @@ It was originally written by Linus Torvalds with help of a group of
 hackers around the net. It is currently maintained by Junio C Hamano.
 
 Please read the file INSTALL for installation instructions.
-See Documentation/tutorial.txt to get started, then see
+See Documentation/gittutorial.txt to get started, then see
 Documentation/everyday.txt for a useful minimum set of commands,
 and "man git-commandname" for documentation of each command.
 CVS users may also want to read Documentation/cvs-migration.txt.
index 50b623e..7a1ff04 100644 (file)
@@ -2445,7 +2445,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
                return error("%s: %s", old_name, strerror(errno));
        }
 
-       if (!cached)
+       if (!cached && !tpatch)
                st_mode = ce_mode_from_stat(*ce, st->st_mode);
 
        if (patch->is_new < 0)
index 1e08399..6cbdd55 100644 (file)
@@ -625,7 +625,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
        if (!commitable && !in_merge && !allow_empty &&
            !(amend && is_a_merge(head_sha1))) {
                run_status(stdout, index_file, prefix, 0);
-               unlink(commit_editmsg);
                return 0;
        }
 
index 8386338..cdb7df5 100644 (file)
@@ -511,6 +511,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
 
        get_tags_and_duplicates(&revs.pending, &extra_refs);
 
+       revs.topo_order = 1;
        if (prepare_revision_walk(&revs))
                die("revision walk setup failed");
        revs.diffopt.format_callback = show_filemodify;
index 30971ce..aa4b239 100644 (file)
@@ -624,7 +624,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
        }
 
        heads = 0;
-       for (i = 1; i < argc; i++) {
+       for (i = 0; i < argc; i++) {
                const char *arg = argv[i];
                if (!get_sha1(arg, head_sha1)) {
                        struct object *obj = lookup_object(head_sha1);
index 3a51662..d3cc75e 100644 (file)
@@ -289,6 +289,8 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
                push_arg("-E");
        if (opt->regflags & REG_ICASE)
                push_arg("-i");
+       if (opt->binary == GREP_BINARY_NOMATCH)
+               push_arg("-I");
        if (opt->word_regexp)
                push_arg("-w");
        if (opt->name_only)
index 4f65b5a..01270fe 100644 (file)
@@ -162,7 +162,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                }
                                argc += last - first;
                        }
-               } else if (lstat(dst, &st) == 0) {
+               } else if (cache_name_pos(src, length) < 0)
+                       bad = "not under version control";
+               else if (lstat(dst, &st) == 0) {
                        bad = "destination exists";
                        if (force) {
                                /*
@@ -177,9 +179,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                } else
                                        bad = "Cannot overwrite";
                        }
-               } else if (cache_name_pos(src, length) < 0)
-                       bad = "not under version control";
-               else if (string_list_has_string(&src_for_dst, dst))
+               } else if (string_list_has_string(&src_for_dst, dst))
                        bad = "multiple sources for the same target";
                else
                        string_list_insert(dst, &src_for_dst);
@@ -192,6 +192,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                                        memmove(destination + i,
                                                destination + i + 1,
                                                (argc - i) * sizeof(char *));
+                                       i--;
                                }
                        } else
                                die ("%s, source=%s, destination=%s",
diff --git a/cache.h b/cache.h
index 42f2f27..099a32e 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -739,6 +739,7 @@ extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t
 extern void close_pack_windows(struct packed_git *);
 extern void unuse_pack(struct pack_window **);
 extern void free_pack_by_name(const char *);
+extern void clear_delta_base_cache(void);
 extern struct packed_git *add_packed_git(const char *, int, int);
 extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
 extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);
diff --git a/contrib/examples/README b/contrib/examples/README
new file mode 100644 (file)
index 0000000..6946f3d
--- /dev/null
@@ -0,0 +1,3 @@
+These are original scripted implementations, kept primarily for their
+reference value to any aspiring plumbing users who want to learn how
+pieces can be fit together.
diff --git a/diff.c b/diff.c
index f91f256..6fea3c0 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -2096,16 +2096,86 @@ static const char *external_diff_attr(const char *name)
        return NULL;
 }
 
+static int similarity_index(struct diff_filepair *p)
+{
+       return p->score * 100 / MAX_SCORE;
+}
+
+static void fill_metainfo(struct strbuf *msg,
+                         const char *name,
+                         const char *other,
+                         struct diff_filespec *one,
+                         struct diff_filespec *two,
+                         struct diff_options *o,
+                         struct diff_filepair *p)
+{
+       strbuf_init(msg, PATH_MAX * 2 + 300);
+       switch (p->status) {
+       case DIFF_STATUS_COPIED:
+               strbuf_addf(msg, "similarity index %d%%", similarity_index(p));
+               strbuf_addstr(msg, "\ncopy from ");
+               quote_c_style(name, msg, NULL, 0);
+               strbuf_addstr(msg, "\ncopy to ");
+               quote_c_style(other, msg, NULL, 0);
+               strbuf_addch(msg, '\n');
+               break;
+       case DIFF_STATUS_RENAMED:
+               strbuf_addf(msg, "similarity index %d%%", similarity_index(p));
+               strbuf_addstr(msg, "\nrename from ");
+               quote_c_style(name, msg, NULL, 0);
+               strbuf_addstr(msg, "\nrename to ");
+               quote_c_style(other, msg, NULL, 0);
+               strbuf_addch(msg, '\n');
+               break;
+       case DIFF_STATUS_MODIFIED:
+               if (p->score) {
+                       strbuf_addf(msg, "dissimilarity index %d%%\n",
+                                   similarity_index(p));
+                       break;
+               }
+               /* fallthru */
+       default:
+               /* nothing */
+               ;
+       }
+       if (one && two && hashcmp(one->sha1, two->sha1)) {
+               int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
+
+               if (DIFF_OPT_TST(o, BINARY)) {
+                       mmfile_t mf;
+                       if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
+                           (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
+                               abbrev = 40;
+               }
+               strbuf_addf(msg, "index %.*s..%.*s",
+                           abbrev, sha1_to_hex(one->sha1),
+                           abbrev, sha1_to_hex(two->sha1));
+               if (one->mode == two->mode)
+                       strbuf_addf(msg, " %06o", one->mode);
+               strbuf_addch(msg, '\n');
+       }
+       if (msg->len)
+               strbuf_setlen(msg, msg->len - 1);
+}
+
 static void run_diff_cmd(const char *pgm,
                         const char *name,
                         const char *other,
                         const char *attr_path,
                         struct diff_filespec *one,
                         struct diff_filespec *two,
-                        const char *xfrm_msg,
+                        struct strbuf *msg,
                         struct diff_options *o,
-                        int complete_rewrite)
+                        struct diff_filepair *p)
 {
+       const char *xfrm_msg = NULL;
+       int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score;
+
+       if (msg) {
+               fill_metainfo(msg, name, other, one, two, o, p);
+               xfrm_msg = msg->len ? msg->buf : NULL;
+       }
+
        if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
                pgm = NULL;
        else {
@@ -2145,11 +2215,6 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
                hashclr(one->sha1);
 }
 
-static int similarity_index(struct diff_filepair *p)
-{
-       return p->score * 100 / MAX_SCORE;
-}
-
 static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
 {
        /* Strip the prefix but do not molest /dev/null and absolute paths */
@@ -2163,13 +2228,11 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
 {
        const char *pgm = external_diff();
        struct strbuf msg;
-       char *xfrm_msg;
        struct diff_filespec *one = p->one;
        struct diff_filespec *two = p->two;
        const char *name;
        const char *other;
        const char *attr_path;
-       int complete_rewrite = 0;
 
        name  = p->one->path;
        other = (strcmp(name, p->two->path) ? p->two->path : NULL);
@@ -2179,83 +2242,34 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
 
        if (DIFF_PAIR_UNMERGED(p)) {
                run_diff_cmd(pgm, name, NULL, attr_path,
-                            NULL, NULL, NULL, o, 0);
+                            NULL, NULL, NULL, o, p);
                return;
        }
 
        diff_fill_sha1_info(one);
        diff_fill_sha1_info(two);
 
-       strbuf_init(&msg, PATH_MAX * 2 + 300);
-       switch (p->status) {
-       case DIFF_STATUS_COPIED:
-               strbuf_addf(&msg, "similarity index %d%%", similarity_index(p));
-               strbuf_addstr(&msg, "\ncopy from ");
-               quote_c_style(name, &msg, NULL, 0);
-               strbuf_addstr(&msg, "\ncopy to ");
-               quote_c_style(other, &msg, NULL, 0);
-               strbuf_addch(&msg, '\n');
-               break;
-       case DIFF_STATUS_RENAMED:
-               strbuf_addf(&msg, "similarity index %d%%", similarity_index(p));
-               strbuf_addstr(&msg, "\nrename from ");
-               quote_c_style(name, &msg, NULL, 0);
-               strbuf_addstr(&msg, "\nrename to ");
-               quote_c_style(other, &msg, NULL, 0);
-               strbuf_addch(&msg, '\n');
-               break;
-       case DIFF_STATUS_MODIFIED:
-               if (p->score) {
-                       strbuf_addf(&msg, "dissimilarity index %d%%\n",
-                                       similarity_index(p));
-                       complete_rewrite = 1;
-                       break;
-               }
-               /* fallthru */
-       default:
-               /* nothing */
-               ;
-       }
-
-       if (hashcmp(one->sha1, two->sha1)) {
-               int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
-
-               if (DIFF_OPT_TST(o, BINARY)) {
-                       mmfile_t mf;
-                       if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
-                           (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
-                               abbrev = 40;
-               }
-               strbuf_addf(&msg, "index %.*s..%.*s",
-                               abbrev, sha1_to_hex(one->sha1),
-                               abbrev, sha1_to_hex(two->sha1));
-               if (one->mode == two->mode)
-                       strbuf_addf(&msg, " %06o", one->mode);
-               strbuf_addch(&msg, '\n');
-       }
-
-       if (msg.len)
-               strbuf_setlen(&msg, msg.len - 1);
-       xfrm_msg = msg.len ? msg.buf : NULL;
-
        if (!pgm &&
            DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) &&
            (S_IFMT & one->mode) != (S_IFMT & two->mode)) {
-               /* a filepair that changes between file and symlink
+               /*
+                * a filepair that changes between file and symlink
                 * needs to be split into deletion and creation.
                 */
                struct diff_filespec *null = alloc_filespec(two->path);
                run_diff_cmd(NULL, name, other, attr_path,
-                            one, null, xfrm_msg, o, 0);
+                            one, null, &msg, o, p);
                free(null);
+               strbuf_release(&msg);
+
                null = alloc_filespec(one->path);
                run_diff_cmd(NULL, name, other, attr_path,
-                            null, two, xfrm_msg, o, 0);
+                            null, two, &msg, o, p);
                free(null);
        }
        else
                run_diff_cmd(pgm, name, other, attr_path,
-                            one, two, xfrm_msg, o, complete_rewrite);
+                            one, two, &msg, o, p);
 
        strbuf_release(&msg);
 }
diff --git a/dir.c b/dir.c
index cfaa28f..04a4b98 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -139,7 +139,7 @@ int match_pathspec(const char **pathspec, const char *name, int namelen, int pre
 
 static int no_wildcard(const char *string)
 {
-       return string[strcspn(string, "*?[{")] == '\0';
+       return string[strcspn(string, "*?[{\\")] == '\0';
 }
 
 void add_exclude(const char *string, const char *base,
index d58cca5..5bc9ce2 100644 (file)
@@ -943,6 +943,7 @@ static void end_packfile(void)
 {
        struct packed_git *old_p = pack_data, *new_p;
 
+       clear_delta_base_cache();
        if (object_count) {
                char *idx_name;
                int i;
@@ -1868,12 +1869,13 @@ static void file_change_m(struct branch *b)
        if (!p)
                die("Corrupt mode: %s", command_buf.buf);
        switch (mode) {
+       case 0644:
+       case 0755:
+               mode |= S_IFREG;
        case S_IFREG | 0644:
        case S_IFREG | 0755:
        case S_IFLNK:
        case S_IFGITLINK:
-       case 0644:
-       case 0755:
                /* ok */
                break;
        default:
@@ -1940,7 +1942,7 @@ static void file_change_m(struct branch *b)
                            typename(type), command_buf.buf);
        }
 
-       tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode, NULL);
+       tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
 }
 
 static void file_change_d(struct branch *b)
index 124cb58..59c148f 100755 (executable)
@@ -309,7 +309,7 @@ do_next () {
        squash|s)
                comment_for_reflog squash
 
-               has_action "$DONE" ||
+               test -f "$DONE" && has_action "$DONE" ||
                        die "Cannot 'squash' without a previous commit"
 
                mark_action_done
index 458a497..be6db5e 100755 (executable)
@@ -88,32 +88,79 @@ if [ -z "$names" ]; then
                echo Nothing new to pack.
        fi
 fi
-for name in $names ; do
-       fullbases="$fullbases pack-$name"
-       chmod a-w "$PACKTMP-$name.pack"
-       chmod a-w "$PACKTMP-$name.idx"
-       mkdir -p "$PACKDIR" || exit
 
+# Ok we have prepared all new packfiles.
+mkdir -p "$PACKDIR" || exit
+
+# First see if there are packs of the same name and if so
+# if we can move them out of the way (this can happen if we
+# repacked immediately after packing fully.
+rollback=
+failed=
+for name in $names
+do
        for sfx in pack idx
        do
-               if test -f "$PACKDIR/pack-$name.$sfx"
-               then
-                       mv -f "$PACKDIR/pack-$name.$sfx" \
-                               "$PACKDIR/old-pack-$name.$sfx"
-               fi
-       done &&
+               file=pack-$name.$sfx
+               test -f "$PACKDIR/$file" || continue
+               rm -f "$PACKDIR/old-$file" &&
+               mv "$PACKDIR/$file" "$PACKDIR/old-$file" || {
+                       failed=t
+                       break
+               }
+               rollback="$rollback $file"
+       done
+       test -z "$failed" || break
+done
+
+# If renaming failed for any of them, roll the ones we have
+# already renamed back to their original names.
+if test -n "$failed"
+then
+       rollback_failure=
+       for file in $rollback
+       do
+               mv "$PACKDIR/old-$file" "$PACKDIR/$file" ||
+               rollback_failure="$rollback_failure $file"
+       done
+       if test -n "$rollback_failure"
+       then
+               echo >&2 "WARNING: Some packs in use have been renamed by"
+               echo >&2 "WARNING: prefixing old- to their name, in order to"
+               echo >&2 "WARNING: replace them with the new version of the"
+               echo >&2 "WARNING: file.  But the operation failed, and"
+               echo >&2 "WARNING: attempt to rename them back to their"
+               echo >&2 "WARNING: original names also failed."
+               echo >&2 "WARNING: Please rename them in $PACKDIR manually:"
+               for file in $rollback_failure
+               do
+                       echo >&2 "WARNING:   old-$file -> $file"
+               done
+       fi
+       exit 1
+fi
+
+# Now the ones with the same name are out of the way...
+fullbases=
+for name in $names
+do
+       fullbases="$fullbases pack-$name"
+       chmod a-w "$PACKTMP-$name.pack"
+       chmod a-w "$PACKTMP-$name.idx"
        mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" &&
-       mv -f "$PACKTMP-$name.idx"  "$PACKDIR/pack-$name.idx" &&
-       test -f "$PACKDIR/pack-$name.pack" &&
-       test -f "$PACKDIR/pack-$name.idx" || {
-               echo >&2 "Couldn't replace the existing pack with updated one."
-               echo >&2 "The original set of packs have been saved as"
-               echo >&2 "old-pack-$name.{pack,idx} in $PACKDIR."
-               exit 1
-       }
-       rm -f "$PACKDIR/old-pack-$name.pack" "$PACKDIR/old-pack-$name.idx"
+       mv -f "$PACKTMP-$name.idx"  "$PACKDIR/pack-$name.idx" ||
+       exit
+done
+
+# Remove the "old-" files
+for name in $names
+do
+       rm -f "$PACKDIR/old-pack-$name.idx"
+       rm -f "$PACKDIR/old-pack-$name.pack"
 done
 
+# End of pack replacement.
+
 if test "$remove_redundant" = t
 then
        # We know $existing are all redundant.
index 6733b6f..0319c82 100644 (file)
@@ -97,7 +97,7 @@ BuildRequires:  perl(Error)
 %description -n perl-Git
 Perl interface to Git
 
-%define path_settings ETC_GITCONFIG=/etc/gitconfig prefix=%{_prefix} mandir=%{_mandir} htmldir=%{_docdir}/%{name}-core-%{version}
+%define path_settings ETC_GITCONFIG=/etc/gitconfig prefix=%{_prefix} mandir=%{_mandir} htmldir=%{_docdir}/%{name}-%{version}
 
 %prep
 %setup -q
@@ -189,6 +189,9 @@ rm -rf $RPM_BUILD_ROOT
 # No files for you!
 
 %changelog
+* Mon Feb 04 2009 David J. Mellor <dmellor@whistlingcat.com>
+- fixed broken git help -w after renaming the git-core package to git.
+
 * Fri Sep 12 2008 Quy Tonthat <qtonthat@gmail.com>
 - move git-cvsserver to bindir.
 
index ba94453..29a1783 100644 (file)
@@ -1012,8 +1012,8 @@ sub _temp_cache {
        my $temp_fd = \$TEMP_FILEMAP{$name};
        if (defined $$temp_fd and $$temp_fd->opened) {
                if ($TEMP_FILES{$$temp_fd}{locked}) {
-                       throw Error::Simple("Temp file with moniker '",
-                               $name, "' already in use");
+                       throw Error::Simple("Temp file with moniker '" .
+                               $name . "' already in use");
                }
        } else {
                if (defined $$temp_fd) {
index 88035a0..bea958e 100644 (file)
@@ -676,6 +676,7 @@ void free_pack_by_name(const char *pack_name)
        while (*pp) {
                p = *pp;
                if (strcmp(pack_name, p->pack_name) == 0) {
+                       clear_delta_base_cache();
                        close_pack_windows(p);
                        if (p->pack_fd != -1)
                                close(p->pack_fd);
@@ -1630,6 +1631,13 @@ static inline void release_delta_base_cache(struct delta_base_cache_entry *ent)
        }
 }
 
+void clear_delta_base_cache(void)
+{
+       unsigned long p;
+       for (p = 0; p < MAX_DELTA_CACHE; p++)
+               release_delta_base_cache(&delta_base_cache[p]);
+}
+
 static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
        void *base, unsigned long base_size, enum object_type type)
 {
@@ -2280,7 +2288,8 @@ static int create_tmpfile(char *buffer, size_t bufsiz, const char *filename)
 static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
                              void *buf, unsigned long len, time_t mtime)
 {
-       int fd, size, ret;
+       int fd, ret;
+       size_t size;
        unsigned char *compressed;
        z_stream stream;
        char *filename;
index 75a5a7e..c4fdade 100644 (file)
@@ -309,7 +309,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 
        /* basic@{time or number} format to query ref-log */
        reflog_len = at = 0;
-       if (str[len-1] == '}') {
+       if (len && str[len-1] == '}') {
                for (at = 0; at < len - 1; at++) {
                        if (str[at] == '@' && str[at+1] == '{') {
                                reflog_len = (len-1) - (at+2);
index 8666946..6a17113 100755 (executable)
@@ -19,6 +19,9 @@ do
     >$dir/a.$i
   done
 done
+>"#ignore1"
+>"#ignore2"
+>"#hidden"
 
 cat >expect <<EOF
 a.2
@@ -42,6 +45,9 @@ three/a.8
 EOF
 
 echo '.gitignore
+\#ignore1
+\#ignore2*
+\#hid*n
 output
 expect
 .gitignore
@@ -79,9 +85,10 @@ test_expect_success \
        >output &&
      test_cmp expect output'
 
-cat > excludes-file << EOF
+cat > excludes-file <<\EOF
 *.[1-8]
 e*
+\#*
 EOF
 
 git config core.excludesFile excludes-file
index 7d10a27..2cc8e7a 100755 (executable)
@@ -373,6 +373,38 @@ test_expect_success '--continue tries to commit, even for "edit"' '
        test $parent = $(git rev-parse HEAD^)
 '
 
+test_expect_success 'aborted --continue does not squash commits after "edit"' '
+       old=$(git rev-parse HEAD) &&
+       test_tick &&
+       FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+       echo "edited again" > file7 &&
+       git add file7 &&
+       (
+               FAKE_COMMIT_MESSAGE=" " &&
+               export FAKE_COMMIT_MESSAGE &&
+               test_must_fail git rebase --continue
+       ) &&
+       test $old = $(git rev-parse HEAD) &&
+       git rebase --abort
+'
+
+test_expect_success 'auto-amend only edited commits after "edit"' '
+       test_tick &&
+       FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+       echo "edited again" > file7 &&
+       git add file7 &&
+       FAKE_COMMIT_MESSAGE="edited file7 again" git commit &&
+       echo "and again" > file7 &&
+       git add file7 &&
+       test_tick &&
+       (
+               FAKE_COMMIT_MESSAGE="and again" &&
+               export FAKE_COMMIT_MESSAGE &&
+               test_must_fail git rebase --continue
+       ) &&
+       git rebase --abort
+'
+
 test_expect_success 'rebase a detached HEAD' '
        grandparent=$(git rev-parse HEAD~2) &&
        git checkout $(git rev-parse HEAD) &&
index 6da2128..bb4cf00 100755 (executable)
@@ -45,6 +45,7 @@ test_expect_success 'cherry-pick after renaming branch' '
 
        git checkout rename2 &&
        git cherry-pick added &&
+       test $(git rev-parse HEAD^) = $(git rev-parse rename2) &&
        test -f opos &&
        grep "Add extra line at the end" opos
 
@@ -54,6 +55,7 @@ test_expect_success 'revert after renaming branch' '
 
        git checkout rename1 &&
        git revert added &&
+       test $(git rev-parse HEAD^) = $(git rev-parse rename1) &&
        test -f spoo &&
        ! grep "Add extra line at the end" spoo
 
index 5533492..0f185ca 100755 (executable)
@@ -25,6 +25,10 @@ test_expect_success 'setup repository and commits' '
        git update-index foo &&
        git commit -m "foo back to file" &&
        git branch foo-back-to-file &&
+       printf "\0" > foo &&
+       git update-index foo &&
+       git commit -m "foo becomes binary" &&
+       git branch foo-becomes-binary &&
        rm -f foo &&
        git update-index --remove foo &&
        mkdir foo &&
@@ -85,6 +89,20 @@ test_expect_success 'symlink becomes file' '
        '
 test_debug 'cat patch'
 
+test_expect_success 'binary file becomes symlink' '
+       git checkout -f foo-becomes-binary &&
+       git diff-tree -p --binary HEAD foo-symlinked-to-bar > patch &&
+       git apply --index < patch
+       '
+test_debug 'cat patch'
+
+test_expect_success 'symlink becomes binary file' '
+       git checkout -f foo-symlinked-to-bar &&
+       git diff-tree -p --binary HEAD foo-becomes-binary > patch &&
+       git apply --index < patch
+       '
+test_debug 'cat patch'
+
 
 test_expect_success 'symlink becomes directory' '
        git checkout -f foo-symlinked-to-bar &&
index 66bb126..d2ec550 100755 (executable)
@@ -38,6 +38,39 @@ test_expect_success \
     'git diff-tree -r -M --name-status  HEAD^ HEAD | \
     grep "^R100..*path1/COPYING..*path0/COPYING"'
 
+test_expect_success \
+    'checking -k on non-existing file' \
+    'git mv -k idontexist path0'
+
+test_expect_success \
+    'checking -k on untracked file' \
+    'touch untracked1 &&
+     git mv -k untracked1 path0 &&
+     test -f untracked1 &&
+     test ! -f path0/untracked1'
+
+test_expect_success \
+    'checking -k on multiple untracked files' \
+    'touch untracked2 &&
+     git mv -k untracked1 untracked2 path0 &&
+     test -f untracked1 &&
+     test -f untracked2 &&
+     test ! -f path0/untracked1 &&
+     test ! -f path0/untracked2'
+
+test_expect_success \
+    'checking -f on untracked file with existing target' \
+    'touch path0/untracked1 &&
+     git mv -f untracked1 path0
+     test ! -f .git/index.lock &&
+     test -f untracked1 &&
+     test -f path0/untracked1'
+
+# clean up the mess in case bad things happen
+rm -f idontexist untracked1 untracked2 \
+     path0/idontexist path0/untracked1 path0/untracked2 \
+     .git/index.lock
+
 test_expect_success \
     'adding another file' \
     'cp ../../README path0/README &&
similarity index 100%
rename from dump-cache-tree.c
rename to test-dump-cache-tree.c
index a0bcb0e..2c0f5a3 100644 (file)
@@ -3,7 +3,7 @@
 int main(int argc, char **argv)
 {
        if (argc == 3 && !strcmp(argv[1], "normalize_absolute_path")) {
-               char *buf = xmalloc(strlen(argv[2])+1);
+               char *buf = xmalloc(PATH_MAX + 1);
                int rv = normalize_absolute_path(buf, argv[2]);
                assert(strlen(buf) == rv);
                puts(buf);
index 54f301d..4229eec 100644 (file)
@@ -240,8 +240,11 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info, con
        return ce;
 }
 
-static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmask, struct cache_entry *src[5],
-       const struct name_entry *names, const struct traverse_info *info)
+static int unpack_nondirectories(int n, unsigned long mask,
+                                unsigned long dirmask,
+                                struct cache_entry **src,
+                                const struct name_entry *names,
+                                const struct traverse_info *info)
 {
        int i;
        struct unpack_trees_options *o = info->data;
@@ -291,7 +294,7 @@ static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmas
 
 static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info)
 {
-       struct cache_entry *src[5] = { NULL, };
+       struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
        struct unpack_trees_options *o = info->data;
        const struct name_entry *p = names;