We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
.gitignore added to places it should not
Refs #1806

Virtualenv now drops a .gitignore file. While I understand where you are coming from, it is a mistake to assume virtualenv owns the target directory. For example, I and many people I work with typically do this:

```
git clone git@github.com:stefanholek/foo
cd foo
virtualenv .
./bin/pip install -e .
./bin/python -m unittest
```

Recent versions of virtualenv add a .gitignore file into my sandbox. To make matters worse it even **overwrites** an existing .gitignore file! This is very clearly wrong.

I suggest to not write the .gitignore file unless virtualenv has created the target directory, or at least don't write it if the target directory already contains a .git directory and/or a .gitignore file.

Thanks!

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/virtualenv/create/creator.py`
Content:
```
1 from __future__ import absolute_import, print_function, unicode_literals
2 
3 import json
4 import logging
5 import os
6 import sys
7 from abc import ABCMeta, abstractmethod
8 from argparse import ArgumentTypeError
9 from ast import literal_eval
10 from collections import OrderedDict
11 from textwrap import dedent
12 
13 from six import add_metaclass
14 
15 from virtualenv.discovery.cached_py_info import LogCmd
16 from virtualenv.info import WIN_CPYTHON_2
17 from virtualenv.util.path import Path, safe_delete
18 from virtualenv.util.six import ensure_str, ensure_text
19 from virtualenv.util.subprocess import run_cmd
20 from virtualenv.version import __version__
21 
22 from .pyenv_cfg import PyEnvCfg
23 
24 HERE = Path(os.path.abspath(__file__)).parent
25 DEBUG_SCRIPT = HERE / "debug.py"
26 
27 
28 class CreatorMeta(object):
29     def __init__(self):
30         self.error = None
31 
32 
33 @add_metaclass(ABCMeta)
34 class Creator(object):
35     """A class that given a python Interpreter creates a virtual environment"""
36 
37     def __init__(self, options, interpreter):
38         """Construct a new virtual environment creator.
39 
40         :param options: the CLI option as parsed from :meth:`add_parser_arguments`
41         :param interpreter: the interpreter to create virtual environment from
42         """
43         self.interpreter = interpreter
44         self._debug = None
45         self.dest = Path(options.dest)
46         self.clear = options.clear
47         self.pyenv_cfg = PyEnvCfg.from_folder(self.dest)
48         self.app_data = options.app_data
49 
50     def __repr__(self):
51         return ensure_str(self.__unicode__())
52 
53     def __unicode__(self):
54         return "{}({})".format(self.__class__.__name__, ", ".join("{}={}".format(k, v) for k, v in self._args()))
55 
56     def _args(self):
57         return [
58             ("dest", ensure_text(str(self.dest))),
59             ("clear", self.clear),
60         ]
61 
62     @classmethod
63     def can_create(cls, interpreter):
64         """Determine if we can create a virtual environment.
65 
66         :param interpreter: the interpreter in question
67         :return: ``None`` if we can't create, any other object otherwise that will be forwarded to \
68                   :meth:`add_parser_arguments`
69         """
70         return True
71 
72     @classmethod
73     def add_parser_arguments(cls, parser, interpreter, meta, app_data):
74         """Add CLI arguments for the creator.
75 
76         :param parser: the CLI parser
77         :param app_data: the application data folder
78         :param interpreter: the interpreter we're asked to create virtual environment for
79         :param meta: value as returned by :meth:`can_create`
80         """
81         parser.add_argument(
82             "dest", help="directory to create virtualenv at", type=cls.validate_dest,
83         )
84         parser.add_argument(
85             "--clear",
86             dest="clear",
87             action="store_true",
88             help="remove the destination directory if exist before starting (will overwrite files otherwise)",
89             default=False,
90         )
91 
92     @abstractmethod
93     def create(self):
94         """Perform the virtual environment creation."""
95         raise NotImplementedError
96 
97     @classmethod
98     def validate_dest(cls, raw_value):
99         """No path separator in the path, valid chars and must be write-able"""
100 
101         def non_write_able(dest, value):
102             common = Path(*os.path.commonprefix([value.parts, dest.parts]))
103             raise ArgumentTypeError(
104                 "the destination {} is not write-able at {}".format(dest.relative_to(common), common),
105             )
106 
107         # the file system must be able to encode
108         # note in newer CPython this is always utf-8 https://www.python.org/dev/peps/pep-0529/
109         encoding = sys.getfilesystemencoding()
110         refused = OrderedDict()
111         kwargs = {"errors": "ignore"} if encoding != "mbcs" else {}
112         for char in ensure_text(raw_value):
113             try:
114                 trip = char.encode(encoding, **kwargs).decode(encoding)
115                 if trip == char:
116                     continue
117                 raise ValueError(trip)
118             except ValueError:
119                 refused[char] = None
120         if refused:
121             raise ArgumentTypeError(
122                 "the file system codec ({}) cannot handle characters {!r} within {!r}".format(
123                     encoding, "".join(refused.keys()), raw_value,
124                 ),
125             )
126         if os.pathsep in raw_value:
127             raise ArgumentTypeError(
128                 "destination {!r} must not contain the path separator ({}) as this would break "
129                 "the activation scripts".format(raw_value, os.pathsep),
130             )
131 
132         value = Path(raw_value)
133         if value.exists() and value.is_file():
134             raise ArgumentTypeError("the destination {} already exists and is a file".format(value))
135         if (3, 3) <= sys.version_info <= (3, 6):
136             # pre 3.6 resolve is always strict, aka must exists, sidestep by using os.path operation
137             dest = Path(os.path.realpath(raw_value))
138         else:
139             dest = Path(os.path.abspath(str(value))).resolve()  # on Windows absolute does not imply resolve so use both
140         value = dest
141         while dest:
142             if dest.exists():
143                 if os.access(ensure_text(str(dest)), os.W_OK):
144                     break
145                 else:
146                     non_write_able(dest, value)
147             base, _ = dest.parent, dest.name
148             if base == dest:
149                 non_write_able(dest, value)  # pragma: no cover
150             dest = base
151         return str(value)
152 
153     def run(self):
154         if self.dest.exists() and self.clear:
155             logging.debug("delete %s", self.dest)
156             safe_delete(self.dest)
157         self.create()
158         self.set_pyenv_cfg()
159         self.setup_ignore_vcs()
160 
161     def set_pyenv_cfg(self):
162         self.pyenv_cfg.content = OrderedDict()
163         self.pyenv_cfg["home"] = self.interpreter.system_exec_prefix
164         self.pyenv_cfg["implementation"] = self.interpreter.implementation
165         self.pyenv_cfg["version_info"] = ".".join(str(i) for i in self.interpreter.version_info)
166         self.pyenv_cfg["virtualenv"] = __version__
167 
168     def setup_ignore_vcs(self):
169         """Generate ignore instructions for version control systems."""
170         # mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs
171         (self.dest / ".gitignore").write_text(
172             dedent(
173                 """
174                 # created by virtualenv automatically
175                 *
176                 """,
177             ).lstrip(),
178         )
179         # Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the
180         # subinclude directive from root, at which point on might as well ignore the directory itself, see
181         # https://www.selenic.com/mercurial/hgignore.5.html for more details
182         # Bazaar - does not support ignore files in sub-directories, only at root level via .bzrignore
183         # Subversion - does not support ignore files, requires direct manipulation with the svn tool
184 
185     @property
186     def debug(self):
187         """
188         :return: debug information about the virtual environment (only valid after :meth:`create` has run)
189         """
190         if self._debug is None and self.exe is not None:
191             self._debug = get_env_debug_info(self.exe, self.debug_script(), self.app_data)
192         return self._debug
193 
194     # noinspection PyMethodMayBeStatic
195     def debug_script(self):
196         return DEBUG_SCRIPT
197 
198 
199 def get_env_debug_info(env_exe, debug_script, app_data):
200     env = os.environ.copy()
201     env.pop(str("PYTHONPATH"), None)
202 
203     with app_data.ensure_extracted(debug_script) as debug_script:
204         cmd = [str(env_exe), str(debug_script)]
205         if WIN_CPYTHON_2:
206             cmd = [ensure_text(i) for i in cmd]
207         logging.debug(str("debug via %r"), LogCmd(cmd))
208         code, out, err = run_cmd(cmd)
209 
210     # noinspection PyBroadException
211     try:
212         if code != 0:
213             result = literal_eval(out)
214         else:
215             result = json.loads(out)
216         if err:
217             result["err"] = err
218     except Exception as exception:
219         return {"out": out, "err": err, "returncode": code, "exception": repr(exception)}
220     if "sys" in result and "path" in result["sys"]:
221         del result["sys"]["path"][0]
222     return result
223
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/virtualenv/create/creator.py b/src/virtualenv/create/creator.py
--- a/src/virtualenv/create/creator.py
+++ b/src/virtualenv/create/creator.py
@@ -168,14 +168,16 @@
     def setup_ignore_vcs(self):
         """Generate ignore instructions for version control systems."""
         # mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs
