Merge branch 'pm/diff'
authorJunio C Hamano <junkio@cox.net>
Thu, 7 Sep 2006 08:33:45 +0000 (01:33 -0700)
committerJunio C Hamano <junkio@cox.net>
Thu, 7 Sep 2006 08:33:45 +0000 (01:33 -0700)
* pm/diff:
diff-index --cc shows a 3-way diff between HEAD, index and working tree.

Documentation/git-rev-list.txt
builtin-rev-list.c
configure.ac
connect.c
git-repack.sh
git.c
revision.c
revision.h
index 3c4c2fbfb9b2b9a0873d35850d503c2de199f556..28966adbbce60c2d3fa02f47bf0797bc29d32f60 100644 (file)
@@ -17,6 +17,7 @@ SYNOPSIS
             [ \--remove-empty ]
             [ \--not ]
             [ \--all ]
+            [ \--stdin ]
             [ \--topo-order ]
             [ \--parents ]
             [ [\--objects | \--objects-edge] [ \--unpacked ] ]
@@ -171,6 +172,11 @@ limiting may be applied.
        Pretend as if all the refs in `$GIT_DIR/refs/` are listed on the
        command line as '<commit>'.
 
+--stdin::
+
+       In addition to the '<commit>' listed on the command
+       line, read them from the standard input.
+
 --merge::
 
        After a failed merge, show refs that touch files having a
index 8437454fbe4e3237aaa6aaecefe54caefb621f1b..8fe8afbd0469c689cad111df6302508d352b6c29 100644 (file)
@@ -23,6 +23,7 @@ static const char rev_list_usage[] =
 "    --no-merges\n"
 "    --remove-empty\n"
 "    --all\n"
+"    --stdin\n"
 "  ordering output:\n"
 "    --topo-order\n"
 "    --date-order\n"
@@ -304,10 +305,28 @@ static void mark_edges_uninteresting(struct commit_list *list)
        }
 }
 
+static void read_revisions_from_stdin(struct rev_info *revs)
+{
+       char line[1000];
+
+       while (fgets(line, sizeof(line), stdin) != NULL) {
+               int len = strlen(line);
+               if (line[len - 1] == '\n')
+                       line[--len] = 0;
+               if (!len)
+                       break;
+               if (line[0] == '-')
+                       die("options not supported in --stdin mode");
+               if (handle_revision_arg(line, revs, 0, 1))
+                       die("bad revision '%s'", line);
+       }
+}
+
 int cmd_rev_list(int argc, const char **argv, const char *prefix)
 {
        struct commit_list *list;
        int i;
+       int read_from_stdin = 0;
 
        init_revisions(&revs, prefix);
        revs.abbrev = 0;
@@ -329,6 +348,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
                        bisect_list = 1;
                        continue;
                }
+               if (!strcmp(arg, "--stdin")) {
+                       if (read_from_stdin++)
+                               die("--stdin given twice?");
+                       read_revisions_from_stdin(&revs);
+                       continue;
+               }
                usage(rev_list_usage);
 
        }
index 64c8345f64a49f5e6ed3a751035e8d0c4f465d19..67c1ae0ed8dfea875408681b62917824ebf08483 100644 (file)
@@ -147,7 +147,7 @@ AC_CHECK_LIB([c], [iconv],
 [NEEDS_LIBICONV=],
 [NEEDS_LIBICONV=YesPlease])
 AC_SUBST(NEEDS_LIBICONV)
-test -n "$NEEDS_SOCKET" && LIBS="$LIBS -liconv"
+test -n "$NEEDS_LIBICONV" && LIBS="$LIBS -liconv"
 #
 # Define NEEDS_SOCKET if linking with libc is not enough (SunOS,
 # Patrick Mauritz).
index 06ef387649e0645b934f3294df8b843aa328393f..1c6429bd51a661f32764f674f28858f6a632ea75 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -17,7 +17,7 @@ static int check_ref(const char *name, int len, unsigned int flags)
        if (!flags)
                return 1;
 
-       if (len > 45 || memcmp(name, "refs/", 5))
+       if (len 5 || memcmp(name, "refs/", 5))
                return 0;
 
        /* Skip the "refs/" part */
