Skip to content

Commit df935b5

Browse files
zwaregnprice
andauthored
[3.8] bpo-37936: Systematically distinguish rooted vs. unrooted in .gitignore (GH-15823) (GH-15900)
A root cause of bpo-37936 is that it's easy to write a .gitignore rule that's intended to apply to a specific file (e.g., the `pyconfig.h` generated by `./configure`) but actually applies to all similarly-named files in the tree (e.g., `PC/pyconfig.h`.) Specifically, any rule with no non-trailing slashes is applied in an "unrooted" way, to files anywhere in the tree. This means that if we write the rules in the most obvious-looking way, then * for specific files we want to ignore that happen to be in subdirectories (like `Modules/config.c`), the rule will work as intended, staying "rooted" to the top of the tree; but * when a specific file we want to ignore happens to be at the root of the repo (like `platform`), then the obvious rule (`platform`) will apply much more broadly than intended: if someone tries to add a file or directory named `platform` somewhere else in the tree, it will unexpectedly get ignored. That's surprising behavior that can make the .gitignore file's behavior feel finicky and unpredictable. To avoid it, we can simply always give a rule "rooted" behavior when that's what's intended, by systematically using leading slashes. Further, to help make the pattern obvious when looking at the file and minimize any need for thinking about the syntax when adding new rules: separate the rules into one group for each type, with brief comments identifying them. For most of these rules it's clear whether they're meant to be rooted or unrooted, but in a handful of cases I've only guessed. In that case the safer default (the choice that won't hide information) is the narrower, rooted meaning, with a leading slash. If for some of these the unrooted meaning is desired after all, it'll be easy to move them to the unrooted section at the top. (cherry picked from commit 455122a) Co-authored-by: Greg Price <[email protected]>
1 parent 872c85a commit df935b5

File tree

3 files changed

+61
-51
lines changed

3 files changed

+61
-51
lines changed

.gitignore

Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
# Two-trick pony for OSX and other case insensitive file systems:
2-
# Ignore ./python binary on Unix but still look into ./Python/ directory.
3-
/python
4-
!/Python/
1+
#####
2+
# First, rules intended to apply in all subdirectories.
3+
# These contain no slash, or only a trailing slash.
54

65
*.cover
76
*.iml
87
*.o
8+
*.a
9+
*.so*
10+
*.dylib
11+
*.dll
912
*.orig
1013
*.pyc
1114
*.pyd
@@ -18,6 +21,31 @@
1821
*.profraw
1922
*.dyn
2023
.gdb_history
24+
.purify
25+
__pycache__
26+
.hg/
27+
.svn/
28+
.idea/
29+
tags
30+
TAGS
31+
.vs/
32+
.vscode/
33+
gmon.out
34+
.coverage
35+
.mypy_cache/
36+
37+
*.exe
38+
!Lib/distutils/command/*.exe
39+
40+
# Ignore core dumps... but not Tools/msi/core/ or the like.
41+
core
42+
!core/
43+
44+
45+
#####
46+
# Then, rules meant for a specific location relative to the repo root.
47+
# These must contain a non-trailing slash (and may also have a trailing slash.)
48+
2149
Doc/build/
2250
Doc/venv/
2351
Doc/.venv/
@@ -29,7 +57,7 @@ Lib/lib2to3/*.pickle
2957
Lib/test/data/*
3058
!Lib/test/data/README
3159
/Makefile
32-
Makefile.pre
60+
/Makefile.pre
3361
Misc/python.pc
3462
Misc/python-embed.pc
3563
Misc/python-config.sh
@@ -38,12 +66,9 @@ Modules/Setup.local
3866
Modules/config.c
3967
Modules/ld_so_aix
4068
Programs/_freeze_importlib
41-
Programs/_freeze_importlib.exe
4269
Programs/_testembed
43-
Programs/_testembed.exe
4470
PC/python_nt*.h
4571
PC/pythonnt_rc*.h
46-
PC/*/*.exe
4772
PC/*/*.exp
4873
PC/*/*.lib
4974
PC/*/*.bsc
@@ -62,52 +87,34 @@ PCbuild/*-pgi
6287
PCbuild/*-pgo
6388
PCbuild/*.VC.db
6489
PCbuild/*.VC.opendb
65-
PCbuild/.vs/
6690
PCbuild/amd64/
6791
PCbuild/arm32/
6892
PCbuild/arm64/
6993
PCbuild/obj/
7094
PCbuild/win32/
71-
.purify
72-
__pycache__
73-
autom4te.cache
74-
build/
75-
buildno
76-
config.cache
77-
config.log
78-
config.status
79-
config.status.lineno
80-
core
81-
!Tools/msi/core/
82-
db_home
83-
.hg/
84-
.idea/
85-
ipch/
86-
libpython*.a
87-
libpython*.so*
88-
libpython*.dylib
89-
libpython*.dll
90-
platform
91-
pybuilddir.txt
95+
/autom4te.cache
96+
/build/
97+
/config.cache
98+
/config.log
99+
/config.status
100+
/config.status.lineno
101+
/platform
102+
/pybuilddir.txt
92103
/pyconfig.h
93-
python-config
94-
python-config.py
95-
python.bat
96-
python.exe
97-
python-gdb.py
98-
python.exe-gdb.py
99-
reflog.txt
100-
.svn/
101-
tags
102-
TAGS
103-
.coverage
104-
coverage/
105-
externals/
106-
htmlcov/
104+
/python-config
105+
/python-config.py
106+
/python.bat
107+
/python-gdb.py
108+
/python.exe-gdb.py
109+
/reflog.txt
110+
/coverage/
111+
/externals/
112+
/htmlcov/
107113
Tools/msi/obj
108114
Tools/ssl/amd64
109115
Tools/ssl/win32
110-
.vs/
111-
.vscode/
112-
gmon.out
113-
.mypy_cache/
116+
117+
# Two-trick pony for OSX and other case insensitive file systems:
118+
# Ignore ./python binary on Unix but still look into ./Python/ directory.
119+
/python
120+
!/Python/

Lib/test/libregrtest/runtest.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,7 @@ def cleanup_test_droppings(test_name, verbose):
313313
# since if a test leaves a file open, it cannot be deleted by name (while
314314
# there's nothing we can do about that here either, we can display the
315315
# name of the offending test, which is a real help).
316-
for name in (support.TESTFN,
317-
"db_home",
318-
):
316+
for name in (support.TESTFN,):
319317
if not os.path.exists(name):
320318
continue
321319

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The :file:`.gitignore` file systematically keeps "rooted", with a
2+
non-trailing slash, all the rules that are meant to apply to files in a
3+
specific place in the repo. Previously, when the intended file to ignore
4+
happened to be at the root of the repo, we'd most often accidentally also
5+
ignore files and directories with the same name anywhere in the tree.

0 commit comments

Comments
 (0)