1. 08 9月, 2016 1 次提交
  2. 19 7月, 2016 2 次提交
    • N
      cache-tree: do not generate empty trees as a result of all i-t-a subentries · 6d6a782f
      Nguyễn Thái Ngọc Duy 提交于
      If a subdirectory contains nothing but i-t-a entries, we generate an
      empty tree object and add it to its parent tree. Which is wrong. Such
      a subdirectory should not be added.
      
      Note that this has a cascading effect. If subdir 'a/b/c' contains
      nothing but i-t-a entries, we ignore it. But then if 'a/b' contains
      only (the non-existing) 'a/b/c', then we should ignore 'a/b' while
      building 'a' too. And it goes all the way up to top directory.
      Noticed-by: NJunio C Hamano <gitster@pobox.com>
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      6d6a782f
    • N
      cache-tree.c: fix i-t-a entry skipping directory updates sometimes · c041d54a
      Nguyễn Thái Ngọc Duy 提交于
      Commit 3cf773e4 (cache-tree: fix writing cache-tree when CE_REMOVE is
      present - 2012-12-16) skips i-t-a entries when building trees objects
      from the index. Unfortunately it may skip too much.
      
      The code in question checks if an entry is an i-t-a one, then no tree
      entry will be written. But it does not take into account that
      directories can also be written with the same code. Suppose we have
      this in the index.
      
          a-file
          subdir/file1
          subdir/file2
          subdir/file3
          the-last-file
      
      We write an entry for a-file as normal and move on to subdir/file1,
      where we realize the entry name for this level is simply just
      "subdir", write down an entry for "subdir" then jump three items ahead
      to the-last-file.
      
      That is what happens normally when the first file in subdir is not an
      i-t-a entry. If subdir/file1 is an i-t-a, because of the broken
      condition in this code, we still think "subdir" is an i-t-a file and
      not writing "subdir" down and jump to the-last-file. The result tree
      now only has two items: a-file and the-last-file. subdir should be
      there too (even though it only records two sub-entries, file2 and
      file3).
      
      If the i-t-a entry is subdir/file2 or subdir/file3, this is not a
      problem because we jump over them anyway. Which may explain why the
      bug is hidden for nearly four years.
      
      Fix it by making sure we only skip i-t-a entries when the entry in
      question is actual an index entry, not a directory.
      Reported-by: NYuri Kanivetsky <yuri.kanivetsky@gmail.com>
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c041d54a
  3. 26 4月, 2016 1 次提交
  4. 23 2月, 2016 1 次提交
  5. 20 11月, 2015 2 次提交
  6. 07 9月, 2015 1 次提交
  7. 05 8月, 2015 1 次提交
  8. 31 10月, 2014 1 次提交
    • J
      cache-tree: avoid infinite loop on zero-entry tree · 729dbbd9
      Jeff King 提交于
      The loop in cache-tree's update_one iterates over all the
      entries in the index. For each one, we find the cache-tree
      subtree which represents our path (creating it if
      necessary), and then recurse into update_one again. The
      return value we get is the number of index entries that
      belonged in that subtree. So for example, with entries:
      
          a/one
          a/two
          b/one
      
      We start by processing the first entry, "a/one".  We would
      find the subtree for "a" and recurse into update_one. That
      would then handle "a/one" and "a/two", and return the value
      2. The parent function then skips past the 2 handled
      entries, and we continue by processing "b/one".
      
      If the recursed-into update_one ever returns 0, then we make
      no forward progress in our loop. We would process "a/one"
      over and over, infinitely.
      
      This should not happen normally. Any subtree we create must
      have at least one path in it (the one that we are
      processing!). However, we may also reuse a cache-tree entry
      we found in the on-disk index. For the same reason, this
      should also never have zero entries. However, certain buggy
      versions of libgit2 could produce such bogus cache-tree
      records. The libgit2 bug has since been fixed, but it does
      not hurt to protect ourselves against bogus input coming
      from the on-disk data structures.
      
      Note that this is not a die("BUG") or assert, because it is
      not an internal bug, but rather a corrupted on-disk
      structure. It's possible that we could even recover from it
      (by throwing out the bogus cache-tree entry), but it is not
      worth the effort; the important thing is that we report an
      error instead of looping infinitely.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      729dbbd9
  9. 02 10月, 2014 1 次提交
  10. 04 9月, 2014 1 次提交
    • J
      cache-tree: do not try to use an invalidated subtree info to build a tree · 4ed115e9
      Junio C Hamano 提交于
      We punt from repairing the cache-tree during a branch switching if
      it involves having to create a new tree object that does not yet
      exist in the object store.  "mkdir dir && >dir/file && git add dir"
      followed by "git checkout" is one example, when a tree that records
      the state of such "dir/" is not in the object store.
      
      However, after discovering that we do not have a tree object that
      records the state of "dir/", the caller failed to remember the fact
      that it noticed the cache-tree entry it received for "dir/" is
      invalidated, it already knows it should not be populating the level
      that has "dir/" as its immediate subdirectory, and it is not an
      error at all for the sublevel cache-tree entry gave it a bogus
      object name it shouldn't even look at.
      
      This led the caller to detect and report a non-existent error.  The
      end result was the same and we avoided stuffing a non-existent tree
      to the cache-tree, but we shouldn't have issued an alarming error
      message to the user.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      4ed115e9
  11. 08 7月, 2014 1 次提交
  12. 14 6月, 2014 4 次提交
  13. 10 3月, 2014 1 次提交
  14. 06 3月, 2014 6 次提交
  15. 04 3月, 2014 1 次提交
  16. 10 7月, 2013 1 次提交
    • N
      Convert "struct cache_entry *" to "const ..." wherever possible · 9c5e6c80
      Nguyễn Thái Ngọc Duy 提交于
      I attempted to make index_state->cache[] a "const struct cache_entry **"
      to find out how existing entries in index are modified and where. The
      question I have is what do we do if we really need to keep track of on-disk
      changes in the index. The result is
      
       - diff-lib.c: setting CE_UPTODATE
      
       - name-hash.c: setting CE_HASHED
      
       - preload-index.c, read-cache.c, unpack-trees.c and
         builtin/update-index: obvious
      
       - entry.c: write_entry() may refresh the checked out entry via
         fill_stat_cache_info(). This causes "non-const struct cache_entry
         *" in builtin/apply.c, builtin/checkout-index.c and
         builtin/checkout.c
      
       - builtin/ls-files.c: --with-tree changes stagemask and may set
         CE_UPDATE
      
      Of these, write_entry() and its call sites are probably most
      interesting because it modifies on-disk info. But this is stat info
      and can be retrieved via refresh, at least for porcelain
      commands. Other just uses ce_flags for local purposes.
      
      So, keeping track of "dirty" entries is just a matter of setting a
      flag in index modification functions exposed by read-cache.c. Except
      unpack-trees, the rest of the code base does not do anything funny
      behind read-cache's back.
      
      The actual patch is less valueable than the summary above. But if
      anyone wants to re-identify the above sites. Applying this patch, then
      this:
      
          diff --git a/cache.h b/cache.h
          index 430d021..1692891 100644
          --- a/cache.h
          +++ b/cache.h
          @@ -267,7 +267,7 @@ static inline unsigned int canon_mode(unsigned int mode)
           #define cache_entry_size(len) (offsetof(struct cache_entry,name) + (len) + 1)
      
           struct index_state {
          -	struct cache_entry **cache;
          +	const struct cache_entry **cache;
           	unsigned int version;
           	unsigned int cache_nr, cache_alloc, cache_changed;
           	struct string_list *resolve_undo;
      
      will help quickly identify them without bogus warnings.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9c5e6c80
  17. 16 12月, 2012 4 次提交
  18. 08 2月, 2012 2 次提交
    • N
    • J
      commit: ignore intent-to-add entries instead of refusing · 3f6d56de
      Junio C Hamano 提交于
      Originally, "git add -N" was introduced to help users from forgetting to
      add new files to the index before they ran "git commit -a".  As an attempt
      to help them further so that they do not forget to say "-a", "git commit"
      to commit the index as-is was taught to error out, reminding the user that
      they may have forgotten to add the final contents of the paths before
      running the command.
      
      This turned out to be a false "safety" that is useless.  If the user made
      changes to already tracked paths and paths added with "git add -N", and
      then ran "git add" to register the final contents of the paths added with
      "git add -N", "git commit" will happily create a commit out of the index,
      without including the local changes made to the already tracked paths. It
      was not a useful "safety" measure to prevent "forgetful" mistakes from
      happening.
      
      It turns out that this behaviour is not just a useless false "safety", but
      actively hurts use cases of "git add -N" that were discovered later and
      have become popular, namely, to tell Git to be aware of these paths added
      by "git add -N", so that commands like "git status" and "git diff" would
      include them in their output, even though the user is not interested in
      including them in the next commit they are going to make.
      
      Fix this ancient UI mistake, and instead make a commit from the index
      ignoring the paths added by "git add -N" without adding real contents.
      
      Based on the work by Nguyễn Thái Ngọc Duy, and helped by injection of
      sanity from Jonathan Nieder and others on the Git mailing list.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      3f6d56de
  19. 07 12月, 2011 1 次提交
  20. 07 9月, 2010 1 次提交
  21. 12 8月, 2010 1 次提交
  22. 15 7月, 2009 1 次提交
  23. 26 5月, 2009 2 次提交
    • J
      Optimize "diff-index --cached" using cache-tree · b65982b6
      Junio C Hamano 提交于
      When running "diff-index --cached" after making a change to only a small
      portion of the index, there is no point unpacking unchanged subtrees into
      the index recursively, only to find that all entries match anyway.  Tweak
      unpack_trees() logic that is used to read in the tree object to catch the
      case where the tree entry we are looking at matches the index as a whole
      by looking at the cache-tree.
      
      As an exercise, after modifying a few paths in the kernel tree, here are
      a few numbers on my Athlon 64X2 3800+:
      
          (without patch, hot cache)
          $ /usr/bin/time git diff --cached --raw
          :100644 100644 b57e1f5... e69de29... M  Makefile
          :100644 000000 8c86b72... 0000000... D  arch/x86/Makefile
          :000000 100644 0000000... e69de29... A  arche
          0.07user 0.02system 0:00.09elapsed 102%CPU (0avgtext+0avgdata 0maxresident)k
          0inputs+0outputs (0major+9407minor)pagefaults 0swaps
      
          (with patch, hot cache)
          $ /usr/bin/time ../git.git/git-diff --cached --raw
          :100644 100644 b57e1f5... e69de29... M  Makefile
          :100644 000000 8c86b72... 0000000... D  arch/x86/Makefile
          :000000 100644 0000000... e69de29... A  arche
          0.02user 0.00system 0:00.02elapsed 103%CPU (0avgtext+0avgdata 0maxresident)k
          0inputs+0outputs (0major+2446minor)pagefaults 0swaps
      
      Cold cache numbers are very impressive, but it does not matter very much
      in practice:
      
          (without patch, cold cache)
          $ su root sh -c 'echo 3 >/proc/sys/vm/drop_caches'
          $ /usr/bin/time git diff --cached --raw
          :100644 100644 b57e1f5... e69de29... M  Makefile
          :100644 000000 8c86b72... 0000000... D  arch/x86/Makefile
          :000000 100644 0000000... e69de29... A  arche
          0.06user 0.17system 0:10.26elapsed 2%CPU (0avgtext+0avgdata 0maxresident)k
          247032inputs+0outputs (1172major+8237minor)pagefaults 0swaps
      
          (with patch, cold cache)
          $ su root sh -c 'echo 3 >/proc/sys/vm/drop_caches'
          $ /usr/bin/time ../git.git/git-diff --cached --raw
          :100644 100644 b57e1f5... e69de29... M  Makefile
          :100644 000000 8c86b72... 0000000... D  arch/x86/Makefile
          :000000 100644 0000000... e69de29... A  arche
          0.02user 0.01system 0:01.01elapsed 3%CPU (0avgtext+0avgdata 0maxresident)k
          18440inputs+0outputs (79major+2369minor)pagefaults 0swaps
      
      This of course helps "git status" as well.
      
          (without patch, hot cache)
          $ /usr/bin/time ../git.git/git-status >/dev/null
          0.17user 0.18system 0:00.35elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k
          0inputs+5336outputs (0major+10970minor)pagefaults 0swaps
      
          (with patch, hot cache)
          $ /usr/bin/time ../git.git/git-status >/dev/null
          0.10user 0.16system 0:00.27elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
          0inputs+5336outputs (0major+3921minor)pagefaults 0swaps
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b65982b6
    • J
      cache-tree.c::cache_tree_find(): simplify internal API · b87fc964
      Junio C Hamano 提交于
      Earlier cache_tree_find() needs to be called with a valid cache_tree,
      but repeated look-up may find an invalid or missing cache_tree in between.
      Help simplify the callers by returning NULL to mean "nothing appropriate
      found" when the input is NULL.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b87fc964
  24. 21 5月, 2009 1 次提交
    • J
      write-tree --ignore-cache-tree · d11b8d34
      Junio C Hamano 提交于
      This allows you to discard the cache-tree information before writing the
      tree out of the index (i.e. it always recomputes the tree object names for
      all the subtrees).
      
      This is only useful as a debug option, so I did not bother documenting it.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      d11b8d34
  25. 20 4月, 2009 1 次提交