Merge branch 'jc/the-index'
authorJunio C Hamano <junkio@cox.net>
Wed, 25 Apr 2007 05:13:22 +0000 (22:13 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 25 Apr 2007 05:13:22 +0000 (22:13 -0700)
* jc/the-index:
  Make read-cache.c "the_index" free.
  Move index-related variables into a structure.

33 files changed:
Documentation/.gitignore
Documentation/config.txt
Documentation/git-checkout.txt
Documentation/git-clean.txt
Documentation/git-reset.txt
Documentation/gitattributes.txt
Makefile
builtin-diff.c
builtin-fetch--tool.c
cache.h
contrib/completion/git-completion.bash
contrib/fast-import/import-tars.perl
dir.c
fast-import.c
git-am.sh
git-applymbox.sh
git-checkout.sh
git-clean.sh
git-fetch.sh
git-quiltimport.sh
git-reset.sh
git-svn.perl
git.spec.in
object.c
object.h
revision.c
revision.h
sha1_name.c
t/t3700-add.sh
t/t4201-shortlog.sh
t/t5302-pack-index.sh
t/t6030-bisect-porcelain.sh
t/test-lib.sh

index b98d21e..a37b215 100644 (file)
@@ -1,7 +1,6 @@
 *.xml
 *.html
-*.1
-*.7
+*.[1-8]
 *.made
 howto-index.txt
 doc.dep
index b13ff3a..e0aff53 100644 (file)
@@ -300,6 +300,10 @@ branch.<name>.merge::
        branch.<name>.merge to the desired branch, and use the special setting
        `.` (a period) for branch.<name>.remote.
 
+clean.requireForce::
+       A boolean to make git-clean do nothing unless given -f or -n.  Defaults
+       to false.
+
 color.branch::
        A boolean to enable/disable color in the output of
        gitlink:git-branch[1]. May be set to `true` (or `always`),
index 4f2e847..918d8ee 100644 (file)
@@ -8,7 +8,7 @@ git-checkout - Checkout and switch to a branch
 SYNOPSIS
 --------
 [verse]
-'git-checkout' [-q] [-f] [-b [--track | --no-track] <new_branch> [-l]] [-m] [<branch>]
+'git-checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
 'git-checkout' [<tree-ish>] <paths>...
 
 DESCRIPTION
index c61afbc..5aff026 100644 (file)
@@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree
 SYNOPSIS
 --------
 [verse]
-'git-clean' [-d] [-n] [-q] [-x | -X] [--] <paths>...
+'git-clean' [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...
 
 DESCRIPTION
 -----------
@@ -25,6 +25,10 @@ OPTIONS
 -d::
        Remove untracked directories in addition to untracked files.
 
+-f::
+       If the git configuration specifies clean.forceRequire as true,
+       git-clean will refuse to run unless given -f or -n.
+
 -n::
        Don't actually remove anything, just show what would be done.
 
index 5b55cda..19c5b9b 100644 (file)
@@ -67,6 +67,8 @@ message, or both.  Leaves working tree as it was before "reset".
 <3> "reset" copies the old head to .git/ORIG_HEAD; redo the
 commit by starting with its log message.  If you do not need to
 edit the message further, you can give -C option instead.
++
+See also the --amend option to gitlink:git-commit[1].
 
 Undo commits permanently::
 +
index 1268717..857d55a 100644 (file)
@@ -49,10 +49,12 @@ Set to a value::
 Unspecified::
 
        No glob pattern matches the path, and nothing says if
-       the path has or does not have the attribute.
+       the path has or does not have the attribute, the
+       attribute for the path is said to be Unspecified.
 
 When more than one glob pattern matches the path, a later line
-overrides an earlier line.
+overrides an earlier line.  This overriding is done per
+attribute.
 
 When deciding what attributes are assigned to a path, git
 consults `$GIT_DIR/info/attributes` file (which has the highest
@@ -151,8 +153,34 @@ Unspecified::
        text, it is treated as text.  Otherwise it would
        generate `Binary files differ`.
 
-Any other value set to `diff` attribute is ignored and git acts
-as if the attribute is left unspecified.
+String::
+
+       Diff is shown using the specified custom diff driver.
+       The driver program is given its input using the same
+       calling convention as used for GIT_EXTERNAL_DIFF
+       program.
+
+
+Defining a custom diff driver
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The definition of a diff driver is done in `gitconfig`, not
+`gitattributes` file, so strictly speaking this manual page is a
+wrong place to talk about it.  However...
+
+To define a custom diff driver `jcdiff`, add a section to your
+`$GIT_DIR/config` file (or `$HOME/.gitconfig` file) like this:
+
+----------------------------------------------------------------
+[diff "jcdiff"]
+       command = j-c-diff
+----------------------------------------------------------------
+
+When git needs to show you a diff for the path with `diff`
+attribute set to `jcdiff`, it calls the command you specified
+with the above configuration, i.e. `j-c-diff`, with 7
+parameters, just like `GIT_EXTERNAL_DIFF` program is called.
+See gitlink:git[7] for details.
 
 
 Performing a three-way merge
@@ -183,13 +211,13 @@ Unspecified::
        different merge driver to be used for paths to which the
        `merge` attribute is unspecified.
 
-Any other string value::
+String::
 
        3-way merge is performed using the specified custom
        merge driver.  The built-in 3-way merge driver can be
        explicitly specified by asking for "text" driver; the
        built-in "take the current branch" driver can be
-       requested by "binary".
+       requested with "binary".
 
 
 Defining a custom merge driver
index 65bd2db..60c41fd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -141,7 +141,12 @@ prefix = $(HOME)
 bindir = $(prefix)/bin
 gitexecdir = $(bindir)
 template_dir = $(prefix)/share/git-core/templates/
-ETC_GITCONFIG = $(prefix)/etc/gitconfig
+ifeq ($(prefix),/usr)
+sysconfdir = /etc
+else
+sysconfdir = $(prefix)/etc
+endif
+ETC_GITCONFIG = $(sysconfdir)/gitconfig
 # DESTDIR=
 
 # default configuration for gitweb
@@ -160,7 +165,7 @@ GITWEB_FAVICON = git-favicon.png
 GITWEB_SITE_HEADER =
 GITWEB_SITE_FOOTER =
 
-export prefix bindir gitexecdir template_dir
+export prefix bindir gitexecdir template_dir sysconfdir
 
 CC = gcc
 AR = ar
index 2ae6009..7f367b6 100644 (file)
 #include "log-tree.h"
 #include "builtin.h"
 
-/* NEEDSWORK: struct object has place for name but we _do_
- * know mode when we extracted the blob out of a tree, which
- * we currently lose.
- */
 struct blobinfo {
        unsigned char sha1[20];
        const char *name;
+       unsigned mode;
 };
 
 static const char builtin_diff_usage[] =
@@ -35,7 +32,7 @@ static void stuff_change(struct diff_options *opt,
        struct diff_filespec *one, *two;
 
        if (!is_null_sha1(old_sha1) && !is_null_sha1(new_sha1) &&
-           !hashcmp(old_sha1, new_sha1))
+           !hashcmp(old_sha1, new_sha1) && (old_mode == new_mode))
                return;
 
        if (opt->reverse_diff) {
@@ -70,8 +67,12 @@ static int builtin_diff_b_f(struct rev_info *revs,
                die("'%s': %s", path, strerror(errno));
        if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
                die("'%s': not a regular file or symlink", path);
+
+       if (blob[0].mode == S_IFINVALID)
+               blob[0].mode = canon_mode(st.st_mode);
+
        stuff_change(&revs->diffopt,
-                    canon_mode(st.st_mode), canon_mode(st.st_mode),
+                    blob[0].mode, canon_mode(st.st_mode),
                     blob[0].sha1, null_sha1,
                     path, path);
        diffcore_std(&revs->diffopt);
@@ -88,8 +89,14 @@ static int builtin_diff_blobs(struct rev_info *revs,
        if (argc > 1)
                usage(builtin_diff_usage);
 
+       if (blob[0].mode == S_IFINVALID)
+               blob[0].mode = mode;
+
+       if (blob[1].mode == S_IFINVALID)
+               blob[1].mode = mode;
+
        stuff_change(&revs->diffopt,
-                    mode, mode,
+                    blob[0].mode, blob[1].mode,
                     blob[0].sha1, blob[1].sha1,
                     blob[0].name, blob[1].name);
        diffcore_std(&revs->diffopt);
@@ -272,6 +279,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                                die("more than two blobs given: '%s'", name);
                        hashcpy(blob[blobs].sha1, obj->sha1);
                        blob[blobs].name = name;
+                       blob[blobs].mode = list->mode;
                        blobs++;
                        continue;
 
index be341c1..3145c01 100644 (file)
@@ -571,9 +571,13 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
                return parse_reflist(reflist);
        }
        if (!strcmp("pick-rref", argv[1])) {
+               const char *ls_remote_result;
                if (argc != 4)
                        return error("pick-rref takes 2 args");
-               return pick_rref(sopt, argv[2], argv[3]);
+               ls_remote_result = argv[3];
+               if (!strcmp(ls_remote_result, "-"))
+                       ls_remote_result = get_stdin();
+               return pick_rref(sopt, argv[2], ls_remote_result);
        }
        if (!strcmp("expand-refs-wildcard", argv[1])) {
                const char *reflist;
diff --git a/cache.h b/cache.h
index 74e47df..f05b67a 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -24,6 +24,9 @@
 #define DTYPE(de)      DT_UNKNOWN
 #endif
 
+/* unknown mode (impossible combination S_IFIFO|S_IFCHR) */
+#define S_IFINVALID     0030000
+
 /*
  * A "directory link" is a link to another git directory.
  *
@@ -367,6 +370,7 @@ static inline unsigned int hexval(unsigned int c)
 #define DEFAULT_ABBREV 7
 
 extern int get_sha1(const char *str, unsigned char *sha1);
+extern int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode);
 extern int get_sha1_hex(const char *hex, unsigned char *sha1);
 extern char *sha1_to_hex(const unsigned char *sha1);   /* static buffer result! */
 extern int read_ref(const char *filename, unsigned char *sha1);
index 7c03403..46356e8 100755 (executable)
@@ -790,6 +790,7 @@ _git_config ()
                core.legacyHeaders
                core.packedGitWindowSize
                core.packedGitLimit
+               clean.requireForce
                color.branch
                color.branch.current
                color.branch.local
index 5585a8b..1842146 100755 (executable)
@@ -64,7 +64,12 @@ foreach my $tar_file (@ARGV)
                }
                print FI "\n";
 
-               my $path = "$prefix$name";
+               my $path;
+               if ($prefix) {
+                       $path = "$prefix/$name";
+               } else {
+                       $path = "$name";
+               }
                $files{$path} = [$next_mark++, $mode];
 
                $commit_time = $mtime if $mtime > $commit_time;
diff --git a/dir.c b/dir.c
index 6564a92..d306352 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -34,8 +34,9 @@ int common_prefix(const char **pathspec)
        prefix = slash - path + 1;
        while ((next = *++pathspec) != NULL) {
                int len = strlen(next);
-               if (len >= prefix && !memcmp(path, next, len))
+               if (len >= prefix && !memcmp(path, next, prefix))
                        continue;
+               len = prefix - 1;
                for (;;) {
                        if (!len)
                                return 0;
index cdd629d..c4c8cb9 100644 (file)
@@ -673,7 +673,7 @@ static void fixup_header_footer(void)
 
        buf = xmalloc(buf_sz);
        for (;;) {
-               size_t n = xread(pack_fd, buf, buf_sz);
+               ssize_t n = xread(pack_fd, buf, buf_sz);
                if (!n)
                        break;
                if (n < 0)
@@ -904,6 +904,12 @@ static int store_object(
        if (e->offset) {
                duplicate_count_by_type[type]++;
                return 1;
+       } else if (find_sha1_pack(sha1, packed_git)) {
+               e->type = type;
+               e->pack_id = MAX_PACK_ID;
+               e->offset = 1; /* just not zero! */
+               duplicate_count_by_type[type]++;
+               return 1;
        }
 
        if (last && last->data && last->depth < max_depth) {
@@ -2021,6 +2027,7 @@ static void import_marks(const char *input_file)
                        e = insert_object(sha1);
                        e->type = type;
                        e->pack_id = MAX_PACK_ID;
+                       e->offset = 1; /* just not zero! */
                }
                insert_mark(mark, e);
        }
@@ -2086,6 +2093,7 @@ int main(int argc, const char **argv)
        if (i != argc)
                usage(fast_import_usage);
 
+       prepare_packed_git();
        start_packfile();
        for (;;) {
                read_next_command();
index e69ecbf..c9f66e2 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -291,7 +291,7 @@ do
                        <"$dotest/$msgnum" >"$dotest/info" ||
                        stop_here $this
                test -s $dotest/patch || {
-                       echo "Patch is empty.  Was is split wrong?"
+                       echo "Patch is empty.  Was it split wrong?"
                        stop_here $this
                }
                git-stripspace < "$dotest/msg" > "$dotest/msg-clean"
index 3efd6a7..c18e80f 100755 (executable)
@@ -78,7 +78,7 @@ do
            git-mailinfo $keep_subject $utf8 \
                .dotest/msg .dotest/patch <$i >.dotest/info || exit 1
            test -s .dotest/patch || {
-               echo "Patch is empty.  Was is split wrong?"
+               echo "Patch is empty.  Was it split wrong?"
                exit 1
            }
            git-stripspace < .dotest/msg > .dotest/msg-clean
index deb0a9a..ed7c2c5 100755 (executable)
@@ -17,6 +17,7 @@ newbranch=
 newbranch_log=
 merge=
 quiet=
+v=-v
 LF='
 '
 while [ "$#" != "0" ]; do
@@ -47,6 +48,7 @@ while [ "$#" != "0" ]; do
                ;;
        "-q")
                quiet=1
+               v=
                ;;
        --)
                break
@@ -197,7 +199,7 @@ fi
 
 if [ "$force" ]
 then
-    git-read-tree --reset -u $new
+    git-read-tree $v --reset -u $new
 else
     git-update-index --refresh >/dev/null
     merge_error=$(git-read-tree -m -u --exclude-per-directory=.gitignore $old $new 2>&1) || (
@@ -210,7 +212,7 @@ else
        # Match the index to the working tree, and do a three-way.
        git diff-files --name-only | git update-index --remove --stdin &&
        work=`git write-tree` &&
-       git read-tree --reset -u $new || exit
+       git read-tree $v --reset -u $new || exit
 
        eval GITHEAD_$new='${new_name:-${branch:-$new}}' &&
        eval GITHEAD_$work=local &&
@@ -221,7 +223,7 @@ else
        # this is not a real merge before committing, but just carrying
        # the working tree changes along.
        unmerged=`git ls-files -u`
-       git read-tree --reset $new
+       git read-tree $v --reset $new
        case "$unmerged" in
        '')     ;;
        *)
index db177a7..299309d 100755 (executable)
@@ -3,9 +3,10 @@
 # Copyright (c) 2005-2006 Pavel Roskin
 #
 
-USAGE="[-d] [-n] [-q] [-x | -X] [--] <paths>..."
+USAGE="[-d] [-f] [-n] [-q] [-x | -X] [--] <paths>..."
 LONG_USAGE='Clean untracked files from the working directory
        -d      remove directories as well
+       -f      override clean.requireForce and clean anyway
        -n      don'\''t remove anything, just show what would be done
        -q      be quiet, only report errors
        -x      remove ignored files as well
@@ -19,6 +20,7 @@ require_work_tree
 ignored=
 ignoredonly=
 cleandir=
+disabled="`git-config --bool clean.requireForce`"
 rmf="rm -f --"
 rmrf="rm -rf --"
 rm_refuse="echo Not removing"
@@ -30,7 +32,11 @@ do
        -d)
                cleandir=1
                ;;
+       -f)
+               disabled=
+               ;;
        -n)
+               disabled=
                rmf="echo Would remove"
                rmrf="echo Would remove"
                rm_refuse="echo Would not remove"
@@ -58,6 +64,11 @@ do
        shift
 done
 
+if [ "$disabled" = true ]; then
+       echo "clean.requireForce set and -n or -f not given; refusing to clean"
+       exit 1
+fi
+
 case "$ignored,$ignoredonly" in
        1,1) usage;;
 esac
index 832b20c..0e05cf1 100755 (executable)
@@ -189,8 +189,8 @@ fetch_all_at_once () {
                        # See if all of what we are going to fetch are
                        # connected to our repository's tips, in which
                        # case we do not have to do any fetch.
-                       theirs=$(git-fetch--tool -s pick-rref \
-                                       "$rref" "$ls_remote_result") &&
+                       theirs=$(echo "$ls_remote_result" | \
+                               git-fetch--tool -s pick-rref "$rref" "-") &&
 
                        # This will barf when $theirs reach an object that
                        # we do not have in our repository.  Otherwise,
@@ -198,7 +198,8 @@ fetch_all_at_once () {
                        git-rev-list --objects $theirs --not --all \
                                >/dev/null 2>/dev/null
                then
-                       git-fetch--tool pick-rref "$rref" "$ls_remote_result"
+                       echo "$ls_remote_result" | \
+                               git-fetch--tool pick-rref "$rref" "-"
                else
                        git-fetch-pack --thin $exec $keep $shallow_depth \
                                $quiet $no_progress "$remote" $rref ||
@@ -263,8 +264,8 @@ fetch_per_ref () {
          fi
 
          # Find $remote_name from ls-remote output.
-         head=$(git-fetch--tool -s pick-rref \
-                       "$remote_name" "$ls_remote_result")
+         head=$(echo "$ls_remote_result" | \
+               git-fetch--tool -s pick-rref "$remote_name" "-")
          expr "z$head" : "z$_x40\$" >/dev/null ||
                die "No such ref $remote_name at $remote"
          echo >&2 "Fetching $remote_name from $remote using $proto"
index 018cc75..a7a6757 100755 (executable)
@@ -74,7 +74,7 @@ for patch_name in $(cat "$QUILT_PATCHES/series" | grep -v '^#'); do
        echo $patch_name
        (cat $QUILT_PATCHES/$patch_name | git-mailinfo "$tmp_msg" "$tmp_patch" > "$tmp_info") || exit 3
        test -s .dotest/patch || {
-               echo "Patch is empty.  Was is split wrong?"
+               echo "Patch is empty.  Was it split wrong?"
                exit 1
        }
 
index fee6d98..a172d7c 100755 (executable)
@@ -71,7 +71,7 @@ then
                die "Cannot do a soft reset in the middle of a merge."
        fi
 else
-       git-read-tree --reset $update "$rev" || exit
+       git-read-tree -v --reset $update "$rev" || exit
 fi
 
 # Any resets update HEAD to the head being switched to.
index efc4c88..077d6b3 100755 (executable)
@@ -1866,11 +1866,14 @@ sub make_log_entry {
        } elsif ($self->use_svnsync_props) {
                my $full_url = $self->svnsync->{url};
                $full_url .= "/$self->{path}" if length $self->{path};
+               remove_username($full_url);
                my $uuid = $self->svnsync->{uuid};
                $log_entry{metadata} = "$full_url\@$rev $uuid";
                $email ||= "$author\@$uuid"
        } else {
-               $log_entry{metadata} = $self->metadata_url. "\@$rev " .
+               my $url = $self->metadata_url;
+               remove_username($url);
+               $log_entry{metadata} = "$url\@$rev " .
                                       $self->ra->get_uuid;
                $email ||= "$author\@" . $self->ra->get_uuid;
        }
index f0746ed..556bdda 100644 (file)
@@ -96,12 +96,14 @@ Perl interface to Git
 
 %build
 make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" WITH_P4IMPORT=YesPlease \
+     ETC_GITCONFIG=/etc/gitconfig \
      prefix=%{_prefix} PYTHON_PATH=%{python_path} all %{!?_without_docs: doc}
 
 %install
 rm -rf $RPM_BUILD_ROOT
 make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" DESTDIR=$RPM_BUILD_ROOT \
      WITH_P4IMPORT=YesPlease prefix=%{_prefix} mandir=%{_mandir} \
+     ETC_GITCONFIG=/etc/gitconfig \
      PYTHON_PATH=%{python_path} \
      INSTALLDIRS=vendor install %{!?_without_docs: install-doc}
 find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';'
index 7bd3fec..37d1363 100644 (file)
--- a/object.c
+++ b/object.c
@@ -230,6 +230,11 @@ int object_list_contains(struct object_list *list, struct object *obj)
 }
 
 void add_object_array(struct object *obj, const char *name, struct object_array *array)
+{
+       add_object_array_with_mode(obj, name, array, S_IFINVALID);
+}
+
+void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode)
 {
        unsigned nr = array->nr;
        unsigned alloc = array->alloc;
@@ -243,5 +248,6 @@ void add_object_array(struct object *obj, const char *name, struct object_array
        }
        objects[nr].item = obj;
        objects[nr].name = name;
+       objects[nr].mode = mode;
        array->nr = ++nr;
 }
index 3e26a0e..94f19ee 100644 (file)
--- a/object.h
+++ b/object.h
@@ -17,6 +17,7 @@ struct object_array {
        struct object_array_entry {
                struct object *item;
                const char *name;
+               unsigned mode;
        } *objects;
 };
 
@@ -77,5 +78,6 @@ int object_list_contains(struct object_list *list, struct object *obj);
 
 /* Object array handling .. */
 void add_object_array(struct object *obj, const char *name, struct object_array *array);
+void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode);
 
 #endif /* OBJECT_H */
index ce70f48..49bd292 100644 (file)
@@ -115,10 +115,15 @@ void mark_parents_uninteresting(struct commit *commit)
 }
 
 void add_pending_object(struct rev_info *revs, struct object *obj, const char *name)
+{
+       add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
+}
+
+void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
 {
        if (revs->no_walk && (obj->flags & UNINTERESTING))
                die("object ranges do not make sense when not walking revisions");
-       add_object_array(obj, name, &revs->pending);
+       add_object_array_with_mode(obj, name, &revs->pending, mode);
        if (revs->reflog_info && obj->type == OBJ_COMMIT)
                add_reflog_for_walk(revs->reflog_info,
                                (struct commit *)obj, name);
@@ -723,6 +728,7 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
                        int flags,
                        int cant_be_filename)
 {
+       unsigned mode;
        char *dotdot;
        struct object *object;
        unsigned char sha1[20];
@@ -796,12 +802,12 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
                local_flags = UNINTERESTING;
                arg++;
        }
-       if (get_sha1(arg, sha1))
+       if (get_sha1_with_mode(arg, sha1, &mode))
                return -1;
        if (!cant_be_filename)
                verify_non_filename(revs->prefix, arg);
        object = get_reference(revs, arg, sha1, flags ^ local_flags);
-       add_pending_object(revs, object, arg);
+       add_pending_object_with_mode(revs, object, arg, mode);
        return 0;
 }
 
@@ -1177,10 +1183,11 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
        if (def && !revs->pending.nr) {
                unsigned char sha1[20];
                struct object *object;
-               if (get_sha1(def, sha1))
+               unsigned mode;
+               if (get_sha1_with_mode(def, sha1, &mode))
                        die("bad default revision '%s'", def);
                object = get_reference(revs, def, sha1, 0);
-               add_pending_object(revs, object, def);
+               add_pending_object_with_mode(revs, object, def, mode);
        }
 
        if (revs->topo_order)
index 8a02618..5b41e2d 100644 (file)
@@ -131,5 +131,6 @@ extern void add_object(struct object *obj,
                       const char *name);
 
 extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
+extern void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode);
 
 #endif
index b0b12bb..55f25a2 100644 (file)
@@ -643,11 +643,17 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
  */
 int get_sha1(const char *name, unsigned char *sha1)
 {
-       int ret, bracket_depth;
        unsigned unused;
+       return get_sha1_with_mode(name, sha1, &unused);
+}
+
+int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
+{
+       int ret, bracket_depth;
        int namelen = strlen(name);
        const char *cp;
 
+       *mode = S_IFINVALID;
        prepare_alt_odb();
        ret = get_sha1_1(name, namelen, sha1);
        if (!ret)
@@ -685,6 +691,7 @@ int get_sha1(const char *name, unsigned char *sha1)
                                break;
                        if (ce_stage(ce) == stage) {
                                hashcpy(sha1, ce->sha1);
+                               *mode = ntohl(ce->ce_mode);
                                return 0;
                        }
                        pos++;
@@ -703,7 +710,7 @@ int get_sha1(const char *name, unsigned char *sha1)
                unsigned char tree_sha1[20];
                if (!get_sha1_1(name, cp-name, tree_sha1))
                        return get_tree_entry(tree_sha1, cp+1, sha1,
-                                             &unused);
+                                             mode);
        }
        return ret;
 }
index 08e0352..ad8cc7d 100755 (executable)
@@ -104,4 +104,10 @@ test_expect_success 'add ignored ones with -f' '
        git-ls-files --error-unmatch d.ig/d.if d.ig/d.ig
 '
 
+mkdir 1 1/2 1/3
+touch 1/2/a 1/3/b 1/2/c
+test_expect_success 'check correct prefix detection' '
+       git add 1/2/a 1/3/b 1/2/c
+'
+
 test_done
index c27e39c..a48733c 100755 (executable)
@@ -15,19 +15,19 @@ commit=$( (echo "Test"; echo) | git commit-tree $tree )
 git update-ref HEAD $commit
 
 echo 2 > a1
-git commit -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1
+git commit --quiet -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1
 
 # test if the wrapping is still valid when replacing all i's by treble clefs.
 echo 3 > a1
-git commit -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1
+git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1
 
 # now fsck up the utf8
 git repo-config i18n.commitencoding non-utf-8
 echo 4 > a1
-git commit -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1
+git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1
 
 echo 5 > a1
-git commit -m "a                                                               12      34      56      78" a1
+git commit --quiet -m "a                                                               12      34      56      78" a1
 
 git shortlog -w HEAD > out
 
index 232e5f1..6902fc6 100755 (executable)
@@ -16,7 +16,7 @@ test_expect_success \
          test-genrandom "$i" 8192 >>file_$i &&
          git-update-index --add file_$i || return 1
      done &&
