1. 11 Jun, 2017 1 commit
  2. 10 Jun, 2017 3 commits
    • git_futils_rmdir: only allow `EBUSY` when asked · 4a0df574
      Only ignore `EBUSY` from `rmdir` when the `GIT_RMDIR_SKIP_NONEMPTY` bit
      is set.
      Edward Thomson committed
    • checkout: cope with untracked files in directory deletion · 83989d70
      When deleting a directory during checkout, do not simply delete the
      directory, since there may be untracked files.  Instead, go into
      the iterator and examine each file.
      
      In the original code (the code with the faulty assumption), we look to
      see if there's an index entry beneath the directory that we want to
      remove.   Eg, it looks to see if we have a workdir entry foo and an
      index entry foo/bar.txt. If this is not the case, then the working
      directory must have precious files in that directory. This part is okay.
      The part that's not okay is if there is an index entry foo/bar.txt. It
      just blows away the whole damned directory.
      
      That's not cool.
      
      Instead, by simply pushing the directory itself onto the stack and
      iterating each entry, we will deal with the files one by one - whether
      they're in the index (and can be force removed) or not (and are
      precious).
      
      The original code was a bad optimization, assuming that we didn't need
      to git_iterator_advance_into if there was any index entry in the folder.
      That's wrong - we could have optimized this iff all folder entries are
      in the index.
      
      Instead, we need to simply dig into the directory and analyze its
      entries.
      Edward Thomson committed
    • checkout: do not delete directories with untracked entries · 0ef405b3
      If the `GIT_CHECKOUT_FORCE` flag is given to any of the `git_checkout`
      invocations, we remove files which were previously staged. But while
      doing so, we unfortunately also remove unstaged files in a directory
      which contains at least one staged file, resulting in potential data
      loss.
      
      This commit adds two tests to verify behavior.
      Patrick Steinhardt committed
  3. 08 Jun, 2017 15 commits
  4. 07 Jun, 2017 7 commits
  5. 06 Jun, 2017 14 commits
    • tests: index::version: improve write test for index v4 · 92d3ea4e
      The current write test does not trigger some edge-cases in the index
      version 4 path compression code. Rewrite the test to start off the an
      empty standard repository, creating index entries with interesting paths
      itself. This allows for more fine-grained control over checked paths.
      Furthermore, we now also verify that entry paths are actually
      reconstructed correctly.
      Patrick Steinhardt committed
    • tests: index::version: verify we write compressed index entries · 8fe33538
      While we do have a test which checks whether a written index of version
      4 has the correct version set, we do not check whether this actually
      enables path compression for index entries. This commit adds a new test
      by adding a number of index entries with equal path prefixes to the
      index and subsequently flushing that to disk. With suffix compression
      enabled by index version 4, only the last few bytes of these paths will
      actually have to be written to the index, saving a lot of disk space.
      For the test, differences are about an order of magnitude, allowing us
      to easily verify without taking a deeper look at actual on-disk
      contents.
      Patrick Steinhardt committed
    • tests: index::version: add test to read index version v4 · 82368b1b
      While we have a simple test to determine whether we can write an index
      of version 4, we never verified that we are able to read this kind of
      index (and in fact, we were not able to do so). Add a new repository
      which has an index of version 4. This repository is then read from a new
      test.
      Patrick Steinhardt committed
    • tests: index::version: move up cleanup function · fea0c81e
      The init and cleanup functions for test suites are usually prepended to
      our actual tests. The index::version test suite does not adhere to this
      stile. Fix this.
      Patrick Steinhardt committed
    • index: verify we have enough space left when writing index entries · 064a60e9
      In our code writing index entries, we carry around a `disk_size`
      representing how much memory we have in total and pass this value to
      `git_encode_varint` to do bounds checks. This does not make much sense,
      as at the time when passing on this variable it is already out of date.
      Fix this by subtracting used memory from `disk_size` as we go along.
      Furthermore, assert we've actually got enough space left to do the final
      path memcpy.
      Patrick Steinhardt committed
    • index: fix shared prefix computation when writing index entry · c71dff7e
      When using compressed index entries, each entry's path is preceded by a
      varint encoding how long the shared prefix with the previous index entry
      actually is. We currently encode a length of `(path_len - same_len)`,
      which is doubly wrong. First, `path_len` is already set to `path_len -
      same_len` previously. Second, we want to encode the shared prefix rather
      than the un-shared suffix length.
      
      Fix this by using `same_len` as the varint value instead.
      Patrick Steinhardt committed
    • index: also sanity check entry size with compressed entries · 83e0392c
      We have a check in place whether the index has enough data left for the
      required footer after reading an index entry, but this was only used for
      uncompressed entries. Move the check down a bit so that it is executed
      for both compressed and uncompressed index entries.
      Patrick Steinhardt committed
    • index: remove file-scope entry size macros · 350d2c47
      All index entry size computations are now performed in
      `index_entry_size`. As such, we do not need the file-scope macros for
      computing these sizes anymore. Remove them and move the `entry_size`
      macro into the `index_entry_size` function.
      Patrick Steinhardt committed
    • index: don't right-pad paths when writing compressed entries · 46b67034
      Our code to write index entries to disk does not check whether the
      entry that is to be written should use prefix compression for the path.
      As such, we were overallocating memory and added bogus right-padding
      into the resulting index entries. As there is no padding allowed in the
      index version 4 format, this should actually result in an invalid index.
      
      Fix this by re-using the newly extracted `index_entry_size` function.
      Patrick Steinhardt committed
    • index: move index entry size computation into its own function · 29f498e0
      Create a new function `index_entry_size` which encapsulates the logic to
      calculate how much space is needed for an index entry, whether it is
      simple/extended or compressed/uncompressed. This can later be re-used by
      our code writing index entries.
      Patrick Steinhardt committed
    • index: set last written index entry in foreach-entry-loop · 8ceb890b
      The last written disk entry is currently being written inside of the
      function `write_disk_entry`. Make behavior a bit more obviously by
      instead setting it inside of `write_entries` while iterating all
      entries.
      Patrick Steinhardt committed
    • index: set last entry when reading compressed entries · 11d0be23
      To calculate the path of a compressed index entry, we need to know the
      preceding entry's path. While we do actually set the first predecessor
      correctly to "", we fail to update this while reading the entries.
      
      Fix the issue by updating `last` inside of the loop. Previously, we've
      been passing a double-pointer to `read_entry`, which it didn't update.
      As it is more obvious to update the pointer inside the loop itself,
      though, we can simply convert it to a normal pointer.
      Patrick Steinhardt committed
    • index: fix confusion with shared prefix in compressed path names · febe8c14
      The index version 4 introduced compressed path names for the entries.
      From the git.git index-format documentation:
      
          At the beginning of an entry, an integer N in the variable width
          encoding [...] is stored, followed by a NUL-terminated string S.
          Removing N bytes from the end of the path name for the previous
          entry, and replacing it with the string S yields the path name for
          this entry.
      
      But instead of stripping N bytes from the previous path's string and
      using the remaining prefix, we were instead simply concatenating the
      previous path with the current entry path, which is obviously wrong.
      
      Fix the issue by correctly copying the first N bytes of the previous
      entry only and concatenating the result with our current entry's path.
      Patrick Steinhardt committed
    • varint: fix computation for remaining buffer space · 8a5e7aae
      When encoding varints to a buffer, we want to remain sure that the
      required buffer space does not exceed what is actually available. Our
      current check does not do the right thing, though, in that it does not
      honor that our `pos` variable counts the position down instead of up. As
      such, we will require too much memory for small varints and not enough
      memory for big varints.
      
      Fix the issue by correctly calculating the required size as
      `(sizeof(varint) - pos)`. Add a test which failed before.
      Patrick Steinhardt committed