1. 29 Sep, 2016 3 commits
    • xdl_change_compact(): introduce the concept of a change group · a49895b5
      The idea of xdl_change_compact() is fairly simple:
      
      * Proceed through groups of changed lines in the file to be compacted,
        keeping track of the corresponding location in the "other" file.
      
      * If possible, slide the group up and down to try to give the most
        aesthetically pleasing diff. Whenever it is slid, the current location
        in the other file needs to be adjusted.
      
      But these simple concepts are obfuscated by a lot of index handling that
      is written in terse, subtle, and varied patterns. I found it very hard
      to convince myself that the function was correct.
      
      So introduce a "struct group" that represents a group of changed lines
      in a file. Add some functions that perform elementary operations on
      groups:
      
      * Initialize a group to the first group in a file
      * Move to the next or previous group in a file
      * Slide a group up or down
      
      Even though the resulting code is longer, I think it is easier to
      understand and review. Its performance is not changed
      appreciably (though it would be if `group_next()` and `group_previous()`
      were not inlined).
      
      ...and in fact, the rewriting helped me discover another bug in the
      --compaction-heuristic code: The update of blank_lines was never done
      for the highest possible position of the group. This means that it could
      fail to slide the group to its highest possible position, even if that
      position had a blank line as its last line. So for example, it yielded
      the following diff:
      
          $ git diff --no-index --compaction-heuristic a.txt b.txt
          diff --git a/a.txt b/b.txt
          index e53969f..0d60c5fe 100644
          --- a/a.txt
          +++ b/b.txt
          @@ -1,3 +1,7 @@
           1
           A
          +
          +B
          +
          +A
           2
      
      when in fact the following diff is better (according to the rules of
      --compaction-heuristic):
      
          $ git diff --no-index --compaction-heuristic a.txt b.txt
          diff --git a/a.txt b/b.txt
          index e53969f..0d60c5fe 100644
          --- a/a.txt
          +++ b/b.txt
          @@ -1,3 +1,7 @@
           1
          +A
          +
          +B
          +
           A
           2
      
      The new code gives the bottom answer.
      
      Original Git commit: e8adf23d1ee97b57c8aea32ee8365203b77c0e42
      Michael Haggerty committed
    • recs_match(): take two xrecord_t pointers as arguments · 09fb5b2a
      There is no reason for it to take an array and two indexes as argument,
      as it only accesses two elements of the array.
      
      Original Git commit: 152598cbb667471c8f5be16e199922a41452b2d5
      Michael Haggerty committed
    • xdiff: add recs_match helper function · 506bf09d
      It is a common pattern in xdl_change_compact to check that hashes and
      strings match. The resulting code to perform this change causes very
      long lines and makes it hard to follow the intention. Introduce a helper
      function recs_match which performs both checks to increase
      code readability.
      
      Original Git commit: 92e5b62fec0e9b647429e8d3736c571c434dd375
      Jacob Keller committed
  2. 13 Sep, 2016 2 commits
  3. 09 Sep, 2016 1 commit
  4. 06 Sep, 2016 2 commits
  5. 05 Sep, 2016 2 commits
    • diff: treat binary patches with no data special · adedac5a
      When creating and printing diffs, deal with binary deltas that have
      binary data specially, versus diffs that have a binary file but lack the
      actual binary data.
      Edward Thomson committed
    • cmake: add curl library path · 528b2f7d
      The `PKG_CHECK_MODULES` function searches a pkg-config module and
      then proceeds to set various variables containing information on
      how to link to the library. In contrast to the `FIND_PACKAGE`
      function, the library path set by `PKG_CHECK_MODULES` will not
      necessarily contain linking instructions with a complete path to
      the library, though. So when a library is not installed in a
      standard location, the linker might later fail due to being
      unable to locate it.
      
      While we already honor this when configuring libssh2 by adding
      `LIBSSH2_LIBRARY_DIRS` to the link directories, we fail to do so
      for libcurl, preventing us to build libgit2 on e.g. FreeBSD. Fix
      the issue by adding the curl library directory to the linker
      search path.
      Patrick Steinhardt committed
  6. 02 Sep, 2016 3 commits
  7. 01 Sep, 2016 1 commit
    • patch_generate: only calculate binary diffs if requested · 4b34f687
      When generating diffs for binary files, we load and decompress
      the blobs in order to generate the actual diff, which can be very
      costly. While we cannot avoid this for the case when we are
      called with the `GIT_DIFF_SHOW_BINARY` flag, we do not have to
      load the blobs in the case where this flag is not set, as the
      caller is expected to have no interest in the actual content of
      binary files.
      
      Fix the issue by only generating a binary diff when the caller is
      actually interested in the diff. As libgit2 uses heuristics to
      determine that a blob contains binary data by inspecting its size
      without loading from the ODB, this saves us quite some time when
      diffing in a repository with binary files.
      Patrick Steinhardt committed
  8. 30 Aug, 2016 3 commits
  9. 29 Aug, 2016 4 commits
  10. 26 Aug, 2016 1 commit
  11. 24 Aug, 2016 2 commits
  12. 22 Aug, 2016 1 commit
  13. 17 Aug, 2016 4 commits
  14. 12 Aug, 2016 1 commit
    • ignore: allow unignoring basenames in subdirectories · fcb2c1c8
      The .gitignore file allows for patterns which unignore previous
      ignore patterns. When unignoring a previous pattern, there are
      basically three cases how this is matched when no globbing is
      used:
      
      1. when a previous file has been ignored, it can be unignored by
         using its exact name, e.g.
      
         foo/bar
         !foo/bar
      
      2. when a file in a subdirectory has been ignored, it can be
         unignored by using its basename, e.g.
      
         foo/bar
         !bar
      
      3. when all files with a basename are ignored, a specific file
         can be unignored again by specifying its path in a
         subdirectory, e.g.
      
         bar
         !foo/bar
      
      The first problem in libgit2 is that we did not correctly treat
      the second case. While we verified that the negative pattern
      matches the tail of the positive one, we did not verify if it
      only matches the basename of the positive pattern. So e.g. we
      would have also negated a pattern like
      
          foo/fruz_bar
          !bar
      
      Furthermore, we did not check for the third case, where a
      basename is being unignored in a certain subdirectory again.
      
      Both issues are fixed with this commit.
      Patrick Steinhardt committed
  15. 10 Aug, 2016 2 commits
  16. 09 Aug, 2016 4 commits
  17. 08 Aug, 2016 4 commits