Skip to content

Commit 06223ad

Browse files
authored
Mark virtual environments ignored for Git (#1825)
1 parent 11d922b commit 06223ad

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

docs/changelog/1806.feature.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Generate ignore file for version control systems to avoid tracking virtual environments by default. Users should
2+
remove these files if still want to track. For now we support only **git** by :user:`gaborbernat`.

docs/user_guide.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ The tool works in two phases:
1919
- **Phase 1** discovers a python interpreter to create a virtual environment from (by default this is the same python
2020
as the one ``virtualenv`` is running from, however we can change this via the :option:`p` option).
2121
- **Phase 2** creates a virtual environment at the specified destination (:option:`dest`), this can be broken down into
22-
three further sub-steps:
22+
four further sub-steps:
2323

2424
- create a python that matches the target python interpreter from phase 1,
2525
- install (bootstrap) seed packages (one or more of :pypi:`pip`, :pypi:`setuptools`, :pypi:`wheel`) in the created
2626
virtual environment,
2727
- install activation scripts into the binary directory of the virtual environment (these will allow end user to
2828
*activate* the virtual environment from various shells).
29+
- create files that mark the virtual environment as to be ignored by version control systems (currently we support
30+
Git only, as Mercurial, Bazaar or SVN does not support ignore files in subdirectories).
2931

3032
The python in your new virtualenv is effectively isolated from the python that was used to create it.
3133

src/virtualenv/create/creator.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from argparse import ArgumentTypeError
99
from ast import literal_eval
1010
from collections import OrderedDict
11+
from textwrap import dedent
1112

1213
from six import add_metaclass
1314

@@ -154,6 +155,7 @@ def run(self):
154155
safe_delete(self.dest)
155156
self.create()
156157
self.set_pyenv_cfg()
158+
self.setup_ignore_vcs()
157159

158160
def set_pyenv_cfg(self):
159161
self.pyenv_cfg.content = OrderedDict()
@@ -162,6 +164,23 @@ def set_pyenv_cfg(self):
162164
self.pyenv_cfg["version_info"] = ".".join(str(i) for i in self.interpreter.version_info)
163165
self.pyenv_cfg["virtualenv"] = __version__
164166

167+
def setup_ignore_vcs(self):
168+
"""Generate ignore instructions for version control systems."""
169+
# mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs
170+
(self.dest / ".gitignore").write_text(
171+
dedent(
172+
"""
173+
# created by virtualenv automatically
174+
*
175+
""",
176+
).lstrip(),
177+
)
178+
# Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the
179+
# subinclude directive from root, at which point on might as well ignore the directory itself, see
180+
# https://www.selenic.com/mercurial/hgignore.5.html for more details
181+
# Bazaar - does not support ignore files in sub-directories, only at root level via .bzrignore
182+
# Subversion - does not support ignore files, requires direct manipulation with the svn tool
183+
165184
@property
166185
def debug(self):
167186
"""

tests/unit/create/test_creator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ def list_to_str(iterable):
233233
make_file = debug["makefile_filename"]
234234
assert os.path.exists(make_file)
235235

236+
git_ignore = (dest / ".gitignore").read_text()
237+
assert git_ignore.splitlines() == ["# created by virtualenv automatically", "*"]
238+
236239

237240
@pytest.mark.skipif(not CURRENT.has_venv, reason="requires interpreter with venv")
238241
def test_venv_fails_not_inline(tmp_path, capsys, mocker):

0 commit comments

Comments
 (0)