diff options
-rw-r--r-- | Documentation/git-rev-list.txt | 6 | ||||
-rw-r--r-- | builtin-rev-list.c | 25 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | connect.c | 2 | ||||
-rwxr-xr-x | git-repack.sh | 11 | ||||
-rw-r--r-- | git.c | 2 | ||||
-rw-r--r-- | revision.c | 159 | ||||
-rw-r--r-- | revision.h | 2 |
8 files changed, 129 insertions, 80 deletions
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 3c4c2fbfb9..28966adbbc 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -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 diff --git a/builtin-rev-list.c b/builtin-rev-list.c index 8437454fbe..8fe8afbd04 100644 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@ -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); } diff --git a/configure.ac b/configure.ac index 64c8345f64..67c1ae0ed8 100644 --- a/configure.ac +++ b/configure.ac @@ -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). @@ -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 */ diff --git a/git-repack.sh b/git-repack.sh index 584a7323ac..b525fc5dfd 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -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." @@ -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) diff --git a/revision.c b/revision.c index b588f74870..db01682750 100644 --- a/revision.c +++ b/revision.c @@ -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) { diff --git a/revision.h b/revision.h index d289781051..c1f71afe6f 100644 --- a/revision.h +++ b/revision.h @@ -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); |