GIT 0.99.9c v0.99.9c
authorJunio C Hamano <junkio@cox.net>
Thu, 3 Nov 2005 23:45:36 +0000 (15:45 -0800)
committerJunio C Hamano <junkio@cox.net>
Thu, 3 Nov 2005 23:45:36 +0000 (15:45 -0800)
Signed-off-by: Junio C Hamano <junkio@cox.net>
25 files changed:
.gitignore
Documentation/git-rev-parse.txt
Documentation/tutorial.txt
Makefile
README
commit.c
config.c
debian/changelog
fetch-pack.c
git-branch.sh
git-checkout.sh
git-clone.sh
git-commit.sh
git-merge-ours.sh [new file with mode: 0755]
git-merge.sh
git-pull.sh
ls-files.c
name-rev.c
send-pack.c
server-info.c
sha1_name.c
t/t3001-ls-files-others-exclude.sh
tag.c
tag.h
upload-pack.c

index 927c89c..3edf6b4 100644 (file)
@@ -50,6 +50,7 @@ git-merge-base
 git-merge-index
 git-merge-octopus
 git-merge-one-file
+git-merge-ours
 git-merge-recursive
 git-merge-resolve
 git-merge-stupid
index 099db29..431b8f6 100644 (file)
@@ -72,6 +72,14 @@ OPTIONS
        path of the current directory relative to the top-level
        directory.
 
+--since=datestring, --after=datestring::
+       Parses the date string, and outputs corresponding
+       --max-age= parameter for git-rev-list command.
+
+--until=datestring, --before=datestring::
+       Parses the date string, and outputs corresponding
+       --min-age= parameter for git-rev-list command.
+
 <args>...::
        Flags and parameters to be parsed.
 
@@ -124,6 +132,32 @@ which is passed to 'git-rev-list'.  Two revision parameters
 concatenated with '..' is a short-hand for writing a range
 between them.  I.e. 'r1..r2' is equivalent to saying '{caret}r1 r2'
 
+Here is an illustration, by Jon Loeliger.  Both node B and C are
+a commit parents of commit node A.  Parent commits are ordered
+left-to-right.
+
+    G   H   I   J
+     \ /     \ /
+      D   E   F
+       \  |  /
+        \ | /
+         \|/
+          B     C
+           \   /
+            \ /
+             A
+
+    A =      = A^0
+    B = A^   = A^1     = A~1
+    C = A^2  = A^2
+    D = A^^  = A^1^1   = A~2
+    E = B^2  = A^^2
+    F = B^3  = A^^3
+    G = A^^^ = A^1^1^1 = A~3
+    H = D^2  = B^^2    = A^^^2  = A~2^2
+    I = F^   = B^3^    = A^^3^
+    J = F^2  = B^3^2   = A^^3^2
+
 
 Author
 ------
index 20a4cb1..214673d 100644 (file)
@@ -455,6 +455,41 @@ the same diff that we've already seen several times, we can now do
 (again, `-p` means to show the difference as a human-readable patch),
 and it will show what the last commit (in `HEAD`) actually changed.
 
+[NOTE]
+============
+Here is an ASCII art by Jon Loeliger that illustrates how
+various diff-\* commands compare things.
+
+                      diff-tree
+                       +----+
+                       |    |
+                       |    |
+                       V    V
+                    +-----------+
+                    | Object DB |
+                    |  Backing  |
+                    |   Store   |
+                    +-----------+
+                      ^    ^
+                      |    |
+                      |    |  diff-index --cached
+                      |    |
+          diff-index  |    V
+                      |  +-----------+
+                      |  |   Index   |
+                      |  |  "cache"  |
+                      |  +-----------+
+                      |    ^
+                      |    |
+                      |    |  diff-files
+                      |    |
+                      V    V
+                    +-----------+
+                    |  Working  |
+                    | Directory |
+                    +-----------+
+============
+
 More interestingly, you can also give `git-diff-tree` the `-v` flag, which
 tells it to also show the commit message and author and date of the
 commit, and you can tell it to show a whole series of diffs.
index 5606c83..f96da67 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@
 
 # DEFINES += -DUSE_STDEV
 
-GIT_VERSION = 0.99.9b
+GIT_VERSION = 0.99.9c
 
 CFLAGS = -g -O2 -Wall
 ALL_CFLAGS = $(CFLAGS) $(PLATFORM_DEFINES) $(DEFINES)
@@ -89,7 +89,7 @@ SCRIPT_SH = \
        git-tag.sh git-verify-tag.sh git-whatchanged.sh git.sh \
        git-applymbox.sh git-applypatch.sh git-am.sh \
        git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
-       git-merge-resolve.sh git-grep.sh
+       git-merge-resolve.sh git-merge-ours.sh git-grep.sh
 
 SCRIPT_PERL = \
        git-archimport.perl git-cvsimport.perl git-relink.perl \
@@ -189,9 +189,9 @@ endif
 ifeq ($(uname_S),SunOS)
        NEEDS_SOCKET = YesPlease
        NEEDS_NSL = YesPlease
+       NEEDS_LIBICONV = YesPlease
        SHELL_PATH = /bin/bash
        NO_STRCASESTR = YesPlease
-       CURLDIR = /opt/sfw
        INSTALL = ginstall
        TAR = gtar
        PLATFORM_DEFINES += -D__EXTENSIONS__
@@ -397,8 +397,8 @@ doc:
 test: all
        $(MAKE) -C t/ all
 
-test-date$X: test-date.c date.o
-       $(CC) $(ALL_CFLAGS) -o $@ test-date.c date.o
+test-date$X: test-date.c date.o ctype.o
+       $(CC) $(ALL_CFLAGS) -o $@ test-date.c date.o ctype.o
 
 test-delta$X: test-delta.c diff-delta.o patch-delta.o
        $(CC) $(ALL_CFLAGS) -o $@ $^
diff --git a/README b/README
index 0ee49d4..4a2616b 100644 (file)
--- a/README
+++ b/README
@@ -399,6 +399,46 @@ save the note about that state, in practice we tend to just write the
 result to the file `.git/HEAD`, so that we can always see what the
 last committed state was.
 
+Here is an ASCII art by Jon Loeliger that illustrates how
+various pieces fit together.
+
+------------
+
+                     commit-tree
+                      commit obj
+                       +----+
+                       |    |
+                       |    |
+                       V    V
+                    +-----------+
+                    | Object DB |
+                    |  Backing  |
+                    |   Store   |
+                    +-----------+
+                       ^
+           write-tree  |     |
+             tree obj  |     |
+                       |     |  read-tree
+                       |     |  tree obj
+                             V
+                    +-----------+
+                    |   Index   |
+                    |  "cache"  |
+                    +-----------+
+         update-index  ^
+             blob obj  |     |
+                       |     |
+    checkout-index -u  |     |  checkout-index
+             stat      |     |  blob obj
+                             V
+                    +-----------+
+                    |  Working  |
+                    | Directory |
+                    +-----------+
+
+------------
+
+
 6) Examining the data
 ~~~~~~~~~~~~~~~~~~~~~
 
