Merge branch 'jc/cache-tree' into jc/dirwalk-n-cache-tree
authorJunio C Hamano <junkio@cox.net>
Sat, 20 May 2006 07:56:11 +0000 (00:56 -0700)
committerJunio C Hamano <junkio@cox.net>
Sat, 20 May 2006 07:56:11 +0000 (00:56 -0700)
* jc/cache-tree: (24 commits)
  Fix crash when reading the empty tree
  fsck-objects: do not segfault on missing tree in cache-tree
  cache-tree: a bit more debugging support.
  read-tree: invalidate cache-tree entry when a new index entry is added.
  Fix test-dump-cache-tree in one-tree disappeared case.
  fsck-objects: mark objects reachable from cache-tree
  cache-tree: replace a sscanf() by two strtol() calls
  cache-tree.c: typefix
  test-dump-cache-tree: validate the cached data as well.
  cache_tree_update: give an option to update cache-tree only.
  read-tree: teach 1-way merege and plain read to prime cache-tree.
  read-tree: teach 1 and 2 way merges about cache-tree.
  update-index: when --unresolve, smudge the relevant cache-tree entries.
  test-dump-cache-tree: report number of subtrees.
  cache-tree: sort the subtree entries.
  Teach fsck-objects about cache-tree.
  index: make the index file format extensible.
  cache-tree: protect against "git prune".
  Add test-dump-cache-tree
  Use cache-tree in update-index.
  ...

1  2 
Makefile
apply.c
cache.h
checkout-index.c
read-cache.c
read-tree.c
update-index.c

diff --cc Makefile
+++ b/Makefile
@@@ -208,7 -204,7 +208,7 @@@ DIFF_OBJS = 
        diffcore-delta.o log-tree.o
  
  LIB_OBJS = \
-       blob.o commit.o connect.o csum-file.o base85.o \
 -      blob.o commit.o connect.o csum-file.o cache-tree.o \
++      blob.o commit.o connect.o csum-file.o cache-tree.o base85.o \
        date.o diff-delta.o entry.o exec_cmd.o ident.o index.o \
        object.o pack-check.o patch-delta.o path.o pkt-line.o \
        quote.o read-cache.o refs.o run-command.o \
@@@ -607,8 -609,11 +607,11 @@@ test-date$X: test-date.c date.o ctype.
        $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) test-date.c date.o ctype.o
  
  test-delta$X: test-delta.c diff-delta.o patch-delta.o
 -      $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^ -lz
 +      $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^
  
+ test-dump-cache-tree$X: dump-cache-tree.o $(GITLIBS)
+       $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
  check:
        for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done
  
diff --cc apply.c
+++ b/apply.c
@@@ -8,9 -8,9 +8,10 @@@
   */
  #include <fnmatch.h>
  #include "cache.h"
+ #include "cache-tree.h"
  #include "quote.h"
  #include "blob.h"
 +#include "delta.h"
  
  //  --check turns on checking that the working tree matches the
  //    files that are being modified, but doesn't apply the patch
@@@ -1917,9 -1718,9 +1918,10 @@@ 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);
 +      if (!cached)
 +              unlink(patch->old_name);
  }
  
  static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)
diff --cc cache.h
Simple merge
Simple merge
diff --cc read-cache.c
Simple merge
diff --cc read-tree.c
@@@ -426,21 -422,12 +427,27 @@@ static void verify_uptodate(struct cach
        die("Entry '%s' not uptodate. Cannot merge.", ce->name);
  }
  
+ static void invalidate_ce_path(struct cache_entry *ce)
+ {
+       if (ce)
+               cache_tree_invalidate_path(active_cache_tree, ce->name);
+ }
 +/*
 + * We do not want to remove or overwrite a working tree file that
 + * is not tracked.
 + */
 +static void verify_absent(const char *path, const char *action)
 +{
 +      struct stat st;
 +
 +      if (index_only || reset || !update)
 +              return;
 +      if (!lstat(path, &st))
 +              die("Untracked working tree file '%s' "
 +                  "would be %s by merge.", path, action);
 +}
 +
  static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
  {
        merge->ce_flags |= htons(CE_UPDATE);
                        *merge = *old;
                } else {
                        verify_uptodate(old);
+                       invalidate_ce_path(old);
                }
        }
--      else
++      else {
 +              verify_absent(merge->name, "overwritten");
+               invalidate_ce_path(merge);
++      }
 +
        merge->ce_flags &= ~htons(CE_STAGEMASK);
        add_cache_entry(merge, ADD_CACHE_OK_TO_ADD);
        return 1;
@@@ -470,10 -457,9 +480,11 @@@ static int deleted_entry(struct cache_e
  {
        if (old)
                verify_uptodate(old);
 +      else
 +              verify_absent(ce->name, "removed");
        ce->ce_mode = 0;
        add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
+       invalidate_ce_path(ce);
        return 1;
  }
  
@@@ -759,6 -727,39 +771,39 @@@ static int read_cache_unmerged(void
        return deleted;
  }
  
 -      
+ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
+ {
+       struct tree_entry_list *ent;
+       int cnt;
++
+       memcpy(it->sha1, tree->object.sha1, 20);
+       for (cnt = 0, ent = tree->entries; ent; ent = ent->next) {
+               if (!ent->directory)
+                       cnt++;
+               else {
+                       struct cache_tree_sub *sub;
+                       struct tree *subtree = (struct tree *)ent->item.tree;
+                       if (!subtree->object.parsed)
+                               parse_tree(subtree);
+                       sub = cache_tree_sub(it, ent->name);
+                       sub->cache_tree = cache_tree();
+                       prime_cache_tree_rec(sub->cache_tree, subtree);
+                       cnt += sub->cache_tree->entry_count;
+               }
+       }
+       it->entry_count = cnt;
+ }
+ static void prime_cache_tree(void)
+ {
+       struct tree *tree = (struct tree *)trees->item;
+       if (!tree)
+               return;
+       active_cache_tree = cache_tree();
+       prime_cache_tree_rec(active_cache_tree, tree);
+ }
  static const char read_tree_usage[] = "git-read-tree (<sha> | -m [--aggressive] [-u | -i] <sha1> [<sha2> [<sha3>]])";
  
  static struct cache_file cache_file;
diff --cc update-index.c
@@@ -252,8 -379,9 +262,9 @@@ static void update_one(const char *path
        if (mark_valid_only) {
                if (mark_valid(p))
                        die("Unable to mark file %s", path);
 -              return;
 +              goto free_return;
        }
+       cache_tree_invalidate_path(active_cache_tree, path);
  
        if (force_remove) {
                if (remove_file_from_cache(p))