Repository: psf/black

Issue:
.gitignore is ignored by black if more than one source location is specified
**Describe the bug**

When adding more than one source entry, black ignores the .gitignore entries.

**To Reproduce**

content of .gitignore

```
generated/*
```

Running

```
black test src
```
produces

```
$ black --check tests src
would reformat generated/jtd/__init__.py

Oh no! 💥 💔 💥
1 file would be reformatted, 29 files would be left unchanged.
```

Running
```
black src
```

produces

```
$ black --check src
All done! ✨ 🍰 ✨
```

**Expected behavior**

```
$ black --check test src
All done! ✨ 🍰 ✨
```

**Environment**

<!-- Please complete the following information: -->

- Black's version: 22.8.0
- OS and Python version: MacOS m1

**Additional context**

works with Black version: 22.6.0

<!-- Add any other context about the problem here. -->



Discussion:
The bug seems to be caused by this section of `get_sources`:

https://github.com/psf/black/blob/b60b85b234d6a575f636d0a125478115f993c90c/src/black/__init__.py#L660-L670

In the first run (the first `SRC`) `exclude` is `None`, but then the value gets overridden by `re_compile_maybe_verbose(DEFAULT_EXCLUDES)`, so in the second iteration the condition is not met and skips to `gitignore = None`. 

This can be fixed by creating a flag before the for loop, something like `is_default_exclude = exclude is None`, and check if the value is false afterwards:

```python
if is_default_exclude:
    exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES)
    ...
```

Should I submit a PR? @ichard26 
@aaossa Would be greatly appreciated!

Resolving patch:
diff --git a/src/black/__init__.py b/src/black/__init__.py
--- a/src/black/__init__.py
+++ b/src/black/__init__.py
@@ -30,6 +30,7 @@
 import click
 from click.core import ParameterSource
 from mypy_extensions import mypyc_attr
+from pathspec import PathSpec
 from pathspec.patterns.gitwildmatch import GitWildMatchPatternError
 
 from _black_version import version as __version__
@@ -625,6 +626,11 @@ def get_sources(
     sources: Set[Path] = set()
     root = ctx.obj["root"]
 
+    exclude_is_None = exclude is None
+    exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES) if exclude is None else exclude
+    gitignore = None  # type: Optional[PathSpec]
+    root_gitignore = get_gitignore(root)
+
     for s in src:
         if s == "-" and stdin_filename:
             p = Path(stdin_filename)
@@ -658,16 +664,14 @@ def get_sources(
 
             sources.add(p)
         elif p.is_dir():
-            if exclude is None:
-                exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES)
-                gitignore = get_gitignore(root)
+            if exclude_is_None:
                 p_gitignore = get_gitignore(p)
                 # No need to use p's gitignore if it is identical to root's gitignore
                 # (i.e. root and p point to the same directory).
-                if gitignore != p_gitignore:
-                    gitignore += p_gitignore
-            else:
-                gitignore = None
+                if root_gitignore == p_gitignore:
+                    gitignore = root_gitignore
+                else:
+                    gitignore = root_gitignore + p_gitignore
             sources.update(
                 gen_python_files(
                     p.iterdir(),


Test patch:
diff --git a/tests/data/gitignore_used_on_multiple_sources/.gitignore b/tests/data/gitignore_used_on_multiple_sources/.gitignore
new file mode 100644
--- /dev/null
+++ b/tests/data/gitignore_used_on_multiple_sources/.gitignore
@@ -0,0 +1 @@
+a.py
diff --git a/tests/data/gitignore_used_on_multiple_sources/dir1/a.py b/tests/data/gitignore_used_on_multiple_sources/dir1/a.py
new file mode 100644
diff --git a/tests/data/gitignore_used_on_multiple_sources/dir1/b.py b/tests/data/gitignore_used_on_multiple_sources/dir1/b.py
new file mode 100644
diff --git a/tests/data/gitignore_used_on_multiple_sources/dir2/a.py b/tests/data/gitignore_used_on_multiple_sources/dir2/a.py
new file mode 100644
diff --git a/tests/data/gitignore_used_on_multiple_sources/dir2/b.py b/tests/data/gitignore_used_on_multiple_sources/dir2/b.py
new file mode 100644
diff --git a/tests/test_black.py b/tests/test_black.py
--- a/tests/test_black.py
+++ b/tests/test_black.py
@@ -1956,6 +1956,17 @@ def test_gitignore_used_as_default(self) -> None:
         ctx.obj["root"] = base
         assert_collected_sources(src, expected, ctx=ctx, extend_exclude=r"/exclude/")
 
+    def test_gitignore_used_on_multiple_sources(self) -> None:
+        root = Path(DATA_DIR / "gitignore_used_on_multiple_sources")
+        expected = [
+            root / "dir1" / "b.py",
+            root / "dir2" / "b.py",
+        ]
+        ctx = FakeContext()
+        ctx.obj["root"] = root
+        src = [root / "dir1", root / "dir2"]
+        assert_collected_sources(src, expected, ctx=ctx)
+
     @patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
     def test_exclude_for_issue_1572(self) -> None:
         # Exclude shouldn't touch files that were explicitly given to Black through the