index 8f40318..a8c9bfc 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -55,7 +55,7 @@ static struct commit *check_commit(struct object *obj,
 struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
                                              int quiet)
 {
-       struct object *obj = deref_tag(parse_object(sha1));
+       struct object *obj = deref_tag(parse_object(sha1), NULL, 0);
 
        if (!obj)
                return NULL;
index 519fecf..e89bab2 100644 (file)
--- a/config.c
+++ b/config.c
@@ -13,6 +13,14 @@ static int get_next_char(void)
        c = '\n';
        if ((f = config_file) != NULL) {
                c = fgetc(f);
+               if (c == '\r') {
+                       /* DOS like systems */
+                       c = fgetc(f);
+                       if (c != '\n') {
+                               ungetc(c, f);
+                               c = '\r';
+                       }
+               }
                if (c == '\n')
                        config_linenr++;
                if (c == EOF) {
index ee68af5..cc97660 100644 (file)
@@ -1,3 +1,9 @@
+git-core (0.99.9c-0) unstable; urgency=low
+
+  * GIT 0.99.9c
+
+ -- Junio C Hamano <junkio@cox.net>  Thu,  3 Nov 2005 15:44:54 -0800
+
 git-core (0.99.9b-0) unstable; urgency=low
 
   * GIT 0.99.9b
index 3df9911..cb21715 100644 (file)
@@ -38,9 +38,9 @@ static void rev_list_push(struct commit *commit, int mark)
 
 static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
 {
-       struct object *o = deref_tag(parse_object(sha1));
+       struct object *o = deref_tag(parse_object(sha1), path, 0);
 
-       if (o->type == commit_type)
+       if (o && o->type == commit_type)
                rev_list_push((struct commit *)o, SEEN);
 
        return 0;
@@ -317,7 +317,8 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
         * Don't mark them common yet; the server has to be told so first.
         */
        for (ref = *refs; ref; ref = ref->next) {
-               struct object *o = deref_tag(lookup_object(ref->old_sha1));
+               struct object *o = deref_tag(lookup_object(ref->old_sha1),
+                                            NULL, 0);
 
                if (!o || o->type != commit_type || !(o->flags & COMPLETE))
                        continue;
index e2db906..67f113a 100755 (executable)
@@ -102,4 +102,6 @@ rev=$(git-rev-parse --verify "$head") || exit
 git-check-ref-format "heads/$branchname" ||
        die "we do not like '$branchname' as a branch name."
 
+leading=`expr "refs/heads/$branchname" : '\(.*\)/'` &&
+mkdir -p "$GIT_DIR/$leading" &&
 echo $rev > "$GIT_DIR/refs/heads/$branchname"
index cb33fdc..4c08f36 100755 (executable)
@@ -126,7 +126,9 @@ fi
 #
 if [ "$?" -eq 0 ]; then
        if [ "$newbranch" ]; then
-               echo $new > "$GIT_DIR/refs/heads/$newbranch"
+               leading=`expr "refs/heads/$newbranch" : '\(.*\)/'` &&
+               mkdir -p "$GIT_DIR/$leading" &&
+               echo $new >"$GIT_DIR/refs/heads/$newbranch" || exit
                branch="$newbranch"
        fi
        [ "$branch" ] &&
index 18e692a..c27a913 100755 (executable)
@@ -196,10 +196,17 @@ cd $D || exit
 
 if test -f ".git/HEAD"
 then
-       mkdir -p .git/remotes || exit
-       echo >.git/remotes/origin \
-       "URL: $repo
-Pull: master:origin"
+       head_points_at=`git-symbolic-ref HEAD`
+       case "$head_points_at" in
+       refs/heads/*)
+               head_points_at=`expr "$head_points_at" : 'refs/heads/\(.*\)'`
+               mkdir -p .git/remotes &&
+               echo >.git/remotes/origin \
+               "URL: $repo
+Pull: $head_points_at:origin"
+               cp ".git/refs/heads/$head_points_at" .git/refs/heads/origin
+       esac
+
        case "$no_checkout" in
        '')
                git checkout
index 10651d8..daf90f1 100755 (executable)
@@ -129,6 +129,9 @@ then
 elif test "$use_commit" != ""
 then
        git-cat-file commit "$use_commit" | sed -e '1,/^$/d'
+elif test -f "$GIT_DIR/MERGE_HEAD" && test -f "$GIT_DIR/MERGE_MSG"
+then
+       cat "$GIT_DIR/MERGE_MSG"
 fi | git-stripspace >"$GIT_DIR"/COMMIT_EDITMSG
 
 case "$signoff" in
@@ -144,9 +147,6 @@ t)
 esac
 
 if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-
-       test -f "$GIT_DIR/MERGE_MSG" && cat "$GIT_DIR/MERGE_MSG"
-
        echo "#"
        echo "# It looks like your may be committing a MERGE."
        echo "# If this is not correct, please remove the file"
diff --git a/git-merge-ours.sh b/git-merge-ours.sh
new file mode 100755 (executable)
index 0000000..4f3d053
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# Pretend we resolved the heads, but declare our tree trumps everybody else.
+#
+
+# We need to exit with 2 if the index does not match our HEAD tree,
+# because the current index is what we will be committing as the
+# merge result.
+
+test "$(git-diff-index --cached --name-status HEAD)" = "" || exit 2
+
+exit 0
index 6ad96eb..b810fce 100755 (executable)
@@ -9,12 +9,12 @@ LF='
 '
 
 usage () {
-    die "git-merge [-n] [-s <strategy>]... <merge-message> <head> <remote>+"
+    die "git-merge [-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+"
 }
 
 # all_strategies='resolve recursive stupid octopus'
 
-all_strategies='recursive octopus resolve stupid'
+all_strategies='recursive octopus resolve stupid ours'
 default_strategies='resolve octopus'
 use_strategies=
 
@@ -63,6 +63,8 @@ do
        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
                --no-summa|--no-summar|--no-summary)
                no_summary=t ;;
+       --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
+               no_commit=t ;;
        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
                --strateg=*|--strategy=*|\
        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@ -111,18 +113,18 @@ done
 common=$(git-show-branch --merge-base $head "$@")
 echo "$head" >"$GIT_DIR/ORIG_HEAD"
 
-case "$#,$common" in
-*,'')
+case "$#,$common,$no_commit" in
+*,'',*)
        # No common ancestors found. We need a real merge.
        ;;
-1,"$1")
+1,"$1",*)
        # If head can reach all the merge then we are up to date.
        # but first the most common case of merging one remote
        echo "Already up-to-date."
        dropsave
        exit 0
        ;;
-1,"$head")
+1,"$head",*)
        # Again the most common case of merging one remote.
        echo "Updating from $head to $1."
        git-update-index --refresh 2>/dev/null
@@ -132,11 +134,11 @@ case "$#,$common" in
        dropsave
        exit 0
        ;;
-1,?*"$LF"?*)
+1,?*"$LF"?*,*)
        # We are not doing octopus and not fast forward.  Need a
        # real merge.
        ;;
-1,*)
+1,*,)
        # We are not doing octopus, not fast forward, and have only
        # one common.  See if it is really trivial.
        echo "Trying really trivial in-index merge..."
@@ -210,12 +212,18 @@ do
     # Remember which strategy left the state in the working tree
     wt_strategy=$strategy
 
-    git-merge-$strategy $common -- "$head_arg" "$@" || {
+    git-merge-$strategy $common -- "$head_arg" "$@"
+    exit=$?
+    if test "$no_commit" = t && test "$exit" = 0
+    then
+       exit=1 ;# pretend it left conflicts.
+    fi
+
+    test "$exit" = 0 || {
 
        # The backend exits with 1 when conflicts are left to be resolved,
        # with 2 when it does not handle the given merge at all.
 
-       exit=$?
        if test "$exit" -eq 1
        then
            cnt=`{
@@ -272,4 +280,4 @@ do
 done >"$GIT_DIR/MERGE_HEAD"
 echo $merge_msg >"$GIT_DIR/MERGE_MSG"
 
-die "Automatic merge failed; fix up by hand"
+die "Automatic merge failed/prevented; fix up by hand"
index d476518..9601627 100755 (executable)
@@ -10,13 +10,15 @@ usage () {
     die "git pull [-n] [-s strategy]... <repo> <head>..."
 }
 
-strategy_args= no_summary=
+strategy_args= no_summary= no_commit=
 while case "$#,$1" in 0) break ;; *,-*) ;; *) break ;; esac
 do
        case "$1" in
        -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
                --no-summa|--no-summar|--no-summary)
                no_summary=-n ;;
+       --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
+               no_commit=--no-commit ;;
        -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
                --strateg=*|--strategy=*|\
        -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@ -81,4 +83,4 @@ case "$strategy_args" in
 esac
 
 merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD")
-git-merge $no_summary $strategy_args "$merge_name" HEAD $merge_head
+git-merge $no_summary $no_commit $strategy_args "$merge_name" HEAD $merge_head
index 3085b2f..d9c8b21 100644 (file)
@@ -97,7 +97,7 @@ static int add_excludes_from_file_1(const char *fname,
        for (i = 0; i < size; i++) {
                if (buf[i] == '\n') {
                        if (entry != buf + i && entry[0] != '#') {
-                               buf[i] = 0;
+                               buf[i - (i && buf[i-1] == '\r')] = 0;
                                add_exclude(entry, base, baselen, which);
                        }
                        entry = buf + i + 1;
index 21fecdf..59194f1 100644 (file)
@@ -164,7 +164,7 @@ int main(int argc, char **argv)
                        continue;
                }
 
-               o = deref_tag(parse_object(sha1));
+               o = deref_tag(parse_object(sha1), *argv, 0);
                if (!o || o->type != commit_type) {
                        fprintf(stderr, "Could not get commit for %s. Skipping.\n",
                                        *argv);
index 9f9a6e7..3eeb18f 100644 (file)
@@ -126,12 +126,12 @@ static int ref_newer(const unsigned char *new_sha1,
        /* Both new and old must be commit-ish and new is descendant of
         * old.  Otherwise we require --force.
         */
-       o = deref_tag(parse_object(old_sha1));
+       o = deref_tag(parse_object(old_sha1), NULL, 0);
        if (!o || o->type != commit_type)
                return 0;
        old = (struct commit *) o;
 
-       o = deref_tag(parse_object(new_sha1));
+       o = deref_tag(parse_object(new_sha1), NULL, 0);
        if (!o || o->type != commit_type)
                return 0;
        new = (struct commit *) o;
index ba53591..0cba8e1 100644 (file)
@@ -13,9 +13,10 @@ static int add_info_ref(const char *path, const unsigned char *sha1)
 
        fprintf(info_ref_fp, "%s        %s\n", sha1_to_hex(sha1), path);
        if (o->type == tag_type) {
-               o = deref_tag(o);
-               fprintf(info_ref_fp, "%s        %s^{}\n",
-                       sha1_to_hex(o->sha1), path);
+               o = deref_tag(o, path, 0);
+               if (o)
+                       fprintf(info_ref_fp, "%s        %s^{}\n",
+                               sha1_to_hex(o->sha1), path);
        }
        return 0;
 }
index fe409fb..be1755a 100644 (file)
@@ -349,7 +349,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
        if (!o)
                return -1;
        if (!type_string) {
-               o = deref_tag(o);
+               o = deref_tag(o, name, sp - name - 2);
                if (!o || (!o->parsed && !parse_object(o->sha1)))
                        return -1;
                memcpy(sha1, o->sha1, 20);
index 5beaaa3..fde2bb2 100755 (executable)
@@ -67,4 +67,16 @@ test_expect_success \
        >output &&
      diff -u expect output'
 
+# Test \r\n (MSDOS-like systems)
+echo -ne '*.1\r\n/*.3\r\n!*.6\r\n' >.gitignore
+
+test_expect_success \
+    'git-ls-files --others with \r\n line endings.' \
+    'git-ls-files --others \
+       --exclude=\*.6 \
+       --exclude-per-directory=.gitignore \
+       --exclude-from=.git/ignore \
+       >output &&
+     diff -u expect output'
+
 test_done
diff --git a/tag.c b/tag.c
index b1ab75f..e574c4b 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -3,10 +3,15 @@
 
 const char *tag_type = "tag";
 
-struct object *deref_tag(struct object *o)
+struct object *deref_tag(struct object *o, const char *warn, int warnlen)
 {
        while (o && o->type == tag_type)
                o = parse_object(((struct tag *)o)->tagged->sha1);
+       if (!o && warn) {
+               if (!warnlen)
+                       warnlen = strlen(warn);
+               error("missing object referenced by '%.*s'", warnlen, warn);
+       }
        return o;
 }
 
diff --git a/tag.h b/tag.h
index 36e5324..7a0cb00 100644 (file)
--- a/tag.h
+++ b/tag.h
@@ -15,6 +15,6 @@ struct tag {
 extern struct tag *lookup_tag(const unsigned char *sha1);
 extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size);
 extern int parse_tag(struct tag *item);
-extern struct object *deref_tag(struct object *);
+extern struct object *deref_tag(struct object *, const char *, int);
 
 #endif /* TAG_H */
index c5eff21..be63132 100644 (file)
@@ -226,7 +226,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
                nr_our_refs++;
        }
        if (o->type == tag_type) {
-               o = deref_tag(o);
+               o = deref_tag(o, refname, 0);
                packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
        }
        return 0;