Skip to content

Patterns with ending slash work incorrectly #81

@YarikTH

Description

@YarikTH
build*/

Ignores only build* directories with git, but gitignore_parser ignores even files named build*.

Here is the test

#!/bin/bash

echo -e '# Ignore everything that starts with build in the current directory only\n
build*/' > .gitignore

git init

mkdir -p 'build'
echo "" >'build/.keep'
mkdir -p 'build_debug'
echo "" >'build_debug/.keep'

echo "" > build.sh

mkdir -p 'cmake'
echo "" >'cmake/.keep'

mkdir -p 'cmake/build'
echo "" >'cmake/build/.keep'

echo "" > 'cmake/build_script.cmake'

mkdir -p 'boost/build'
echo "" >'boost/build/.keep'
echo -e '# Unignore build here\n
!build' > 'boost/.gitignore'

tree

git status --ignored=matching --untracked-files

test.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ===============================================================================
from gitignore_parser import parse_gitignore
import os


def main():
    gitignore_matches = parse_gitignore('.gitignore')

    ignored_files: List[str] = []

    for root, dirs, files in os.walk('.'):
        def is_dir_suitable(d: str) -> bool:
            full_path = os.path.join(root, d)
            if d == '.git':
                return False
            if gitignore_matches(full_path):
                return False
            return True

        def is_file_suitable(f: str) -> bool:
            full_path = os.path.join(root, f)
            if gitignore_matches(full_path):
                return False
            return True

        # print(f'root: {root}, dirs: {dirs}, files: {files}')

        ignored_files.extend([os.path.join(root, d) for d in dirs if gitignore_matches(os.path.join(root, d))])

        ignored_files.extend([os.path.join(root, f) for f in files if gitignore_matches(os.path.join(root, f))])

        dirs[:] = [d for d in dirs if is_dir_suitable(d)]
        files[:] = [f for f in files if is_file_suitable(f)]

    print('Ignored files:')
    print('\n'.join(ignored_files))


if __name__ == '__main__':
    main()

Outputs:

$ ./make_tree.sh
.
├── boost
│   └── build
├── build
├── build_debug
├── build.sh
├── cmake
│   ├── build
│   └── build_script.cmake
└── make_tree.sh

7 directories, 3 files
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        boost/.gitignore
        boost/build/.keep
        build.sh
        cmake/.keep
        cmake/build_script.cmake
        make_tree.sh

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        build/
        build_debug/
        cmake/build/

nothing added to commit but untracked files present (use "git add" to track)

While this the library thinks

$ ./test.py 
Ignored files:
./build_debug
./build
./build.sh
./cmake/build
./cmake/build_script.cmake
./boost/build

./boost/build is reincluded in nested .gitignore, which I not parsed (because there is no ready function for it).
But ./build.sh and ./cmake/build_script.cmake are falsly ignored because ending '/' that means DIRECTORY is not handled

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions