Merge branch 'cc/bisect-filter'
authorJunio C Hamano <gitster@pobox.com>
Sun, 12 Apr 2009 23:46:40 +0000 (16:46 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 12 Apr 2009 23:46:40 +0000 (16:46 -0700)
* cc/bisect-filter: (21 commits)
rev-list: add "int bisect_show_flags" in "struct rev_list_info"
rev-list: remove last static vars used in "show_commit"
list-objects: add "void *data" parameter to show functions
bisect--helper: string output variables together with "&&"
rev-list: pass "int flags" as last argument of "show_bisect_vars"
t6030: test bisecting with paths
bisect: use "bisect--helper" and remove "filter_skipped" function
bisect: implement "read_bisect_paths" to read paths in "$GIT_DIR/BISECT_NAMES"
bisect--helper: implement "git bisect--helper"
bisect: use the new generic "sha1_pos" function to lookup sha1
rev-list: call new "filter_skip" function
patch-ids: use the new generic "sha1_pos" function to lookup sha1
sha1-lookup: add new "sha1_pos" function to efficiently lookup sha1
rev-list: pass "revs" to "show_bisect_vars"
rev-list: make "show_bisect_vars" non static
rev-list: move code to show bisect vars into its own function
rev-list: move bisect related code into its own file
rev-list: make "bisect_list" variable local to "cmd_rev_list"
refs: add "for_each_ref_in" function to refactor "for_each_*_ref" functions
quote: add "sq_dequote_to_argv" to put unwrapped args in an argv array
...

1  2 
Makefile
builtin-pack-objects.c
git-bisect.sh
git.c
list-objects.c
refs.c
diff --combined Makefile
index bcf7cbb3fbcfa174dd3d26c95419caeb7dacc4b9,a2bfad43bc9f695f707d2d69472eb7d1af09ca5e..d8cd0111465ba371e990777f38959a9ec2913f27
+++ b/Makefile
@@@ -432,6 -432,7 +432,7 @@@ LIB_OBJS += archive-tar.
  LIB_OBJS += archive-zip.o
  LIB_OBJS += attr.o
  LIB_OBJS += base85.o
+ LIB_OBJS += bisect.o
  LIB_OBJS += blob.o
  LIB_OBJS += branch.o
  LIB_OBJS += bundle.o
@@@ -532,6 -533,7 +533,7 @@@ BUILTIN_OBJS += builtin-add.
  BUILTIN_OBJS += builtin-annotate.o
  BUILTIN_OBJS += builtin-apply.o
  BUILTIN_OBJS += builtin-archive.o
+ BUILTIN_OBJS += builtin-bisect--helper.o
  BUILTIN_OBJS += builtin-blame.o
  BUILTIN_OBJS += builtin-branch.o
  BUILTIN_OBJS += builtin-bundle.o
@@@ -1191,7 -1193,6 +1193,7 @@@ strip: $(PROGRAMS) git$
  
  git.o: git.c common-cmds.h GIT-CFLAGS
        $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \
 +              '-DGIT_HTML_PATH="$(htmldir_SQ)"' \
                $(ALL_CFLAGS) -c $(filter %.c,$^)
  
  git$X: git.o $(BUILTIN_OBJS) $(GITLIBS)
diff --combined builtin-pack-objects.c
index e58d300e3fc9e260fde122168ccdd880b6ad81d4,82536359d6738463a8173f8100355117c825ec58..d3360ac1f8bf13a00f90d9f385d69b628471a95d
@@@ -1612,7 -1612,7 +1612,7 @@@ static void ll_find_deltas(struct objec
                return;
        }
        if (progress > pack_to_stdout)
 -              fprintf(stderr, "Delta compression using %d threads.\n",
 +              fprintf(stderr, "Delta compression using up to %d threads.\n",
                                delta_search_threads);
  
        /* Partition the work amongst work threads. */
@@@ -1901,19 -1901,17 +1901,19 @@@ static void read_object_list_from_stdin
  
  #define OBJECT_ADDED (1u<<20)
  
- static void show_commit(struct commit *commit)
+ static void show_commit(struct commit *commit, void *data)
  {
        add_object_entry(commit->object.sha1, OBJ_COMMIT, NULL, 0);
        commit->object.flags |= OBJECT_ADDED;
  }
  
- static void show_object(struct object_array_entry *p)
+ static void show_object(struct object_array_entry *p, void *data)
  {
        add_preferred_base_object(p->name);
        add_object_entry(p->item->sha1, p->item->type, p->name, 0);
        p->item->flags |= OBJECT_ADDED;
 +      free((char *)p->name);
 +      p->name = NULL;
  }
  
  static void show_edge(struct commit *commit)
@@@ -2073,7 -2071,7 +2073,7 @@@ static void get_object_list(int ac, con
        if (prepare_revision_walk(&revs))
                die("revision walk setup failed");
        mark_edges_uninteresting(revs.commits, &revs, show_edge);
-       traverse_commit_list(&revs, show_commit, show_object);
+       traverse_commit_list(&revs, show_commit, show_object, NULL);
  
        if (keep_unreachable)
                add_objects_in_unpacked_packs(&revs);
diff --combined git-bisect.sh
index df0ae63b4e40f9aa7373269e9a7fb7eeeb66cd18,5074dda45164791a5273dc0b94ea2037922aee87..24712ff304af89317793fa4c54d39f4c579bb345
@@@ -77,7 -77,7 +77,7 @@@ bisect_start() 
        then
                # Reset to the rev from where we started.
                start_head=$(cat "$GIT_DIR/BISECT_START")
 -              git checkout "$start_head" || exit
 +              git checkout "$start_head" -- || exit
        else
                # Get rev from where we start.
                case "$head" in
@@@ -279,87 -279,14 +279,14 @@@ bisect_auto_next() 
        bisect_next_check && bisect_next || :
  }
  
- filter_skipped() {
-       _eval="$1"
-       _skip="$2"
-       if [ -z "$_skip" ]; then
-               eval "$_eval" | {
-                       while read line
-                       do
-                               echo "$line &&"
-                       done
-                       echo ':'
-               }
-               return
-       fi
-       # Let's parse the output of:
-       # "git rev-list --bisect-vars --bisect-all ..."
-       eval "$_eval" | {
-               VARS= FOUND= TRIED=
-               while read hash line
-               do
-                       case "$VARS,$FOUND,$TRIED,$hash" in
-                       1,*,*,*)
-                               # "bisect_foo=bar" read from rev-list output.
-                               echo "$hash &&"
-                               ;;
-                       ,*,*,---*)
-                               # Separator
-                               ;;
-                       ,,,bisect_rev*)
-                               # We had nothing to search.
-                               echo "bisect_rev= &&"
-                               VARS=1
-                               ;;
-                       ,,*,bisect_rev*)
-                               # We did not find a good bisect rev.
-                               # This should happen only if the "bad"
-                               # commit is also a "skip" commit.
-                               echo "bisect_rev='$TRIED' &&"
-                               VARS=1
-                               ;;
-                       ,,*,*)
-                               # We are searching.
-                               TRIED="${TRIED:+$TRIED|}$hash"
-                               case "$_skip" in
-                               *$hash*) ;;
-                               *)
-                                       echo "bisect_rev=$hash &&"
-                                       echo "bisect_tried='$TRIED' &&"
-                                       FOUND=1
-                                       ;;
-                               esac
-                               ;;
-                       ,1,*,bisect_rev*)
-                               # We have already found a rev to be tested.
-                               VARS=1
-                               ;;
-                       ,1,*,*)
-                               ;;
-                       *)
-                               # Unexpected input
-                               echo "die 'filter_skipped error'"
-                               die "filter_skipped error " \
-                                   "VARS: '$VARS' " \
-                                   "FOUND: '$FOUND' " \
-                                   "TRIED: '$TRIED' " \
-                                   "hash: '$hash' " \
-                                   "line: '$line'"
-                               ;;
-                       esac
-               done
-               echo ':'
-       }
- }
  exit_if_skipped_commits () {
        _tried=$1
-       if expr "$_tried" : ".*[|].*" > /dev/null ; then
+       _bad=$2
+       if test -n "$_tried" ; then
                echo "There are only 'skip'ped commit left to test."
                echo "The first bad commit could be any of:"
                echo "$_tried" | tr '[|]' '[\012]'
+               test -n "$_bad" && echo "$_bad"
                echo "We cannot bisect more!"
                exit 2
        fi
@@@ -370,7 -297,7 +297,7 @@@ bisect_checkout() 
        _msg="$2"
        echo "Bisecting: $_msg"
        mark_expected_rev "$_rev"
 -      git checkout -q "$_rev" || exit
 +      git checkout -q "$_rev" -- || exit
        git show-branch "$_rev"
  }
  