index 584a7323acd79e4092910ec4415f51603eccea61..b525fc5dfd9053a6fb63a4d38517e25e75341199 100755 (executable)
@@ -24,8 +24,10 @@ do
        shift
 done
 
-rm -f .tmp-pack-*
 PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
+PACKTMP="$GIT_DIR/.tmp-$$-pack"
+rm -f "$PACKTMP"-*
+trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
 
 # There will be more repacking strategies to come...
 case ",$all_into_one," in
@@ -42,11 +44,12 @@ case ",$all_into_one," in
            find . -type f \( -name '*.pack' -o -name '*.idx' \) -print`
        ;;
 esac
+
 pack_objects="$pack_objects $local $quiet $no_reuse_delta$extra"
 name=$( { git-rev-list --objects --all $rev_list ||
          echo "git-rev-list died with exit code $?"
        } |
-       git-pack-objects --non-empty $pack_objects .tmp-pack) ||
+       git-pack-objects --non-empty $pack_objects "$PACKTMP") ||
        exit 1
 if [ -z "$name" ]; then
        echo Nothing new to pack.
@@ -64,8 +67,8 @@ else
                                "$PACKDIR/old-pack-$name.$sfx"
                fi
        done &&
-       mv -f .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
-       mv -f .tmp-pack-$name.idx  "$PACKDIR/pack-$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."
diff --git a/git.c b/git.c
index 1d00111819f69cb4495be582bebee95be73ab214..335f405c20b3b07af5bb2e96dd00a75eb47ff809 100644 (file)
--- a/git.c
+++ b/git.c
@@ -36,6 +36,8 @@ static void prepend_to_path(const char *dir, int len)
        memcpy(path + len + 1, old_path, path_len - len);
 
        setenv("PATH", path, 1);
+
+       free(path);
 }
 
 static int handle_options(const char*** argv, int* argc)
index b588f7487035027755954575f922afee99651662..db01682750a4dfa820ea3f0e4a99e306aa6b075a 100644 (file)
@@ -592,6 +592,85 @@ static void prepare_show_merge(struct rev_info *revs)
        revs->prune_data = prune;
 }
 
+int handle_revision_arg(const char *arg, struct rev_info *revs,
+                       int flags,
+                       int cant_be_filename)
+{
+       char *dotdot;
+       struct object *object;
+       unsigned char sha1[20];
+       int local_flags;
+
+       dotdot = strstr(arg, "..");
+       if (dotdot) {
+               unsigned char from_sha1[20];
+               const char *next = dotdot + 2;
+               const char *this = arg;
+               int symmetric = *next == '.';
+               unsigned int flags_exclude = flags ^ UNINTERESTING;
+
+               *dotdot = 0;
+               next += symmetric;
+
+               if (!*next)
+                       next = "HEAD";
+               if (dotdot == arg)
+                       this = "HEAD";
+               if (!get_sha1(this, from_sha1) &&
+                   !get_sha1(next, sha1)) {
+                       struct commit *a, *b;
+                       struct commit_list *exclude;
+
+                       a = lookup_commit_reference(from_sha1);
+                       b = lookup_commit_reference(sha1);
+                       if (!a || !b) {
+                               die(symmetric ?
+                                   "Invalid symmetric difference expression %s...%s" :
+                                   "Invalid revision range %s..%s",
+                                   arg, next);
+                       }
+
+                       if (!cant_be_filename) {
+                               *dotdot = '.';
+                               verify_non_filename(revs->prefix, arg);
+                       }
+
+                       if (symmetric) {
+                               exclude = get_merge_bases(a, b, 1);
+                               add_pending_commit_list(revs, exclude,
+                                                       flags_exclude);
+                               free_commit_list(exclude);
+                               a->object.flags |= flags;
+                       } else
+                               a->object.flags |= flags_exclude;
+                       b->object.flags |= flags;
+                       add_pending_object(revs, &a->object, this);
+                       add_pending_object(revs, &b->object, next);
+                       return 0;
+               }
+               *dotdot = '.';
+       }
+       dotdot = strstr(arg, "^@");
+       if (dotdot && !dotdot[2]) {
+               *dotdot = 0;
+               if (add_parents_only(revs, arg, flags))
+                       return 0;
+               *dotdot = '^';
+       }
+       local_flags = 0;
+       if (*arg == '^') {
+               local_flags = UNINTERESTING;
+               arg++;
+       }
+       if (get_sha1(arg, sha1))
+               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);
+       return 0;
+}
+
 /*
  * Parse revision information, filling in the "rev_info" structure,
  * and removing the used arguments from the argument list.
@@ -620,12 +699,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 
        flags = show_merge = 0;
        for (i = 1; i < argc; i++) {
-               struct object *object;
                const char *arg = argv[i];
-               unsigned char sha1[20];
-               char *dotdot;
-               int local_flags;
-
                if (*arg == '-') {
                        int opts;
                        if (!strncmp(arg, "--max-count=", 12)) {
@@ -830,71 +904,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                        left++;
                        continue;
                }
-               dotdot = strstr(arg, "..");
-               if (dotdot) {
-                       unsigned char from_sha1[20];
-                       const char *next = dotdot + 2;
-                       const char *this = arg;
-                       int symmetric = *next == '.';
-                       unsigned int flags_exclude = flags ^ UNINTERESTING;
-
-                       *dotdot = 0;
-                       next += symmetric;
-
-                       if (!*next)
-                               next = "HEAD";
-                       if (dotdot == arg)
-                               this = "HEAD";
-                       if (!get_sha1(this, from_sha1) &&
-                           !get_sha1(next, sha1)) {
-                               struct commit *a, *b;
-                               struct commit_list *exclude;
-
-                               a = lookup_commit_reference(from_sha1);
-                               b = lookup_commit_reference(sha1);
-                               if (!a || !b) {
-                                       die(symmetric ?
-                                           "Invalid symmetric difference expression %s...%s" :
-                                           "Invalid revision range %s..%s",
-                                           arg, next);
-                               }
-
-                               if (!seen_dashdash) {
-                                       *dotdot = '.';
-                                       verify_non_filename(revs->prefix, arg);
-                               }
-
-                               if (symmetric) {
-                                       exclude = get_merge_bases(a, b, 1);
-                                       add_pending_commit_list(revs, exclude,
-                                                               flags_exclude);
-                                       free_commit_list(exclude);
-                                       a->object.flags |= flags;
-                               } else
-                                       a->object.flags |= flags_exclude;
-                               b->object.flags |= flags;
-                               add_pending_object(revs, &a->object, this);
-                               add_pending_object(revs, &b->object, next);
-                               continue;
-                       }
-                       *dotdot = '.';
-               }
-               dotdot = strstr(arg, "^@");
-               if (dotdot && !dotdot[2]) {
-                       *dotdot = 0;
-                       if (add_parents_only(revs, arg, flags))
-                               continue;
-                       *dotdot = '^';
-               }
-               local_flags = 0;
-               if (*arg == '^') {
-                       local_flags = UNINTERESTING;
-                       arg++;
-               }
-               if (get_sha1(arg, sha1)) {
-                       int j;
 
-                       if (seen_dashdash || local_flags)
+               if (handle_revision_arg(arg, revs, flags, seen_dashdash)) {
+                       int j;
+                       if (seen_dashdash || *arg == '^')
                                die("bad revision '%s'", arg);
 
                        /* If we didn't have a "--":
@@ -906,14 +919,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                        for (j = i; j < argc; j++)
                                verify_filename(revs->prefix, argv[j]);
 
-                       revs->prune_data = get_pathspec(revs->prefix, argv + i);
+                       revs->prune_data = get_pathspec(revs->prefix,
+                                                       argv + i);
                        break;
                }
-               if (!seen_dashdash)
-                       verify_non_filename(revs->prefix, arg);
-               object = get_reference(revs, arg, sha1, flags ^ local_flags);
-               add_pending_object(revs, object, arg);
        }
+
        if (show_merge)
                prepare_show_merge(revs);
        if (def && !revs->pending.nr) {
index d289781051c523c7e1596c6e215625616d51f088..c1f71afe6fa71075b64df03c1e9616f50325d29e 100644 (file)
@@ -90,6 +90,8 @@ extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2)
 
 extern void init_revisions(struct rev_info *revs, const char *prefix);
 extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
+extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
+
 extern void prepare_revision_walk(struct rev_info *revs);
 extern struct commit *get_revision(struct rev_info *revs);