1. 28 Apr, 2021 1 commit
  2. 11 Dec, 2020 2 commits
  3. 27 Nov, 2020 2 commits
  4. 09 Jun, 2020 1 commit
  5. 01 Jun, 2020 1 commit
  6. 18 Jan, 2020 1 commit
  7. 22 Nov, 2019 1 commit
  8. 05 Nov, 2019 1 commit
  9. 27 Aug, 2019 2 commits
    • diff_generate: detect memory allocation errors when preparing opts · fe241071
      When preparing options for the two iterators that are about to be
      diffed, we allocate a common prefix for both iterators depending on
      the options passed by the user. We do not check whether the allocation
      was successful, though. In fact, this isn't much of a problem, as using
      a `NULL` prefix is perfectly fine. But in the end, we probably want to
      detect that the system doesn't have any memory left, as we're unlikely
      to be able to continue afterwards anyway.
      
      While the issue is being fixed in the newly created function
      `diff_prepare_iterator_opts`, it has been previously existing in the
      previous macro `DIFF_FROM_ITERATORS` already.
      Patrick Steinhardt committed
    • diff_generate: refactor `DIFF_FROM_ITERATORS` macro of doom · 8a23597b
      While the `DIFF_FROM_ITERATORS` does make it shorter to implement the
      various `git_diff_foo_to_bar` functions, it is a complex and unreadable
      beast that implicitly assumes certain local variable names. This is not
      something desirable to have at all and obstructs understanding and more
      importantly debugging the code by quite a bit.
      
      The `DIFF_FROM_ITERATORS` macro basically removed the burden of having
      to derive the options for both iterators from a pair of iterator flags
      and the diff options. This patch introduces a new function that does the
      that exact and refactors all callers to manage the iterators by
      themselves.
      
      As we potentially need to allocate a shared prefix for the
      iterator, we need to tell the caller to allocate that prefix as soon as
      the options aren't required anymore. Thus, the function has a `char
      **prefix` out pointer that will get set to the allocated string and
      subsequently be free'd by the caller.
      
      While this patch increases the line count, I personally deem this to an
      acceptable tradeoff for increased readbiblity.
      Patrick Steinhardt committed
  10. 20 Jul, 2019 1 commit
  11. 18 Jul, 2019 1 commit
  12. 15 Jun, 2019 1 commit
  13. 25 Jan, 2019 2 commits
  14. 22 Jan, 2019 1 commit
  15. 01 Dec, 2018 2 commits
  16. 10 Jun, 2018 1 commit
  17. 06 Jun, 2018 1 commit
    • Fix stash save bug with fast path index check · 5a7d454b
      If the index contains stat data for a modified file, and the file is
      not racily dirty, and there exists an untracked working tree directory
      alphabetically after that file, and there are no other changes to the
      repo, then git_stash_save would fail. It would confuse the untracked
      working tree directory for the modified file, because they have the
      same sha: zero.  The wt directory has a sha of zero because it's a
      directory, and the file would have a zero sha because we wouldn't read
      the file -- we would just know that it doesn't match the index.  To
      fix this confusion, we simply check mode as well as SHA.
      David Turner committed
  18. 03 Jan, 2018 1 commit
    • diff_generate: avoid excessive stats of .gitattribute files · d8896bda
      When generating a diff between two trees, for each file that is to be
      diffed we have to determine whether it shall be treated as text or as
      binary files. While git has heuristics to determine which kind of diff
      to generate, users can also that default behaviour by setting or
      unsetting the 'diff' attribute for specific files.
      
      Because of that, we have to query gitattributes in order to determine
      how to diff the current files. Instead of hitting the '.gitattributes'
      file every time we need to query an attribute, which can get expensive
      especially on networked file systems, we try to cache them instead. This
      works perfectly fine for every '.gitattributes' file that is found, but
      we hit cache invalidation problems when we determine that an attribuse
      file is _not_ existing. We do create an entry in the cache for missing
      '.gitattributes' files, but as soon as we hit that file again we
      invalidate it and stat it again to see if it has now appeared.
      
      In the case of diffing large trees with each other, this behaviour is
      very suboptimal. For each pair of files that is to be diffed, we will
      repeatedly query every directory component leading towards their
      respective location for an attributes file. This leads to thousands or
      even hundreds of thousands of wasted syscalls.
      
      The attributes cache already has a mechanism to help in that scenario in
      form of the `git_attr_session`. As long as the same attributes session
      is still active, we will not try to re-query the gitmodules files at all
      but simply retain our currently cached results. To fix our problem, we
      can create a session at the top-most level, which is the initialization
      of the `git_diff` structure, and use it in order to look up the correct
      diff driver. As the `git_diff` structure is used to generate patches for
      multiple files at once, this neatly solves our problem by retaining the
      session until patches for all files have been generated.
      
      The fix has been tested with linux.git by calling
      `git_diff_tree_to_tree` and `git_diff_to_buf` with v4.10^{tree} and
      v4.14^{tree}.
      
                      | time    | .gitattributes stats
          without fix | 33.201s | 844614
          with fix    | 30.327s | 4441
      
      While execution only improved by roughly 10%, the stat(3) syscalls for
      .gitattributes files decreased by 99.5%. The benchmarks were quite
      simple with best-of-three timings on Linux ext4 systems. One can assume
      that for network based file systems the performance gain will be a lot
      larger due to a much higher latency.
      Patrick Steinhardt committed
  19. 30 Nov, 2017 1 commit
    • diff_generate: fix unsetting diff flags · 5ca3f115
      The macro `DIFF_FLAG_SET` can be used to set or unset a flag by
      modifying the diff's bitmask. While the case of setting the flag is
      handled correctly, the case of unsetting the flag was not. Instead of
      inverting the flags, we are inverting the value which is used to decide
      whether we want to set or unset the bits.
      
      The value being used here is a simple `bool` which is `false`. As that
      is being uplifted to `int` when getting the bitwise-complement, we will
      end up retaining all bits inside of the bitmask. As that's only ever
      used to set `GIT_DIFF_IGNORE_CASE`, we were actually always ignoring
      case for generated diffs.
      
      Fix that by instead getting the bitwise-complement of `FLAG`, not `VAL`.
      Patrick Steinhardt committed
  20. 18 Nov, 2017 1 commit
    • refcount: make refcounting conform to aliasing rules · 585b5dac
      Strict aliasing rules dictate that for most data types, you are not
      allowed to cast them to another data type and then access the casted
      pointers. While this works just fine for most compilers, technically we
      end up in undefined behaviour when we hurt that rule.
      
      Our current refcounting code makes heavy use of casting and thus
      violates that rule. While we didn't have any problems with that code,
      Travis started spitting out a lot of warnings due to a change in their
      toolchain. In the refcounting case, the code is also easy to fix:
      as all refcounting-statements are actually macros, we can just access
      the `rc` field directly instead of casting.
      
      There are two outliers in our code where that doesn't work. Both the
      `git_diff` and `git_patch` structures have specializations for generated
      and parsed diffs/patches, which directly inherit from them. Because of
      that, the refcounting code is only part of the base structure and not of
      the children themselves. We can help that by instead passing their base
      into `GIT_REFCOUNT_INC`, though.
      Patrick Steinhardt committed
  21. 03 Jul, 2017 1 commit
    • Make sure to always include "common.h" first · 0c7f49dd
      Next to including several files, our "common.h" header also declares
      various macros which are then used throughout the project. As such, we
      have to make sure to always include this file first in all
      implementation files. Otherwise, we might encounter problems or even
      silent behavioural differences due to macros or defines not being
      defined as they should be. So in fact, our header and implementation
      files should make sure to always include "common.h" first.
      
      This commit does so by establishing a common include pattern. Header
      files inside of "src" will now always include "common.h" as its first
      other file, separated by a newline from all the other includes to make
      it stand out as special. There are two cases for the implementation
      files. If they do have a matching header file, they will always include
      this one first, leading to "common.h" being transitively included as
      first file. If they do not have a matching header file, they instead
      include "common.h" as first file themselves.
      
      This fixes the outlined problems and will become our standard practice
      for header and source files inside of the "src/" from now on.
      Patrick Steinhardt committed
  22. 29 Dec, 2016 1 commit
  23. 24 Aug, 2016 1 commit
  24. 26 May, 2016 3 commits
  25. 03 May, 2016 1 commit
    • diff: simplify code for handling empty dirs · fe3057b4
      When determining diffs between two iterators we may need to
      recurse into an unmatched directory for the "new" iterator when
      it is either a prefix to the current item of the "old" iterator
      or when untracked/ignored changes are requested by the user and
      the directory is untracked/ignored.
      
      When advancing into the directory and no files are found, we will
      get back `GIT_ENOTFOUND`. If so, we simply skip the directory,
      handling resulting unmatched old items in the next iteration. The
      other case of `iterator_advance_into` returning either
      `GIT_NOERROR` or any other error but `GIT_ENOTFOUND` will be
      handled by the caller, which will now either compare the first
      directory entry of the "new" iterator in case of `GIT_ENOERROR`
      or abort on other cases.
      
      Improve readability of the code to make the above logic more
      clear.
      Patrick Steinhardt committed
  26. 24 Mar, 2016 1 commit
  27. 23 Mar, 2016 2 commits
  28. 11 Feb, 2016 1 commit
  29. 01 Dec, 2015 1 commit
  30. 23 Nov, 2015 1 commit
    • checkout: only consider nsecs when built that way · 25e84f95
      When examining the working directory and determining whether it's
      up-to-date, only consider the nanoseconds in the index entry when
      built with `GIT_USE_NSEC`.  This prevents us from believing that
      the working directory is always dirty when the index was originally
      written with a git client that uinderstands nsecs (like git 2.x).
      Edward Thomson committed
  31. 02 Nov, 2015 1 commit
  32. 28 Oct, 2015 1 commit