@@@ -490,28 -417,23 +417,23 @@@ bisect_next() 
        test "$?" -eq "1" && return
  
        # Get bisection information
-       BISECT_OPT=''
-       test -n "$skip" && BISECT_OPT='--bisect-all'
-       eval="git rev-list --bisect-vars $BISECT_OPT $good $bad --" &&
-       eval="$eval $(cat "$GIT_DIR/BISECT_NAMES")" &&
-       eval=$(filter_skipped "$eval" "$skip") &&
+       eval=$(eval "git bisect--helper --next-vars") &&
        eval "$eval" || exit
  
        if [ -z "$bisect_rev" ]; then
+               # We should exit here only if the "bad"
+               # commit is also a "skip" commit (see above).
+               exit_if_skipped_commits "$bisect_tried"
                echo "$bad was both good and bad"
                exit 1
        fi
        if [ "$bisect_rev" = "$bad" ]; then
-               exit_if_skipped_commits "$bisect_tried"
+               exit_if_skipped_commits "$bisect_tried" "$bad"
                echo "$bisect_rev is first bad commit"
                git diff-tree --pretty $bisect_rev
                exit 0
        fi
  
-       # We should exit here only if the "bad"
-       # commit is also a "skip" commit (see above).
-       exit_if_skipped_commits "$bisect_rev"
        bisect_checkout "$bisect_rev" "$bisect_nr revisions left to test after this (roughly $bisect_steps steps)"
  }
  
