Merge branch 'vb/sendemail' into next
authorJunio C Hamano <junkio@cox.net>
Sun, 4 Jun 2006 07:01:52 +0000 (00:01 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 4 Jun 2006 07:01:52 +0000 (00:01 -0700)
* vb/sendemail:
  Cleanup git-send-email.perl:extract_valid_email
  read-tree --reset: update working tree file for conflicted paths.
  Documentation: Spelling fixes
  Builtin git-rev-parse.
  fetch: do not report "same" unless -verbose.

1  2 
Documentation/git-read-tree.txt
builtin-read-tree.c

@@@ -8,7 -8,7 +8,7 @@@ git-read-tree - Reads tree information 
  
  SYNOPSIS
  --------
 -'git-read-tree' (<tree-ish> | [[-m [--aggressive]| --reset] [-u | -i]] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
 +'git-read-tree' (<tree-ish> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
  
  
  DESCRIPTION
@@@ -63,15 -63,6 +63,15 @@@ OPTION
  * when both sides adds a path identically.  The resolution
    is to add that path.
  
 +--prefix=<prefix>/::
 +      Keep the current index contents, and read the contents
 +      of named tree-ish under directory at `<prefix>`.  The
 +      original index file cannot have anything at the path
 +      `<prefix>` itself, and have nothing in `<prefix>/`
 +      directory.  Note that the `<prefix>/` value must end
 +      with a slash.
 +
 +
  <tree-ish#>::
        The id of the tree object(s) to be read/merged.
  
@@@ -214,7 -205,7 +214,7 @@@ The `git-write-tree` command refuses t
  will complain about unmerged entries if it sees a single entry that is not
  stage 0.
  
- Ok, this all sounds like a collection of totally nonsensical rules,
+ OK, this all sounds like a collection of totally nonsensical rules,
  but it's actually exactly what you want in order to do a fast
  merge. The different stages represent the "result tree" (stage 0, aka
  "merged"), the original tree (stage 1, aka "orig"), and the two trees
@@@ -235,7 -226,7 +235,7 @@@ populated.  Here is an outline of how t
  
  - the index file saves and restores with all this information, so you
    can merge things incrementally, but as long as it has entries in
-   stages 1/2/3 (ie "unmerged entries") you can't write the result. So
+   stages 1/2/3 (i.e., "unmerged entries") you can't write the result. So
    now the merge algorithm ends up being really simple:
  
    * you walk the index in order, and ignore all entries of stage 0,
diff --combined builtin-read-tree.c
@@@ -24,7 -24,6 +24,7 @@@ static int trivial_merges_only = 0
  static int aggressive = 0;
  static int verbose_update = 0;
  static volatile int progress_update = 0;
 +static const char *prefix = NULL;
  
  static int head_idx = -1;
  static int merge_size = 0;
@@@ -412,8 -411,7 +412,8 @@@ static int unpack_trees(merge_fn_t fn
                        posns[i] = create_tree_entry_list((struct tree *) posn->item);
                        posn = posn->next;
                }
 -              if (unpack_trees_rec(posns, len, "", fn, &indpos))
 +              if (unpack_trees_rec(posns, len, prefix ? prefix : "",
 +                                   fn, &indpos))
                        return -1;
        }
  
@@@ -763,28 -761,6 +763,28 @@@ static int twoway_merge(struct cache_en
  }
  
  /*
 + * Bind merge.
 + *
 + * Keep the index entries at stage0, collapse stage1 but make sure
 + * stage0 does not have anything there.
 + */
 +static int bind_merge(struct cache_entry **src)
 +{
 +      struct cache_entry *old = src[0];
 +      struct cache_entry *a = src[1];
 +
 +      if (merge_size != 1)
 +              return error("Cannot do a bind merge of %d trees\n",
 +                           merge_size);
 +      if (a && old)
 +              die("Entry '%s' overlaps.  Cannot bind.", a->name);
 +      if (!a)
 +              return keep_entry(old);
 +      else
 +              return merged_entry(a, NULL);
 +}
 +
 +/*
   * One-way merge.
   *
   * The rule is:
@@@ -799,10 -775,8 +799,10 @@@ static int oneway_merge(struct cache_en
                return error("Cannot do a oneway merge of %d trees",
                             merge_size);
  
 -      if (!a)
 +      if (!a) {
 +              invalidate_ce_path(old);
                return deleted_entry(old, old);
 +      }
        if (old && same(old, a)) {
                if (reset) {
                        struct stat st;
  
  static int read_cache_unmerged(void)
  {
-       int i, deleted;
+       int i;
        struct cache_entry **dst;
+       struct cache_entry *last = NULL;
  
        read_cache();
        dst = active_cache;
-       deleted = 0;
        for (i = 0; i < active_nr; i++) {
                struct cache_entry *ce = active_cache[i];
                if (ce_stage(ce)) {
-                       deleted++;
+                       if (last && !strcmp(ce->name, last->name))
+                               continue;
                        invalidate_ce_path(ce);
-                       continue;
+                       last = ce;
+                       ce->ce_mode = 0;
+                       ce->ce_flags &= ~htons(CE_STAGEMASK);
                }
-               if (deleted)
-                       *dst = ce;
-               dst++;
+               *dst++ = ce;
        }
-       active_nr -= deleted;
-       return deleted;
+       active_nr = dst - active_cache;
+       return !!last;
  }
  
  static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
@@@ -875,7 -850,7 +876,7 @@@ static void prime_cache_tree(void
  
  }
  
 -static const char read_tree_usage[] = "git-read-tree (<sha> | -m [--aggressive] [-u | -i] <sha1> [<sha2> [<sha3>]])";
 +static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] <sha1> [<sha2> [<sha3>]])";
  
  static struct cache_file cache_file;
  
@@@ -920,24 -895,12 +921,27 @@@ int cmd_read_tree(int argc, const char 
                        continue;
                }
  
-               /* This differs from "-m" in that we'll silently ignore unmerged entries */
 +              /* "--prefix=<subdirectory>/" means keep the current index
 +               *  entries and put the entries from the tree under the
 +               * given subdirectory.
 +               */
 +              if (!strncmp(arg, "--prefix=", 9)) {
 +                      if (stage || merge || prefix)
 +                              usage(read_tree_usage);
 +                      prefix = arg + 9;
 +                      merge = 1;
 +                      stage = 1;
 +                      if (read_cache_unmerged())
 +                              die("you need to resolve your current index first");
 +                      continue;
 +              }
 +
+               /* This differs from "-m" in that we'll silently ignore
+                * unmerged entries and overwrite working tree files that
+                * correspond to them.
+                */
                if (!strcmp(arg, "--reset")) {
 -                      if (stage || merge)
 +                      if (stage || merge || prefix)
                                usage(read_tree_usage);
                        reset = 1;
                        merge = 1;
  
                /* "-m" stands for "merge", meaning we start in stage 1 */
                if (!strcmp(arg, "-m")) {
 -                      if (stage || merge)
 +                      if (stage || merge || prefix)
                                usage(read_tree_usage);
                        if (read_cache_unmerged())
                                die("you need to resolve your current index first");
        if ((update||index_only) && !merge)
                usage(read_tree_usage);
  
 +      if (prefix) {
 +              int pfxlen = strlen(prefix);
 +              int pos;
 +              if (prefix[pfxlen-1] != '/')
 +                      die("prefix must end with /");
 +              if (stage != 2)
 +                      die("binding merge takes only one tree");
 +              pos = cache_name_pos(prefix, pfxlen);
 +              if (0 <= pos)
 +                      die("corrupt index file");
 +              pos = -pos-1;
 +              if (pos < active_nr &&
 +                  !strncmp(active_cache[pos]->name, prefix, pfxlen))
 +                      die("subdirectory '%s' already exists.", prefix);
 +              pos = cache_name_pos(prefix, pfxlen-1);
 +              if (0 <= pos)
 +                      die("file '%.*s' already exists.", pfxlen-1, prefix);
 +      }
 +
        if (merge) {
                if (stage < 2)
                        die("just how do you expect me to merge %d trees?", stage-1);
                switch (stage - 1) {
                case 1:
 -                      fn = oneway_merge;
 +                      fn = prefix ? bind_merge : oneway_merge;
                        break;
                case 2:
                        fn = twoway_merge;