Merge branch 'master' into next
authorJunio C Hamano <junkio@cox.net>
Wed, 10 May 2006 02:32:08 +0000 (19:32 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 10 May 2006 02:32:08 +0000 (19:32 -0700)
* master:
checkout: use --aggressive when running a 3-way merge (-m).
revert/cherry-pick: use aggressive merge.
read-cache.c: use xcalloc() not calloc()
apply: fix infinite loop with multiple patches with --index

1  2 
apply.c
read-cache.c
diff --combined apply.c
index 88d2a3206b0c46e31d2459f616e0d7bc7fb93a0f,7c8146a7f317d9d1743e6a780eec823be72905a6..ea6fb4c8806203a0268261a4aaa4a07dcdefdca2
+++ b/apply.c
@@@ -8,7 -8,6 +8,7 @@@
   */
  #include <fnmatch.h>
  #include "cache.h"
 +#include "cache-tree.h"
  #include "quote.h"
  #include "blob.h"
  #include "delta.h"
@@@ -21,6 -20,7 +21,7 @@@
  //
  static const char *prefix;
  static int prefix_length = -1;
+ static int newfd = -1;
  
  static int p_value = 1;
  static int allow_binary_replacement = 0;
@@@ -1893,7 -1893,6 +1894,7 @@@ static void remove_file(struct patch *p
        if (write_index) {
                if (remove_file_from_cache(patch->old_name) < 0)
                        die("unable to remove %s from index", patch->old_name);
 +              cache_tree_invalidate_path(active_cache_tree, patch->old_name);
        }
        unlink(patch->old_name);
  }
@@@ -1990,9 -1989,8 +1991,9 @@@ static void create_file(struct patch *p
  
        if (!mode)
                mode = S_IFREG | 0644;
 -      create_one_file(path, mode, buf, size); 
 +      create_one_file(path, mode, buf, size);
        add_index_file(path, mode, buf, size);
 +      cache_tree_invalidate_path(active_cache_tree, path);
  }
  
  static void write_out_one_result(struct patch *patch)
@@@ -2051,7 -2049,6 +2052,6 @@@ static int use_patch(struct patch *p
  
  static int apply_patch(int fd, const char *filename)
  {
-       int newfd;
        unsigned long offset, size;
        char *buffer = read_patch_file(fd, &size);
        struct patch *list = NULL, **listp = &list;
                size -= nr;
        }
  
-       newfd = -1;
        if (whitespace_error && (new_whitespace == error_on_whitespace))
                apply = 0;
  
        write_index = check_index && apply;
-       if (write_index)
+       if (write_index && newfd < 0)
                newfd = hold_index_file_for_update(&cache_file, get_index_file());
        if (check_index) {
                if (read_cache() < 0)
        if (apply)
                write_out_results(list, skipped_patch);
  
-       if (write_index) {
-               if (write_cache(newfd, active_cache, active_nr) ||
-                   commit_index_file(&cache_file))
-                       die("Unable to write new cachefile");
-       }
        if (show_index_info)
                show_index_list(list);
  
@@@ -2264,5 -2254,12 +2257,12 @@@ int main(int argc, char **argv
                                whitespace_error == 1 ? "" : "s",
                                whitespace_error == 1 ? "s" : "");
        }
+       if (write_index) {
+               if (write_cache(newfd, active_cache, active_nr) ||
+                   commit_index_file(&cache_file))
+                       die("Unable to write new cachefile");
+       }
        return 0;
  }
diff --combined read-cache.c
index 1f71d125780fbaecf613f8b979fcc04b1b630c97,a917ab0cfe1547d1070f2567a41295c96f97b249..ed0da38e07cdb3d0a05a12bdebf10d833e53bd08
@@@ -4,26 -4,11 +4,26 @@@
   * Copyright (C) Linus Torvalds, 2005
   */
  #include "cache.h"
 +#include "cache-tree.h"
 +
 +/* Index extensions.
 + *
 + * The first letter should be 'A'..'Z' for extensions that are not
 + * necessary for a correct operation (i.e. optimization data).
 + * When new extensions are added that _needs_ to be understood in
 + * order to correctly interpret the index file, pick character that
 + * is outside the range, to cause the reader to abort.
 + */
 +
 +#define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) )
 +#define CACHE_EXT_TREE 0x54524545     /* "TREE" */
  
  struct cache_entry **active_cache = NULL;
  static time_t index_file_timestamp;
  unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0;
  
 +struct cache_tree *active_cache_tree = NULL;
 +
  /*
   * This only updates the "non-critical" parts of the directory
   * cache, ie the parts that aren't tracked by GIT, and only used
@@@ -528,22 -513,6 +528,22 @@@ static int verify_hdr(struct cache_head
        return 0;
  }
  
 +static int read_index_extension(const char *ext, void *data, unsigned long sz)
 +{
 +      switch (CACHE_EXT(ext)) {
 +      case CACHE_EXT_TREE:
 +              active_cache_tree = cache_tree_read(data, sz);
 +              break;
 +      default:
 +              if (*ext < 'A' || 'Z' < *ext)
 +                      return error("index uses %.4s extension, which we do not understand",
 +                                   ext);
 +              fprintf(stderr, "ignoring %.4s extension\n", ext);
 +              break;
 +      }
 +      return 0;
 +}
 +
  int read_cache(void)
  {
        int fd, i;
  
        active_nr = ntohl(hdr->hdr_entries);
        active_alloc = alloc_nr(active_nr);
-       active_cache = calloc(active_alloc, sizeof(struct cache_entry *));
+       active_cache = xcalloc(active_alloc, sizeof(struct cache_entry *));
  
        offset = sizeof(*hdr);
        for (i = 0; i < active_nr; i++) {
                active_cache[i] = ce;
        }
        index_file_timestamp = st.st_mtime;
 +      while (offset <= size - 20 - 8) {
 +              /* After an array of active_nr index entries,
 +               * there can be arbitrary number of extended
 +               * sections, each of which is prefixed with
 +               * extension name (4-byte) and section length
 +               * in 4-byte network byte order.
 +               */
 +              unsigned long extsize;
 +              memcpy(&extsize, map + offset + 4, 4);
 +              extsize = ntohl(extsize);
 +              if (read_index_extension(map + offset,
 +                                       map + offset + 8, extsize) < 0)
 +                      goto unmap;
 +              offset += 8;
 +              offset += extsize;
 +      }
        return active_nr;
  
  unmap:
@@@ -642,17 -595,6 +642,17 @@@ static int ce_write(SHA_CTX *context, i
        return 0;
  }
  
 +static int write_index_ext_header(SHA_CTX *context, int fd,
 +                                unsigned long ext, unsigned long sz)
 +{
 +      ext = htonl(ext);
 +      sz = htonl(sz);
 +      if ((ce_write(context, fd, &ext, 4) < 0) ||
 +          (ce_write(context, fd, &sz, 4) < 0))
 +              return -1;
 +      return 0;
 +}
 +
  static int ce_flush(SHA_CTX *context, int fd)
  {
        unsigned int left = write_buffer_len;
@@@ -749,19 -691,5 +749,19 @@@ int write_cache(int newfd, struct cache
                if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
                        return -1;
        }
 +
 +      /* Write extension data here */
 +      if (active_cache_tree) {
 +              unsigned long sz;
 +              void *data = cache_tree_write(active_cache_tree, &sz);
 +              if (data &&
 +                  !write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sz) &&
 +                  !ce_write(&c, newfd, data, sz))
 +                      ;
 +              else {
 +                      free(data);
 +                      return -1;
 +              }
 +      }
        return ce_flush(&c, newfd);
  }