@@@ -549,7 -471,7 +471,7 @@@ bisect_reset() 
        *)
            usage ;;
        esac
 -      git checkout "$branch" && bisect_clean_state
 +      git checkout "$branch" -- && bisect_clean_state
  }
  
  bisect_clean_state() {
diff --combined git.c
index ff72e22bec3116b311a42e36dba6172b3390bfa2,a553926b68f06bc9b1bd3169f6719b79ec0fd624..bfb6508ad0f0a49b6e7006619920fd00e768d7f3
--- 1/git.c
--- 2/git.c
+++ b/git.c
@@@ -5,7 -5,7 +5,7 @@@
  #include "run-command.h"
  
  const char git_usage_string[] =
 -      "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
 +      "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]";
  
  const char git_more_info_string[] =
        "See 'git help COMMAND' for more information on a specific command.";
@@@ -75,9 -75,6 +75,9 @@@ static int handle_options(const char**
                                puts(git_exec_path());
                                exit(0);
                        }
 +              } else if (!strcmp(cmd, "--html-path")) {
 +                      puts(system_path(GIT_HTML_PATH));
 +                      exit(0);
                } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
                        use_pager = 1;
                } else if (!strcmp(cmd, "--no-pager")) {
@@@ -274,6 -271,7 +274,7 @@@ static void handle_internal_command(in
                { "annotate", cmd_annotate, RUN_SETUP },
                { "apply", cmd_apply },
                { "archive", cmd_archive },
+               { "bisect--helper", cmd_bisect__helper, RUN_SETUP | NEED_WORK_TREE },
                { "blame", cmd_blame, RUN_SETUP },
                { "branch", cmd_branch, RUN_SETUP },
                { "bundle", cmd_bundle },
diff --combined list-objects.c
index dd243c7c662c2f3fe9463b616bb00bed2cc503a7,208a4cb0027eeb3ded2d16905ad2029df70cd84a..433394a107fe682b6adfcb122ef182321c4f5947
@@@ -23,6 -23,7 +23,6 @@@ static void process_blob(struct rev_inf
        if (obj->flags & (UNINTERESTING | SEEN))
                return;
        obj->flags |= SEEN;
 -      name = xstrdup(name);
        add_object(obj, p, path, name);
  }
  
@@@ -77,6 -78,7 +77,6 @@@ static void process_tree(struct rev_inf
        if (parse_tree(tree) < 0)
                die("bad tree object %s", sha1_to_hex(obj->sha1));
        obj->flags |= SEEN;
 -      name = xstrdup(name);
        add_object(obj, p, path, name);
        me.up = path;
        me.elem = name;
@@@ -135,8 -137,9 +135,9 @@@ void mark_edges_uninteresting(struct co
  }
  
  void traverse_commit_list(struct rev_info *revs,
-                         void (*show_commit)(struct commit *),
-                         void (*show_object)(struct object_array_entry *))
+                         show_commit_fn show_commit,
+                         show_object_fn show_object,
+                         void *data)
  {
        int i;
        struct commit *commit;
  
        while ((commit = get_revision(revs)) != NULL) {
                process_tree(revs, commit->tree, &objects, NULL, "");
-               show_commit(commit);
+               show_commit(commit, data);
        }
        for (i = 0; i < revs->pending.nr; i++) {
                struct object_array_entry *pending = revs->pending.objects + i;
                    sha1_to_hex(obj->sha1), name);
        }
        for (i = 0; i < objects.nr; i++)
-               show_object(&objects.objects[i]);
+               show_object(&objects.objects[i], data);
        free(objects.objects);
        if (revs->pending.nr) {
                free(revs->pending.objects);
diff --combined refs.c
index 59c373fc6d315aacfc3b1a0cecce0ceb4b65d72f,e5468967eb81f5d102395e031c57cbb621280012..9ccaf40172ee17472b4e33e9bd7f6dbac991d4bf
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -647,19 -647,24 +647,24 @@@ int for_each_ref(each_ref_fn fn, void *
        return do_for_each_ref("refs/", fn, 0, 0, cb_data);
  }
  
+ int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
+ {
+       return do_for_each_ref(prefix, fn, strlen(prefix), 0, cb_data);
+ }
  int for_each_tag_ref(each_ref_fn fn, void *cb_data)
  {
-       return do_for_each_ref("refs/tags/", fn, 10, 0, cb_data);
+       return for_each_ref_in("refs/tags/", fn, cb_data);
  }
  
  int for_each_branch_ref(each_ref_fn fn, void *cb_data)
  {
-       return do_for_each_ref("refs/heads/", fn, 11, 0, cb_data);
+       return for_each_ref_in("refs/heads/", fn, cb_data);
  }
  
  int for_each_remote_ref(each_ref_fn fn, void *cb_data)
  {
-       return do_for_each_ref("refs/remotes/", fn, 13, 0, cb_data);
+       return for_each_ref_in("refs/remotes/", fn, cb_data);
  }
  
  int for_each_rawref(each_ref_fn fn, void *cb_data)
   * - it has double dots "..", or
   * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
   * - it ends with a "/".
 + * - it ends with ".lock"
   */
  
  static inline int bad_ref_char(int ch)
  
  int check_ref_format(const char *ref)
  {
 -      int ch, level, bad_type;
 +      int ch, level, bad_type, last;
        int ret = CHECK_REF_FORMAT_OK;
        const char *cp = ref;
  
                                return CHECK_REF_FORMAT_ERROR;
                }
  
 +              last = ch;
                /* scan the rest of the path component */
                while ((ch = *cp++) != 0) {
                        bad_type = bad_ref_char(ch);
 -                      if (bad_type) {
 +                      if (bad_type)
                                return CHECK_REF_FORMAT_ERROR;
 -                      }
                        if (ch == '/')
                                break;
 -                      if (ch == '.' && *cp == '.')
 +                      if (last == '.' && ch == '.')
 +                              return CHECK_REF_FORMAT_ERROR;
 +                      if (last == '@' && ch == '{')
                                return CHECK_REF_FORMAT_ERROR;
 +                      last = ch;
                }
                level++;
                if (!ch) {
 +                      if (ref <= cp - 2 && cp[-2] == '.')
 +                              return CHECK_REF_FORMAT_ERROR;
                        if (level < 2)
                                return CHECK_REF_FORMAT_ONELEVEL;
 +                      if (has_extension(ref, ".lock"))
 +                              return CHECK_REF_FORMAT_ERROR;
                        return ret;
                }
        }