1. 01 Jun, 2020 1 commit
  2. 22 Nov, 2019 1 commit
  3. 11 Aug, 2019 1 commit
  4. 12 Jul, 2019 3 commits
    • attr_file: ignore macros defined in subdirectories · f8346905
      Right now, we are unconditionally applying all macros found in a
      gitatttributes file. But quoting gitattributes(5):
      
          Custom macro attributes can be defined only in top-level
          gitattributes files ($GIT_DIR/info/attributes, the .gitattributes
          file at the top level of the working tree, or the global or
          system-wide gitattributes files), not in .gitattributes files in
          working tree subdirectories. The built-in macro attribute "binary"
          is equivalent to:
      
      So gitattribute files in subdirectories of the working tree may
      explicitly _not_ contain macro definitions, but we do not currently
      enforce this limitation.
      
      This patch introduces a new parameter to the gitattributes parser that
      tells whether macros are allowed in the current file or not. If set to
      `false`, we will still parse macros, but silently ignore them instead of
      adding them to the list of defined macros. Update all callers to
      correctly determine whether the to-be-parsed file may contain macros or
      not. Most importantly, when walking up the directory hierarchy, we will
      only set it to `true` once it reaches the root directory of the repo
      itself.
      
      Add a test that verifies that we are indeed not applying macros from
      subdirectories. Previous to these changes, the test would've failed.
      Patrick Steinhardt committed
    • attr_file: refactor `parse_buffer` function · 97968529
      The gitattributes code is one of our oldest and most-untouched codebases
      in libgit2, and as such its code style doesn't quite match our current
      best practices. Refactor the function `git_attr_file__parse_buffer` to
      better match them.
      Patrick Steinhardt committed
    • attr_file: refactor `load_standalone` function · dbc7e4b1
      The gitattributes code is one of our oldest and most-untouched codebases
      in libgit2, and as such its code style doesn't quite match our current
      best practices. Refactor the function `git_attr_file__lookup_standalone`
      to better match them.
      Patrick Steinhardt committed
  5. 04 Jul, 2019 1 commit
    • attr_file: completely initialize attribute sessions · 1bbec26d
      The function `git_attr_session__init` is currently only initializing
      setting up the attribute's session key by incrementing the repo-global
      key by one. Most notably, all other members of the `git_attr_session`
      struct are not getting initialized at all. So if one is to allocate a
      session on the stack and then calls `git_attr_session__init`, the
      session will still not be fully initialized. We have fared just fine
      with that until now as all users of the function have allocated the
      session structure as part of bigger structs with `calloc`, and thus its
      contents have been zero-initialized implicitly already.
      
      Fix this by explicitly zeroing out the session to enable allocation of
      sessions on the stack.
      Patrick Steinhardt committed
  6. 15 Jun, 2019 2 commits
    • attr_file: convert to use `wildmatch` · 05f9986a
      Upstream git has converted to use `wildmatch` instead of
      `fnmatch`. Convert our gitattributes logic to use `wildmatch` as
      the last user of `fnmatch`. Please, don't expect I know what I'm
      doing here: the fnmatch parser is one of the most fun things to
      play around with as it has a sh*tload of weird cases. In all
      honesty, I'm simply relying on our tests that are by now rather
      comprehensive in that area.
      
      The conversion actually fixes compatibility with how git.git
      parser "**" patterns when the given path does not contain any
      directory separators. Previously, a pattern "**.foo" erroneously
      wouldn't match a file "x.foo", while git.git would match.
      
      Remove the new-unused LEADINGDIR/NOLEADINGDIR flags for
      `git_attr_fnmatch`.
      Patrick Steinhardt committed
    • posix: remove implicit include of "fnmatch.h" · 451df793
      We're about to phase out our bundled fnmatch implementation as
      git.git has moved to wildmatch long ago in 2014. To make it
      easier to spot which files are stilll using fnmatch, remove the
      implicit "fnmatch.h" include in "posix.h" and instead include it
      explicitly.
      Patrick Steinhardt committed
  7. 13 Jun, 2019 4 commits
    • attr_file: remove invalid TODO comment · 3b517351
      In our attributes pattern parsing code, we have a comment that
      states we might have to convert '\' characters to '/' to have
      proper POSIX paths. But in fact, '\' characters are valid inside
      the string and act as escape mechanism for various characters,
      which is why we never want to convert those to POSIX directory
      separators. Furthermore, gitignore patterns are specified to only
      treat '/' as directory separators.
      
      Remove the comment to avoid future confusion.
      Patrick Steinhardt committed
    • attr_file: account for escaped escapes when searching trailing space · b3b6a39d
      When determining the trailing space length, we need to honor
      whether spaces are escaped or not. Currently, we do not check
      whether the escape itself is escaped, though, which might
      generate an off-by-one in that case as we will simply treat the
      space as escaped.
      
      Fix this by checking whether the backslashes preceding the space
      are themselves escaped.
      Patrick Steinhardt committed
    • attr_file: fix unescaping of escapes required for fnmatch · 10ac298c
      When parsing attribute patterns, we will eventually unescape the
      parsed pattern. This is required because we require custom
      escapes for whitespace characters, as normally they are used to
      terminate the current pattern. Thing is, we don't only unescape
      those whitespace characters, but in fact all escaped sequences.
      So for example if the pattern was "\*", we unescape that to "*".
      As this is directly passed to fnmatch(3) later, fnmatch would
      treat it as a simple glob matching all files where it should
      instead only match a file with name "*".
      
      Fix the issue by unescaping spaces, only. Add a bunch of tests to
      exercise escape parsing.
      Patrick Steinhardt committed
    • attr_file: properly handle escaped '\' when searching non-escaped spaces · eb146e58
      When parsing attributes, we need to search for the first
      unescaped whitespace character to determine where the pattern is
      to be cut off. The scan fails to account for the case where the
      escaping '\' character is itself escaped, though, and thus we
      would not recognize the cut-off point in patterns like "\\ ".
      
      Refactor the scanning loop to remember whether the last character
      was an escape character. If it was and the next character is a
      '\', too, then we will reset to non-escaped mode again. Thus, we
      now handle escaped whitespaces as well as escaped wildcards
      correctly.
      Patrick Steinhardt committed
  8. 06 Jun, 2019 2 commits
    • ignore: handle escaped trailing whitespace · d81e7866
      The gitignore's pattern format specifies that "Trailing spaces
      are ignored unless they are quoted with backslash ("\")". We do
      not honor this currently and will treat a pattern "foo\ " as if
      it was "foo\" only and a pattern "foo\ \ " as "foo\ \".
      
      Fix our code to handle those special cases and add tests to avoid
      regressions.
      Patrick Steinhardt committed
    • attr_file: refactor stripping of trailing spaces · b6967c39
      The stripping of trailing spaces currently happens as part of
      `git_attr_fnmatch__parse`. As we aren't currently parsing
      trailing whitespaces correct in case they're escaped, we'll have
      to change that code, though. To make actual behavioural change
      easier to review, refactor the code up-front by pulling it out
      into its own function that is expected to retain the exact same
      functionality as before. Like this, the fix will be trivial to
      apply.
      Patrick Steinhardt committed
  9. 24 May, 2019 1 commit
  10. 19 May, 2019 2 commits
  11. 14 Mar, 2019 1 commit
  12. 25 Jan, 2019 1 commit
  13. 22 Jan, 2019 1 commit
  14. 10 Jun, 2018 1 commit
  15. 06 Jun, 2018 1 commit
    • ignore: fix negative leading directory rules unignoring subdirectory files · 20b4c175
      When computing whether a file is ignored, we simply search for the first
      matching rule and return whether it is a positive ignore rule (the file
      is really ignored) or whether it is a negative ignore rule (the file is
      being unignored). Each rule has a set of flags which are being passed to
      `fnmatch`, depending on what kind of rule it is. E.g. in case it is a
      negative ignore we add a flag `GIT_ATTR_FNMATCH_NEGATIVE`, in case it
      contains a glob we set the `GIT_ATTR_FNMATCH_HASGLOB` flag.
      
      One of these flags is the `GIT_ATTR_FNMATCH_LEADINGDIR` flag, which is
      always set in case the pattern has a trailing "/*" or in case the
      pattern is negative. The flag causes the `fnmatch` function to return a
      match in case a string is a leading directory of another, e.g. "dir/"
      matches "dir/foo/bar.c". In case of negative patterns, this is wrong in
      certain cases.
      
      Take the following simple example of a gitignore:
      
          dir/
          !dir/
      
      The `LEADINGDIR` flag causes "!dir/" to match "dir/foo/bar.c", and we
      correctly unignore the directory. But take this example:
      
          *.test
          !dir/*
      
      We expect everything in "dir/" to be unignored, but e.g. a file in a
      subdirectory of dir should be ignored, as the "*" does not cross
      directory hierarchies. With `LEADINGDIR`, though, we would just see that
      "dir/" matches and return that the file is unignored, even if it is
      contained in a subdirectory. Instead, we want to ignore leading
      directories here and check "*.test". Afterwards, we have to iterate up
      to the parent directory and do the same checks.
      
      To fix the issue, disallow matching against leading directories in
      gitignore files. This can be trivially done by just adding the
      `GIT_ATTR_FNMATCH_NOLEADINGDIR` to the spec passed to
      `git_attr_fnmatch__parse`. Due to a bug in that function, though, this
      flag is being ignored for negative patterns, which is fixed in this
      commit, as well. As a last fix, we need to ignore rules that are
      supposed to match a directory when our path itself is a file.
      
      All together, these changes fix the described error case.
      Patrick Steinhardt committed
  16. 12 Apr, 2018 1 commit
    • attr_file: fix handling of directory patterns with trailing spaces · 251d8771
      When comparing whether a path matches a directory rule, we pass the
      both the path and directory name to `fnmatch` with
      `GIT_ATTR_FNMATCH_DIRECTORY` being set. `fnmatch` expects the pattern to
      contain no trailing directory '/', which is why we try to always strip
      patterns of trailing slashes. We do not handle that case correctly
      though when the pattern itself has trailing spaces, causing the match to
      fail.
      
      Fix the issue by stripping trailing spaces and tabs for a rule previous
      to checking whether the pattern is a directory pattern with a trailing
      '/'. This replaces the whitespace-stripping in our ignore file parsing
      code, which was stripping whitespaces too late. Add a test to catch
      future breakage.
      Patrick Steinhardt committed
  17. 03 Jul, 2017 2 commits
    • 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
    • Add missing license headers · 2480d0eb
      Some implementation files were missing the license headers. This commit
      adds them.
      Patrick Steinhardt committed
  18. 17 May, 2017 1 commit
  19. 29 Dec, 2016 1 commit
  20. 09 Feb, 2016 1 commit
  21. 28 Oct, 2015 1 commit
  22. 12 May, 2015 4 commits
    • attr: less path mangling during attribute matching · 90997e40
      When handling attr matching, simply compare the directory path where the
      attribute file resides to the path being matched.  Skip over commonality
      to allow us to compare the contents of the attribute file to the remainder
      of the path.
      
      This allows us to more easily compare the pattern directly to the path,
      instead of trying to guess whether we want to compare the path's basename
      or the full path based on whether the match was inside a containing
      directory or not.
      
      This also allows us to do fewer translations on the pattern (trying to
      re-prefix it.)
      Edward Thomson committed
    • attr: don't mangle file path during attr matching · 9465bedb
      When determining whether some file matches an attr pattern, do
      not try to truncate the path to pass to fnmatch.  When there is
      no containing directory for an item (eg, from a .gitignore in the
      root) this will cause us to truncate our path, which means that
      we cannot do meaningful comparisons on it and we may have false
      positives when trying to determine whether a given file is actually
      a file or a folder (as we have lost the path's base information.)
      
      This mangling was to allow fnmatch to compare a directory on disk to
      the name of a directory, but it is unnecessary as our fnmatch accepts
      FNM_LEADING_DIR.
      Edward Thomson committed
    • attr: don't match files for folders · ef6d0722
      When ignoring a path "foo/", ensure that this is actually a directory,
      and not simply a file named "foo".
      Edward Thomson committed
  23. 28 Apr, 2015 1 commit
  24. 23 Apr, 2015 1 commit
  25. 04 Feb, 2015 2 commits
  26. 03 Feb, 2015 1 commit
    • attrcache: don't re-read attrs during checkout · 9f779aac
      During checkout, assume that the .gitattributes files aren't
      modified during the checkout.  Instead, create an "attribute session"
      during checkout.  Assume that attribute data read in the same
      checkout "session" hasn't been modified since the checkout started.
      (But allow subsequent checkouts to invalidate the cache.)
      
      Further, cache nonexistent git_attr_file data even when .gitattributes
      files are not found to prevent re-scanning for nonexistent files.
      Edward Thomson committed
  27. 29 Dec, 2014 1 commit