-     echo 101 >file_101 && tail -c 8192 file_100 >>file_101 &&
+     { echo 101 && test-genrandom 100 8192; } >file_101 &&
      git-update-index --add file_101 &&
      tree=`git-write-tree` &&
      commit=`git-commit-tree $tree </dev/null` && {
index 13e9379..30f6ade 100755 (executable)
@@ -22,22 +22,25 @@ add_line_into_file()
         MSG="Create file <$_file> with <$_line> inside."
     fi
 
-    git-commit -m "$MSG" $_file
+    test_tick
+    git-commit --quiet -m "$MSG" $_file
 }
 
 HASH1=
+HASH2=
 HASH3=
 HASH4=
 
-test_expect_success \
-    'set up basic repo with 1 file (hello) and 4 commits' \
-    'add_line_into_file "1: Hello World" hello &&
+test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' '
+     add_line_into_file "1: Hello World" hello &&
+     HASH1=$(git rev-parse --verify HEAD) &&
      add_line_into_file "2: A new day for git" hello &&
+     HASH2=$(git rev-parse --verify HEAD) &&
      add_line_into_file "3: Another new day for git" hello &&
+     HASH3=$(git rev-parse --verify HEAD) &&
      add_line_into_file "4: Ciao for now" hello &&
-     HASH1=$(git rev-list HEAD | tail -1) &&
-     HASH3=$(git rev-list HEAD | head -2 | tail -1) &&
-     HASH4=$(git rev-list HEAD | head -1)'
+     HASH4=$(git rev-parse --verify HEAD)
+'
 
 test_expect_success 'bisect starts with only one bad' '
        git bisect reset &&
index c075474..f2c6bd3 100644 (file)
@@ -36,6 +36,10 @@ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
 export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
 export EDITOR VISUAL
 
+# Protect ourselves from common misconfiguration to export
+# CDPATH into the environment
+unset CDPATH
+
 case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
        1|2|true)
                echo "* warning: Some tests will not work if GIT_TRACE" \