We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Don't allow the `site_dir` to be within the `docs_dir`
This leads to the output being copied into the output during a build.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mkdocs/config.py`
Content:
```
1 # coding: utf-8
2 
3 from mkdocs import utils
4 from mkdocs.compat import urlparse
5 from mkdocs.exceptions import ConfigurationError
6 
7 import logging
8 import os
9 import yaml
10 
11 log = logging.getLogger(__name__)
12 
13 DEFAULT_CONFIG = {
14     'site_name': None,
15     'pages': None,
16 
17     'site_url': None,
18     'site_description': None,
19     'site_author': None,
20     'site_favicon': None,
21 
22     'theme': 'mkdocs',
23     'docs_dir': 'docs',
24     'site_dir': 'site',
25     'theme_dir': None,
26 
27     'copyright': None,
28     'google_analytics': None,
29 
30     # The address on which to serve the livereloading docs server.
31     'dev_addr': '127.0.0.1:8000',
32 
33     # If `True`, use `<page_name>/index.hmtl` style files with hyperlinks to the directory.
34     # If `False`, use `<page_name>.html style file with hyperlinks to the file.
35     # True generates nicer URLs, but False is useful if browsing the output on a filesystem.
36     'use_directory_urls': True,
37 
38     # Specify a link to the project source repo to be included
39     # in the documentation pages.
40     'repo_url': None,
41 
42     # A name to use for the link to the project source repo.
43     # Default: If repo_url is unset then None, otherwise
44     # "GitHub" or "Bitbucket" for known url or Hostname for unknown urls.
45     'repo_name': None,
46 
47     # Specify which css or javascript files from the docs
48     # directionary should be additionally included in the site.
49     # Default: List of all .css and .js files in the docs dir.
50     'extra_css': None,
51     'extra_javascript': None,
52 
53     # Determine if the site should include the nav and next/prev elements.
54     # Default: True if the site has more than one page, False otherwise.
55     'include_nav': None,
56     'include_next_prev': None,
57 
58     # PyMarkdown extension names.
59     'markdown_extensions': (),
60 
61     # Determine if the site should generate a json search index and include
62     # search elements in the theme. - TODO
63     'include_search': False,
64 
65     # Determine if the site should include a 404.html page.
66     # TODO: Implment this. Make this None, have it True if a 404.html
67     # template exists in the theme or docs dir.
68     'include_404': False,
69 
70     # enabling strict mode causes MkDocs to stop the build when a problem is
71     # encountered rather than display an error.
72     'strict': False,
73 }
74 
75 
76 def load_config(filename='mkdocs.yml', options=None):
77     options = options or {}
78     if 'config' in options:
79         filename = options.pop('config')
80     if not os.path.exists(filename):
81         raise ConfigurationError("Config file '%s' does not exist." % filename)
82     with open(filename, 'r') as fp:
83         user_config = yaml.load(fp)
84         if not isinstance(user_config, dict):
85             raise ConfigurationError("The mkdocs.yml file is invalid. See http://www.mkdocs.org/user-guide/configuration/ for more information.")
86     user_config.update(options)
87     return validate_config(user_config)
88 
89 
90 def validate_config(user_config):
91     config = DEFAULT_CONFIG.copy()
92 
93     theme_in_config = 'theme' in user_config
94 
95     config.update(user_config)
96 
97     if not config['site_name']:
98         raise ConfigurationError("Config must contain 'site_name' setting.")
99 
100     # If not specified, then the 'pages' config simply includes all
101     # markdown files in the docs dir, without generating any header items
102     # for them.
103     pages = []
104     extra_css = []
105     extra_javascript = []
106     for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):
107         for filename in sorted(filenames):
108             fullpath = os.path.join(dirpath, filename)
109             relpath = os.path.relpath(fullpath, config['docs_dir'])
110 
111             if utils.is_markdown_file(filename):
112                 # index pages should always be the first listed page.
113                 if os.path.splitext(relpath)[0] == 'index':
114                     pages.insert(0, relpath)
115                 else:
116                     pages.append(relpath)
117             elif utils.is_css_file(filename):
118                 extra_css.append(relpath)
119             elif utils.is_javascript_file(filename):
120                 extra_javascript.append(relpath)
121 
122     if config['pages'] is None:
123         config['pages'] = pages
124 
125     if config['extra_css'] is None:
126         config['extra_css'] = extra_css
127 
128     if config['extra_javascript'] is None:
129         config['extra_javascript'] = extra_javascript
130 
131     package_dir = os.path.dirname(__file__)
132     theme_dir = [os.path.join(package_dir, 'themes', config['theme'])]
133 
134     if config['theme_dir'] is not None:
135         # If the user has given us a custom theme but not a
136         # builtin theme name then we don't want to merge them.
137         if not theme_in_config:
138             theme_dir = []
139         theme_dir.insert(0, config['theme_dir'])
140 
141     config['theme_dir'] = theme_dir
142 
143     if config['repo_url'] is not None and config['repo_name'] is None:
144         repo_host = urlparse(config['repo_url']).netloc.lower()
145         if repo_host == 'github.com':
146             config['repo_name'] = 'GitHub'
147         elif repo_host == 'bitbucket.org':
148             config['repo_name'] = 'Bitbucket'
149         else:
150             config['repo_name'] = repo_host.split('.')[0].title()
151 
152     if config['include_next_prev'] is None:
153         config['include_next_prev'] = len(config['pages']) > 1
154 
155     if config['include_nav'] is None:
156         config['include_nav'] = len(config['pages']) > 1
157 
158     # To Do:
159 
160     # The docs dir must exist.
161     # The theme dir must exist.
162     # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'
163     # A homepage 'index' must exist.
164     # The theme 'base.html' file must exist.
165     # Cannot set repo_name without setting repo_url.
166     # Cannot set 'include_next_prev: true' when only one page exists.
167     # Cannot set 'include_nav: true' when only one page exists.
168     # Error if any config keys provided that are not in the DEFAULT_CONFIG.
169 
170     return config
171
```
--- 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/mkdocs/config.py b/mkdocs/config.py
--- a/mkdocs/config.py
+++ b/mkdocs/config.py
@@ -97,6 +97,18 @@
     if not config['site_name']:
         raise ConfigurationError("Config must contain 'site_name' setting.")
 
+    # Validate that the docs_dir and site_dir don't contain the
+    # other as this will lead to copying back and forth on each
+    # and eventually make a deep nested mess.
+    abs_site_dir = os.path.abspath(config['site_dir'])
+    abs_docs_dir = os.path.abspath(config['docs_dir'])
+    if abs_docs_dir.startswith(abs_site_dir):
+        raise ConfigurationError(
+            "The 'docs_dir' can't be within the 'site_dir'.")
+    elif abs_site_dir.startswith(abs_docs_dir):
+        raise ConfigurationError(
+            "The 'site_dir' can't be within the 'docs_dir'.")
+
     # If not specified, then the 'pages' config simply includes all
     # markdown files in the docs dir, without generating any header items
     # for them.

{"golden_diff": "diff --git a/mkdocs/config.py b/mkdocs/config.py\n--- a/mkdocs/config.py\n+++ b/mkdocs/config.py\n@@ -97,6 +97,18 @@\n     if not config['site_name']:\n         raise ConfigurationError(\"Config must contain 'site_name' setting.\")\n \n+    # Validate that the docs_dir and site_dir don't contain the\n+    # other as this will lead to copying back and forth on each\n+    # and eventually make a deep nested mess.\n+    abs_site_dir = os.path.abspath(config['site_dir'])\n+    abs_docs_dir = os.path.abspath(config['docs_dir'])\n+    if abs_docs_dir.startswith(abs_site_dir):\n+        raise ConfigurationError(\n+            \"The 'docs_dir' can't be within the 'site_dir'.\")\n+    elif abs_site_dir.startswith(abs_docs_dir):\n+        raise ConfigurationError(\n+            \"The 'site_dir' can't be within the 'docs_dir'.\")\n+\n     # If not specified, then the 'pages' config simply includes all\n     # markdown files in the docs dir, without generating any header items\n     # for them.\n", "issue": "Don't allow the `site_dir` to be within the `docs_dir`\nThis leads to the output being copied into the output during a build.\n\n", "before_files": [{"content": "# coding: utf-8\n\nfrom mkdocs import utils\nfrom mkdocs.compat import urlparse\nfrom mkdocs.exceptions import ConfigurationError\n\nimport logging\nimport os\nimport yaml\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_CONFIG = {\n    'site_name': None,\n    'pages': None,\n\n    'site_url': None,\n    'site_description': None,\n    'site_author': None,\n    'site_favicon': None,\n\n    'theme': 'mkdocs',\n    'docs_dir': 'docs',\n    'site_dir': 'site',\n    'theme_dir': None,\n\n    'copyright': None,\n    'google_analytics': None,\n\n    # The address on which to serve the livereloading docs server.\n    'dev_addr': '127.0.0.1:8000',\n\n    # If `True`, use `<page_name>/index.hmtl` style files with hyperlinks to the directory.\n    # If `False`, use `<page_name>.html style file with hyperlinks to the file.\n    # True generates nicer URLs, but False is useful if browsing the output on a filesystem.\n    'use_directory_urls': True,\n\n    # Specify a link to the project source repo to be included\n    # in the documentation pages.\n    'repo_url': None,\n\n    # A name to use for the link to the project source repo.\n    # Default: If repo_url is unset then None, otherwise\n    # \"GitHub\" or \"Bitbucket\" for known url or Hostname for unknown urls.\n    'repo_name': None,\n\n    # Specify which css or javascript files from the docs\n    # directionary should be additionally included in the site.\n    # Default: List of all .css and .js files in the docs dir.\n    'extra_css': None,\n    'extra_javascript': None,\n\n    # Determine if the site should include the nav and next/prev elements.\n    # Default: True if the site has more than one page, False otherwise.\n    'include_nav': None,\n    'include_next_prev': None,\n\n    # PyMarkdown extension names.\n    'markdown_extensions': (),\n\n    # Determine if the site should generate a json search index and include\n    # search elements in the theme. - TODO\n    'include_search': False,\n\n    # Determine if the site should include a 404.html page.\n    # TODO: Implment this. Make this None, have it True if a 404.html\n    # template exists in the theme or docs dir.\n    'include_404': False,\n\n    # enabling strict mode causes MkDocs to stop the build when a problem is\n    # encountered rather than display an error.\n    'strict': False,\n}\n\n\ndef load_config(filename='mkdocs.yml', options=None):\n    options = options or {}\n    if 'config' in options:\n        filename = options.pop('config')\n    if not os.path.exists(filename):\n        raise ConfigurationError(\"Config file '%s' does not exist.\" % filename)\n    with open(filename, 'r') as fp:\n        user_config = yaml.load(fp)\n        if not isinstance(user_config, dict):\n            raise ConfigurationError(\"The mkdocs.yml file is invalid. See http://www.mkdocs.org/user-guide/configuration/ for more information.\")\n    user_config.update(options)\n    return validate_config(user_config)\n\n\ndef validate_config(user_config):\n    config = DEFAULT_CONFIG.copy()\n\n    theme_in_config = 'theme' in user_config\n\n    config.update(user_config)\n\n    if not config['site_name']:\n        raise ConfigurationError(\"Config must contain 'site_name' setting.\")\n\n    # If not specified, then the 'pages' config simply includes all\n    # markdown files in the docs dir, without generating any header items\n    # for them.\n    pages = []\n    extra_css = []\n    extra_javascript = []\n    for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):\n        for filename in sorted(filenames):\n            fullpath = os.path.join(dirpath, filename)\n            relpath = os.path.relpath(fullpath, config['docs_dir'])\n\n            if utils.is_markdown_file(filename):\n                # index pages should always be the first listed page.\n                if os.path.splitext(relpath)[0] == 'index':\n                    pages.insert(0, relpath)\n                else:\n                    pages.append(relpath)\n            elif utils.is_css_file(filename):\n                extra_css.append(relpath)\n            elif utils.is_javascript_file(filename):\n                extra_javascript.append(relpath)\n\n    if config['pages'] is None:\n        config['pages'] = pages\n\n    if config['extra_css'] is None:\n        config['extra_css'] = extra_css\n\n    if config['extra_javascript'] is None:\n        config['extra_javascript'] = extra_javascript\n\n    package_dir = os.path.dirname(__file__)\n    theme_dir = [os.path.join(package_dir, 'themes', config['theme'])]\n\n    if config['theme_dir'] is not None:\n        # If the user has given us a custom theme but not a\n        # builtin theme name then we don't want to merge them.\n        if not theme_in_config:\n            theme_dir = []\n        theme_dir.insert(0, config['theme_dir'])\n\n    config['theme_dir'] = theme_dir\n\n    if config['repo_url'] is not None and config['repo_name'] is None:\n        repo_host = urlparse(config['repo_url']).netloc.lower()\n        if repo_host == 'github.com':\n            config['repo_name'] = 'GitHub'\n        elif repo_host == 'bitbucket.org':\n            config['repo_name'] = 'Bitbucket'\n        else:\n            config['repo_name'] = repo_host.split('.')[0].title()\n\n    if config['include_next_prev'] is None:\n        config['include_next_prev'] = len(config['pages']) > 1\n\n    if config['include_nav'] is None:\n        config['include_nav'] = len(config['pages']) > 1\n\n    # To Do:\n\n    # The docs dir must exist.\n    # The theme dir must exist.\n    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'\n    # A homepage 'index' must exist.\n    # The theme 'base.html' file must exist.\n    # Cannot set repo_name without setting repo_url.\n    # Cannot set 'include_next_prev: true' when only one page exists.\n    # Cannot set 'include_nav: true' when only one page exists.\n    # Error if any config keys provided that are not in the DEFAULT_CONFIG.\n\n    return config\n", "path": "mkdocs/config.py"}], "after_files": [{"content": "# coding: utf-8\n\nfrom mkdocs import utils\nfrom mkdocs.compat import urlparse\nfrom mkdocs.exceptions import ConfigurationError\n\nimport logging\nimport os\nimport yaml\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_CONFIG = {\n    'site_name': None,\n    'pages': None,\n\n    'site_url': None,\n    'site_description': None,\n    'site_author': None,\n    'site_favicon': None,\n\n    'theme': 'mkdocs',\n    'docs_dir': 'docs',\n    'site_dir': 'site',\n    'theme_dir': None,\n\n    'copyright': None,\n    'google_analytics': None,\n\n    # The address on which to serve the livereloading docs server.\n    'dev_addr': '127.0.0.1:8000',\n\n    # If `True`, use `<page_name>/index.hmtl` style files with hyperlinks to the directory.\n    # If `False`, use `<page_name>.html style file with hyperlinks to the file.\n    # True generates nicer URLs, but False is useful if browsing the output on a filesystem.\n    'use_directory_urls': True,\n\n    # Specify a link to the project source repo to be included\n    # in the documentation pages.\n    'repo_url': None,\n\n    # A name to use for the link to the project source repo.\n    # Default: If repo_url is unset then None, otherwise\n    # \"GitHub\" or \"Bitbucket\" for known url or Hostname for unknown urls.\n    'repo_name': None,\n\n    # Specify which css or javascript files from the docs\n    # directionary should be additionally included in the site.\n    # Default: List of all .css and .js files in the docs dir.\n    'extra_css': None,\n    'extra_javascript': None,\n\n    # Determine if the site should include the nav and next/prev elements.\n    # Default: True if the site has more than one page, False otherwise.\n    'include_nav': None,\n    'include_next_prev': None,\n\n    # PyMarkdown extension names.\n    'markdown_extensions': (),\n\n    # Determine if the site should generate a json search index and include\n    # search elements in the theme. - TODO\n    'include_search': False,\n\n    # Determine if the site should include a 404.html page.\n    # TODO: Implment this. Make this None, have it True if a 404.html\n    # template exists in the theme or docs dir.\n    'include_404': False,\n\n    # enabling strict mode causes MkDocs to stop the build when a problem is\n    # encountered rather than display an error.\n    'strict': False,\n}\n\n\ndef load_config(filename='mkdocs.yml', options=None):\n    options = options or {}\n    if 'config' in options:\n        filename = options.pop('config')\n    if not os.path.exists(filename):\n        raise ConfigurationError(\"Config file '%s' does not exist.\" % filename)\n    with open(filename, 'r') as fp:\n        user_config = yaml.load(fp)\n        if not isinstance(user_config, dict):\n            raise ConfigurationError(\"The mkdocs.yml file is invalid. See http://www.mkdocs.org/user-guide/configuration/ for more information.\")\n    user_config.update(options)\n    return validate_config(user_config)\n\n\ndef validate_config(user_config):\n    config = DEFAULT_CONFIG.copy()\n\n    theme_in_config = 'theme' in user_config\n\n    config.update(user_config)\n\n    if not config['site_name']:\n        raise ConfigurationError(\"Config must contain 'site_name' setting.\")\n\n    # Validate that the docs_dir and site_dir don't contain the\n    # other as this will lead to copying back and forth on each\n    # and eventually make a deep nested mess.\n    abs_site_dir = os.path.abspath(config['site_dir'])\n    abs_docs_dir = os.path.abspath(config['docs_dir'])\n    if abs_docs_dir.startswith(abs_site_dir):\n        raise ConfigurationError(\n            \"The 'docs_dir' can't be within the 'site_dir'.\")\n    elif abs_site_dir.startswith(abs_docs_dir):\n        raise ConfigurationError(\n            \"The 'site_dir' can't be within the 'docs_dir'.\")\n\n    # If not specified, then the 'pages' config simply includes all\n    # markdown files in the docs dir, without generating any header items\n    # for them.\n    pages = []\n    extra_css = []\n    extra_javascript = []\n    for (dirpath, dirnames, filenames) in os.walk(config['docs_dir']):\n        for filename in sorted(filenames):\n            fullpath = os.path.join(dirpath, filename)\n            relpath = os.path.relpath(fullpath, config['docs_dir'])\n\n            if utils.is_markdown_file(filename):\n                # index pages should always be the first listed page.\n                if os.path.splitext(relpath)[0] == 'index':\n                    pages.insert(0, relpath)\n                else:\n                    pages.append(relpath)\n            elif utils.is_css_file(filename):\n                extra_css.append(relpath)\n            elif utils.is_javascript_file(filename):\n                extra_javascript.append(relpath)\n\n    if config['pages'] is None:\n        config['pages'] = pages\n\n    if config['extra_css'] is None:\n        config['extra_css'] = extra_css\n\n    if config['extra_javascript'] is None:\n        config['extra_javascript'] = extra_javascript\n\n    package_dir = os.path.dirname(__file__)\n    theme_dir = [os.path.join(package_dir, 'themes', config['theme'])]\n\n    if config['theme_dir'] is not None:\n        # If the user has given us a custom theme but not a\n        # builtin theme name then we don't want to merge them.\n        if not theme_in_config:\n            theme_dir = []\n        theme_dir.insert(0, config['theme_dir'])\n\n    config['theme_dir'] = theme_dir\n\n    if config['repo_url'] is not None and config['repo_name'] is None:\n        repo_host = urlparse(config['repo_url']).netloc.lower()\n        if repo_host == 'github.com':\n            config['repo_name'] = 'GitHub'\n        elif repo_host == 'bitbucket.org':\n            config['repo_name'] = 'Bitbucket'\n        else:\n            config['repo_name'] = repo_host.split('.')[0].title()\n\n    if config['include_next_prev'] is None:\n        config['include_next_prev'] = len(config['pages']) > 1\n\n    if config['include_nav'] is None:\n        config['include_nav'] = len(config['pages']) > 1\n\n    # To Do:\n\n    # The docs dir must exist.\n    # The theme dir must exist.\n    # Ensure 'theme' is one of 'mkdocs', 'readthedocs', 'custom'\n    # A homepage 'index' must exist.\n    # The theme 'base.html' file must exist.\n    # Cannot set repo_name without setting repo_url.\n    # Cannot set 'include_next_prev: true' when only one page exists.\n    # Cannot set 'include_nav: true' when only one page exists.\n    # Error if any config keys provided that are not in the DEFAULT_CONFIG.\n\n    return config\n", "path": "mkdocs/config.py"}]}