-        (self.dest / ".gitignore").write_text(
-            dedent(
-                """
-                # created by virtualenv automatically
-                *
-                """,
-            ).lstrip(),
-        )
+        git_ignore = self.dest / ".gitignore"
+        if not git_ignore.exists():
+            git_ignore.write_text(
+                dedent(
+                    """
+                    # created by virtualenv automatically
+                    *
+                    """,
+                ).lstrip(),
+            )
         # Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the
         # subinclude directive from root, at which point on might as well ignore the directory itself, see
         # https://www.selenic.com/mercurial/hgignore.5.html for more details

{"golden_diff": "diff --git a/src/virtualenv/create/creator.py b/src/virtualenv/create/creator.py\n--- a/src/virtualenv/create/creator.py\n+++ b/src/virtualenv/create/creator.py\n@@ -168,14 +168,16 @@\n     def setup_ignore_vcs(self):\n         \"\"\"Generate ignore instructions for version control systems.\"\"\"\n         # mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs\n-        (self.dest / \".gitignore\").write_text(\n-            dedent(\n-                \"\"\"\n-                # created by virtualenv automatically\n-                *\n-                \"\"\",\n-            ).lstrip(),\n-        )\n+        git_ignore = self.dest / \".gitignore\"\n+        if not git_ignore.exists():\n+            git_ignore.write_text(\n+                dedent(\n+                    \"\"\"\n+                    # created by virtualenv automatically\n+                    *\n+                    \"\"\",\n+                ).lstrip(),\n+            )\n         # Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the\n         # subinclude directive from root, at which point on might as well ignore the directory itself, see\n         # https://www.selenic.com/mercurial/hgignore.5.html for more details\n", "issue": ".gitignore added to places it should not\nRefs #1806\r\n\r\nVirtualenv now drops a .gitignore file. While I understand where you are coming from, it is a mistake to assume virtualenv owns the target directory. For example, I and many people I work with typically do this:\r\n\r\n```\r\ngit clone git@github.com:stefanholek/foo\r\ncd foo\r\nvirtualenv .\r\n./bin/pip install -e .\r\n./bin/python -m unittest\r\n```\r\n\r\nRecent versions of virtualenv add a .gitignore file into my sandbox. To make matters worse it even **overwrites** an existing .gitignore file! This is very clearly wrong.\r\n\r\nI suggest to not write the .gitignore file unless virtualenv has created the target directory, or at least don't write it if the target directory already contains a .git directory and/or a .gitignore file.\r\n\r\nThanks!\n", "before_files": [{"content": "from __future__ import absolute_import, print_function, unicode_literals\n\nimport json\nimport logging\nimport os\nimport sys\nfrom abc import ABCMeta, abstractmethod\nfrom argparse import ArgumentTypeError\nfrom ast import literal_eval\nfrom collections import OrderedDict\nfrom textwrap import dedent\n\nfrom six import add_metaclass\n\nfrom virtualenv.discovery.cached_py_info import LogCmd\nfrom virtualenv.info import WIN_CPYTHON_2\nfrom virtualenv.util.path import Path, safe_delete\nfrom virtualenv.util.six import ensure_str, ensure_text\nfrom virtualenv.util.subprocess import run_cmd\nfrom virtualenv.version import __version__\n\nfrom .pyenv_cfg import PyEnvCfg\n\nHERE = Path(os.path.abspath(__file__)).parent\nDEBUG_SCRIPT = HERE / \"debug.py\"\n\n\nclass CreatorMeta(object):\n    def __init__(self):\n        self.error = None\n\n\n@add_metaclass(ABCMeta)\nclass Creator(object):\n    \"\"\"A class that given a python Interpreter creates a virtual environment\"\"\"\n\n    def __init__(self, options, interpreter):\n        \"\"\"Construct a new virtual environment creator.\n\n        :param options: the CLI option as parsed from :meth:`add_parser_arguments`\n        :param interpreter: the interpreter to create virtual environment from\n        \"\"\"\n        self.interpreter = interpreter\n        self._debug = None\n        self.dest = Path(options.dest)\n        self.clear = options.clear\n        self.pyenv_cfg = PyEnvCfg.from_folder(self.dest)\n        self.app_data = options.app_data\n\n    def __repr__(self):\n        return ensure_str(self.__unicode__())\n\n    def __unicode__(self):\n        return \"{}({})\".format(self.__class__.__name__, \", \".join(\"{}={}\".format(k, v) for k, v in self._args()))\n\n    def _args(self):\n        return [\n            (\"dest\", ensure_text(str(self.dest))),\n            (\"clear\", self.clear),\n        ]\n\n    @classmethod\n    def can_create(cls, interpreter):\n        \"\"\"Determine if we can create a virtual environment.\n\n        :param interpreter: the interpreter in question\n        :return: ``None`` if we can't create, any other object otherwise that will be forwarded to \\\n                  :meth:`add_parser_arguments`\n        \"\"\"\n        return True\n\n    @classmethod\n    def add_parser_arguments(cls, parser, interpreter, meta, app_data):\n        \"\"\"Add CLI arguments for the creator.\n\n        :param parser: the CLI parser\n        :param app_data: the application data folder\n        :param interpreter: the interpreter we're asked to create virtual environment for\n        :param meta: value as returned by :meth:`can_create`\n        \"\"\"\n        parser.add_argument(\n            \"dest\", help=\"directory to create virtualenv at\", type=cls.validate_dest,\n        )\n        parser.add_argument(\n            \"--clear\",\n            dest=\"clear\",\n            action=\"store_true\",\n            help=\"remove the destination directory if exist before starting (will overwrite files otherwise)\",\n            default=False,\n        )\n\n    @abstractmethod\n    def create(self):\n        \"\"\"Perform the virtual environment creation.\"\"\"\n        raise NotImplementedError\n\n    @classmethod\n    def validate_dest(cls, raw_value):\n        \"\"\"No path separator in the path, valid chars and must be write-able\"\"\"\n\n        def non_write_able(dest, value):\n            common = Path(*os.path.commonprefix([value.parts, dest.parts]))\n            raise ArgumentTypeError(\n                \"the destination {} is not write-able at {}\".format(dest.relative_to(common), common),\n            )\n\n        # the file system must be able to encode\n        # note in newer CPython this is always utf-8 https://www.python.org/dev/peps/pep-0529/\n        encoding = sys.getfilesystemencoding()\n        refused = OrderedDict()\n        kwargs = {\"errors\": \"ignore\"} if encoding != \"mbcs\" else {}\n        for char in ensure_text(raw_value):\n            try:\n                trip = char.encode(encoding, **kwargs).decode(encoding)\n                if trip == char:\n                    continue\n                raise ValueError(trip)\n            except ValueError:\n                refused[char] = None\n        if refused:\n            raise ArgumentTypeError(\n                \"the file system codec ({}) cannot handle characters {!r} within {!r}\".format(\n                    encoding, \"\".join(refused.keys()), raw_value,\n                ),\n            )\n        if os.pathsep in raw_value:\n            raise ArgumentTypeError(\n                \"destination {!r} must not contain the path separator ({}) as this would break \"\n                \"the activation scripts\".format(raw_value, os.pathsep),\n            )\n\n        value = Path(raw_value)\n        if value.exists() and value.is_file():\n            raise ArgumentTypeError(\"the destination {} already exists and is a file\".format(value))\n        if (3, 3) <= sys.version_info <= (3, 6):\n            # pre 3.6 resolve is always strict, aka must exists, sidestep by using os.path operation\n            dest = Path(os.path.realpath(raw_value))\n        else:\n            dest = Path(os.path.abspath(str(value))).resolve()  # on Windows absolute does not imply resolve so use both\n        value = dest\n        while dest:\n            if dest.exists():\n                if os.access(ensure_text(str(dest)), os.W_OK):\n                    break\n                else:\n                    non_write_able(dest, value)\n            base, _ = dest.parent, dest.name\n            if base == dest:\n                non_write_able(dest, value)  # pragma: no cover\n            dest = base\n        return str(value)\n\n    def run(self):\n        if self.dest.exists() and self.clear:\n            logging.debug(\"delete %s\", self.dest)\n            safe_delete(self.dest)\n        self.create()\n        self.set_pyenv_cfg()\n        self.setup_ignore_vcs()\n\n    def set_pyenv_cfg(self):\n        self.pyenv_cfg.content = OrderedDict()\n        self.pyenv_cfg[\"home\"] = self.interpreter.system_exec_prefix\n        self.pyenv_cfg[\"implementation\"] = self.interpreter.implementation\n        self.pyenv_cfg[\"version_info\"] = \".\".join(str(i) for i in self.interpreter.version_info)\n        self.pyenv_cfg[\"virtualenv\"] = __version__\n\n    def setup_ignore_vcs(self):\n        \"\"\"Generate ignore instructions for version control systems.\"\"\"\n        # mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs\n        (self.dest / \".gitignore\").write_text(\n            dedent(\n                \"\"\"\n                # created by virtualenv automatically\n                *\n                \"\"\",\n            ).lstrip(),\n        )\n        # Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the\n        # subinclude directive from root, at which point on might as well ignore the directory itself, see\n        # https://www.selenic.com/mercurial/hgignore.5.html for more details\n        # Bazaar - does not support ignore files in sub-directories, only at root level via .bzrignore\n        # Subversion - does not support ignore files, requires direct manipulation with the svn tool\n\n    @property\n    def debug(self):\n        \"\"\"\n        :return: debug information about the virtual environment (only valid after :meth:`create` has run)\n        \"\"\"\n        if self._debug is None and self.exe is not None:\n            self._debug = get_env_debug_info(self.exe, self.debug_script(), self.app_data)\n        return self._debug\n\n    # noinspection PyMethodMayBeStatic\n    def debug_script(self):\n        return DEBUG_SCRIPT\n\n\ndef get_env_debug_info(env_exe, debug_script, app_data):\n    env = os.environ.copy()\n    env.pop(str(\"PYTHONPATH\"), None)\n\n    with app_data.ensure_extracted(debug_script) as debug_script:\n        cmd = [str(env_exe), str(debug_script)]\n        if WIN_CPYTHON_2:\n            cmd = [ensure_text(i) for i in cmd]\n        logging.debug(str(\"debug via %r\"), LogCmd(cmd))\n        code, out, err = run_cmd(cmd)\n\n    # noinspection PyBroadException\n    try:\n        if code != 0:\n            result = literal_eval(out)\n        else:\n            result = json.loads(out)\n        if err:\n            result[\"err\"] = err\n    except Exception as exception:\n        return {\"out\": out, \"err\": err, \"returncode\": code, \"exception\": repr(exception)}\n    if \"sys\" in result and \"path\" in result[\"sys\"]:\n        del result[\"sys\"][\"path\"][0]\n    return result\n", "path": "src/virtualenv/create/creator.py"}], "after_files": [{"content": "from __future__ import absolute_import, print_function, unicode_literals\n\nimport json\nimport logging\nimport os\nimport sys\nfrom abc import ABCMeta, abstractmethod\nfrom argparse import ArgumentTypeError\nfrom ast import literal_eval\nfrom collections import OrderedDict\nfrom textwrap import dedent\n\nfrom six import add_metaclass\n\nfrom virtualenv.discovery.cached_py_info import LogCmd\nfrom virtualenv.info import WIN_CPYTHON_2\nfrom virtualenv.util.path import Path, safe_delete\nfrom virtualenv.util.six import ensure_str, ensure_text\nfrom virtualenv.util.subprocess import run_cmd\nfrom virtualenv.version import __version__\n\nfrom .pyenv_cfg import PyEnvCfg\n\nHERE = Path(os.path.abspath(__file__)).parent\nDEBUG_SCRIPT = HERE / \"debug.py\"\n\n\nclass CreatorMeta(object):\n    def __init__(self):\n        self.error = None\n\n\n@add_metaclass(ABCMeta)\nclass Creator(object):\n    \"\"\"A class that given a python Interpreter creates a virtual environment\"\"\"\n\n    def __init__(self, options, interpreter):\n        \"\"\"Construct a new virtual environment creator.\n\n        :param options: the CLI option as parsed from :meth:`add_parser_arguments`\n        :param interpreter: the interpreter to create virtual environment from\n        \"\"\"\n        self.interpreter = interpreter\n        self._debug = None\n        self.dest = Path(options.dest)\n        self.clear = options.clear\n        self.pyenv_cfg = PyEnvCfg.from_folder(self.dest)\n        self.app_data = options.app_data\n\n    def __repr__(self):\n        return ensure_str(self.__unicode__())\n\n    def __unicode__(self):\n        return \"{}({})\".format(self.__class__.__name__, \", \".join(\"{}={}\".format(k, v) for k, v in self._args()))\n\n    def _args(self):\n        return [\n            (\"dest\", ensure_text(str(self.dest))),\n            (\"clear\", self.clear),\n        ]\n\n    @classmethod\n    def can_create(cls, interpreter):\n        \"\"\"Determine if we can create a virtual environment.\n\n        :param interpreter: the interpreter in question\n        :return: ``None`` if we can't create, any other object otherwise that will be forwarded to \\\n                  :meth:`add_parser_arguments`\n        \"\"\"\n        return True\n\n    @classmethod\n    def add_parser_arguments(cls, parser, interpreter, meta, app_data):\n        \"\"\"Add CLI arguments for the creator.\n\n        :param parser: the CLI parser\n        :param app_data: the application data folder\n        :param interpreter: the interpreter we're asked to create virtual environment for\n        :param meta: value as returned by :meth:`can_create`\n        \"\"\"\n        parser.add_argument(\n            \"dest\", help=\"directory to create virtualenv at\", type=cls.validate_dest,\n        )\n        parser.add_argument(\n            \"--clear\",\n            dest=\"clear\",\n            action=\"store_true\",\n            help=\"remove the destination directory if exist before starting (will overwrite files otherwise)\",\n            default=False,\n        )\n\n    @abstractmethod\n    def create(self):\n        \"\"\"Perform the virtual environment creation.\"\"\"\n        raise NotImplementedError\n\n    @classmethod\n    def validate_dest(cls, raw_value):\n        \"\"\"No path separator in the path, valid chars and must be write-able\"\"\"\n\n        def non_write_able(dest, value):\n            common = Path(*os.path.commonprefix([value.parts, dest.parts]))\n            raise ArgumentTypeError(\n                \"the destination {} is not write-able at {}\".format(dest.relative_to(common), common),\n            )\n\n        # the file system must be able to encode\n        # note in newer CPython this is always utf-8 https://www.python.org/dev/peps/pep-0529/\n        encoding = sys.getfilesystemencoding()\n        refused = OrderedDict()\n        kwargs = {\"errors\": \"ignore\"} if encoding != \"mbcs\" else {}\n        for char in ensure_text(raw_value):\n            try:\n                trip = char.encode(encoding, **kwargs).decode(encoding)\n                if trip == char:\n                    continue\n                raise ValueError(trip)\n            except ValueError:\n                refused[char] = None\n        if refused:\n            raise ArgumentTypeError(\n                \"the file system codec ({}) cannot handle characters {!r} within {!r}\".format(\n                    encoding, \"\".join(refused.keys()), raw_value,\n                ),\n            )\n        if os.pathsep in raw_value:\n            raise ArgumentTypeError(\n                \"destination {!r} must not contain the path separator ({}) as this would break \"\n                \"the activation scripts\".format(raw_value, os.pathsep),\n            )\n\n        value = Path(raw_value)\n        if value.exists() and value.is_file():\n            raise ArgumentTypeError(\"the destination {} already exists and is a file\".format(value))\n        if (3, 3) <= sys.version_info <= (3, 6):\n            # pre 3.6 resolve is always strict, aka must exists, sidestep by using os.path operation\n            dest = Path(os.path.realpath(raw_value))\n        else:\n            dest = Path(os.path.abspath(str(value))).resolve()  # on Windows absolute does not imply resolve so use both\n        value = dest\n        while dest:\n            if dest.exists():\n                if os.access(ensure_text(str(dest)), os.W_OK):\n                    break\n                else:\n                    non_write_able(dest, value)\n            base, _ = dest.parent, dest.name\n            if base == dest:\n                non_write_able(dest, value)  # pragma: no cover\n            dest = base\n        return str(value)\n\n    def run(self):\n        if self.dest.exists() and self.clear:\n            logging.debug(\"delete %s\", self.dest)\n            safe_delete(self.dest)\n        self.create()\n        self.set_pyenv_cfg()\n        self.setup_ignore_vcs()\n\n    def set_pyenv_cfg(self):\n        self.pyenv_cfg.content = OrderedDict()\n        self.pyenv_cfg[\"home\"] = self.interpreter.system_exec_prefix\n        self.pyenv_cfg[\"implementation\"] = self.interpreter.implementation\n        self.pyenv_cfg[\"version_info\"] = \".\".join(str(i) for i in self.interpreter.version_info)\n        self.pyenv_cfg[\"virtualenv\"] = __version__\n\n    def setup_ignore_vcs(self):\n        \"\"\"Generate ignore instructions for version control systems.\"\"\"\n        # mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs\n        git_ignore = self.dest / \".gitignore\"\n        if not git_ignore.exists():\n            git_ignore.write_text(\n                dedent(\n                    \"\"\"\n                    # created by virtualenv automatically\n                    *\n                    \"\"\",\n                ).lstrip(),\n            )\n        # Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the\n        # subinclude directive from root, at which point on might as well ignore the directory itself, see\n        # https://www.selenic.com/mercurial/hgignore.5.html for more details\n        # Bazaar - does not support ignore files in sub-directories, only at root level via .bzrignore\n        # Subversion - does not support ignore files, requires direct manipulation with the svn tool\n\n    @property\n    def debug(self):\n        \"\"\"\n        :return: debug information about the virtual environment (only valid after :meth:`create` has run)\n        \"\"\"\n        if self._debug is None and self.exe is not None:\n            self._debug = get_env_debug_info(self.exe, self.debug_script(), self.app_data)\n        return self._debug\n\n    # noinspection PyMethodMayBeStatic\n    def debug_script(self):\n        return DEBUG_SCRIPT\n\n\ndef get_env_debug_info(env_exe, debug_script, app_data):\n    env = os.environ.copy()\n    env.pop(str(\"PYTHONPATH\"), None)\n\n    with app_data.ensure_extracted(debug_script) as debug_script:\n        cmd = [str(env_exe), str(debug_script)]\n        if WIN_CPYTHON_2:\n            cmd = [ensure_text(i) for i in cmd]\n        logging.debug(str(\"debug via %r\"), LogCmd(cmd))\n        code, out, err = run_cmd(cmd)\n\n    # noinspection PyBroadException\n    try:\n        if code != 0:\n            result = literal_eval(out)\n        else:\n            result = json.loads(out)\n        if err:\n            result[\"err\"] = err\n    except Exception as exception:\n        return {\"out\": out, \"err\": err, \"returncode\": code, \"exception\": repr(exception)}\n    if \"sys\" in result and \"path\" in result[\"sys\"]:\n        del result[\"sys\"][\"path\"][0]\n    return result\n", "path": "src/virtualenv/create/creator.py"}]}