8000 Replace fnmatch with wildmatch by pks-t · Pull Request #5110 · libgit2/libgit2 · GitHub
[go: up one dir, main page]

Skip to content

Replace fnmatch with wildmatch #5110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 15, 2019
Merged

Replace fnmatch with wildmatch #5110

merged 8 commits into from
Jun 15, 2019

Conversation

pks-t
Copy link
Member
@pks-t pks-t commented Jun 13, 2019

Upstream git.git has replaced fnmatch with wildmatch back in commit 70a8fc999d (stop using fnmatch (either native or compat), 2014-02-15). wildmatch has different semantics than fnmatch has and thus may show slightly different behaviour than fnmatch. In fact, by replacing fnmatch with wildmatch, we fix compatibility with git.git in at least two places:

  • gitignores and gitattributes now correctly handle patterns like "**.foo", which previously wouldn't match a file "x.foo"
  • conditional includes now work (more?) consistently with how it works upstream

There's probably more compatibility improvements as fnmatch/wildmatch are used at various locations throught the tree, but only those two struck me while working on the replacement.

Anyway. Getting this merged will have to wait until @ethomson has determined whether we're even allowed to use "wildmatch.c" from git.git, depending on its license history.

@pks-t
Copy link
Member Author
pks-t commented Jun 13, 2019

Fixes #5093

@pks-t
Copy link
Member Author
pks-t commented Jun 14, 2019 via email

@pks-t
Copy link
Member Author
pks-t commented Jun 14, 2019

Fixes #5068

@ethomson
Copy link
Member

Would you mind adding a paragraph to COPYING:

The bundled wildmatch code is licensed under the BSD license:

Copyright Rich Salz.
All rights reserved.

Redistribution and use in any form are permitted provided that the
following restrictions are are met:

1.  Source distributions must retain this entire copyright notice
    and comment.
2.  Binary distributions must include the acknowledgement ``This
    product includes software developed by Rich Salz'' in the
    documentation or other materials provided with the
    distribution.  This must not be represented as an endorsement
   or promotion without specific prior written permission.
3.  The origin of this software must not be misrepresented, either
    by explicit claim or by omission.  Credits must appear in the
    source and documentation.
4.  Altered versions must be plainly marked as such in the source
    and documentation and must not be misrepresented as being the
    original software.

THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

pks-t added 8 commits June 15, 2019 09:34
In commit 70a8fc999d (stop using fnmatch (either native or
compat), 2014-02-15), upstream git has switched over all code
from their internal fnmatch copy to its new wildmatch code. We
haven't followed suit, and thus have developed some
incompatibilities in how we match regular expressions.

Import git's wildmatch from v2.22.0 and add a test suite based on
their t3070-wildmatch.sh tests.
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.
Upstream git.git has converted its codebase to use wildcard in
favor of fnmatch in commit 70a8fc999d (stop using fnmatch (either
native or compat), 2014-02-15). To keep our own regex-matching in
line with what git does, convert all trivial instances of
`fnmatch` usage to use `wildcard`, instead. Trivial usage is
defined to be use of `fnmatch` with either no flags or flags that
have a 1:1 equivalent in wildmatch (PATHNAME, IGNORECASE).
The function `do_match_gitdir` has some horribly named parameters
and variables. Rename them to improve readability. Furthermore,
fix a potentially undetected out-of-memory condition when
appending "**" to the pattern.
When evaluating "gitdir:" and "gitdir/i:" conditionals, we
currently compare the given pattern with the value of
`git_repository_path`. Thing is though that `git_repository_path`
returns the gitdir path with trailing '/', while we actually need
to match against the gitdir without it.

Fix this issue by stripping the trailing '/' previous to
matching. Add various tests to ensure we get this right.
We currently use `p_fnmatch` to compute whether a given "gitdir:"
or "gitdir/i:" conditional matches the current configuration file
path. As git.git has moved to use `wildmatch` instead of
`p_fnmatch` throughout its complete codebase, we evaluate
conditionals inconsistently with git.git in some special cases.

Convert `p_fnmatch` to use `wildmatch`. The `FNM_LEADINGDIR` flag
cannot be translated to `wildmatch`, but in fact git.git doesn't
use it here either. And in fact, dropping it while we go
increases compatibility with git.git.
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`.
The `fnmatch` code has now been completely replaced by
`wildmatch`, same as upstream git.git has been doing in 2014.
Remove it.
@pks-t
Copy link
Member Author
pks-t commented Jun 15, 2019

Would you mind adding a paragraph to COPYING

Done!

@ethomson
Copy link
Member

Nice one, thanks for this @pks-t!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0