We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix the repo regex to handle + in URLs
The documentation said that you could do git+https:// or git+ssh:// but that was not, in fact, true.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cookiecutter/main.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 
4 """
5 cookiecutter.main
6 -----------------
7 
8 Main entry point for the `cookiecutter` command.
9 
10 The code in this module is also a good example of how to use Cookiecutter as a
11 library rather than a script.
12 """
13 
14 from __future__ import unicode_literals
15 import logging
16 import os
17 import re
18 
19 from .config import get_user_config, USER_CONFIG_PATH
20 from .exceptions import InvalidModeException, RepositoryNotFound
21 from .prompt import prompt_for_config
22 from .generate import generate_context, generate_files
23 from .vcs import clone
24 from .replay import dump, load
25 
26 logger = logging.getLogger(__name__)
27 
28 builtin_abbreviations = {
29     'gh': 'https://github.com/{0}.git',
30     'bb': 'https://bitbucket.org/{0}',
31 }
32 
33 REPO_REGEX = """
34 (
35 ((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.
36  |                              # or
37  (\w+@[\w\.]+)                  # something like user@...
38 )
39 .*
40 """
41 
42 
43 def is_repo_url(value):
44     """Return True if value is a repository URL."""
45     return bool(re.match(REPO_REGEX, value, re.VERBOSE))
46 
47 
48 def expand_abbreviations(template, config_dict):
49     """
50     Expand abbreviations in a template name.
51 
52     :param template: The project template name.
53     :param config_dict: The user config, which will contain abbreviation
54         definitions.
55     """
56 
57     abbreviations = builtin_abbreviations.copy()
58     abbreviations.update(config_dict.get('abbreviations', {}))
59 
60     if template in abbreviations:
61         return abbreviations[template]
62 
63     # Split on colon. If there is no colon, rest will be empty
64     # and prefix will be the whole template
65     prefix, sep, rest = template.partition(':')
66     if prefix in abbreviations:
67         return abbreviations[prefix].format(rest)
68 
69     return template
70 
71 
72 def cookiecutter(
73         template, checkout=None, no_input=False, extra_context=None,
74         replay=False, overwrite_if_exists=False, output_dir='.',
75         config_file=USER_CONFIG_PATH):
76     """
77     API equivalent to using Cookiecutter at the command line.
78 
79     :param template: A directory containing a project template directory,
80         or a URL to a git repository.
81     :param checkout: The branch, tag or commit ID to checkout after clone.
82     :param no_input: Prompt the user at command line for manual configuration?
83     :param extra_context: A dictionary of context that overrides default
84         and user configuration.
85     :param: overwrite_if_exists: Overwrite the contents of output directory
86         if it exists
87     :param output_dir: Where to output the generated project dir into.
88     :param config_file: User configuration file path.
89     """
90     if replay and ((no_input is not False) or (extra_context is not None)):
91         err_msg = (
92             "You can not use both replay and no_input or extra_context "
93             "at the same time."
94         )
95         raise InvalidModeException(err_msg)
96 
97     # Get user config from ~/.cookiecutterrc or equivalent
98     # If no config file, sensible defaults from config.DEFAULT_CONFIG are used
99     config_dict = get_user_config(config_file=config_file)
100 
101     template = expand_abbreviations(template, config_dict)
102 
103     if is_repo_url(template):
104         repo_dir = clone(
105             repo_url=template,
106             checkout=checkout,
107             clone_to_dir=config_dict['cookiecutters_dir'],
108             no_input=no_input
109         )
110     else:
111         # If it's a local repo, no need to clone or copy to your
112         # cookiecutters_dir
113         repo_dir = template
114 
115     if not os.path.isdir(repo_dir):
116         raise RepositoryNotFound(
117             'The repository {0} could not be located.'.format(template)
118         )
119 
120     template_name = os.path.basename(template)
121 
122     if replay:
123         context = load(config_dict['replay_dir'], template_name)
124     else:
125         context_file = os.path.join(repo_dir, 'cookiecutter.json')
126         logging.debug('context_file is {0}'.format(context_file))
127 
128         context = generate_context(
129             context_file=context_file,
130             default_context=config_dict['default_context'],
131             extra_context=extra_context,
132         )
133 
134         # prompt the user to manually configure at the command line.
135         # except when 'no-input' flag is set
136         context['cookiecutter'] = prompt_for_config(context, no_input)
137 
138         dump(config_dict['replay_dir'], template_name, context)
139 
140     # Create project from local context and project template.
141     return generate_files(
142         repo_dir=repo_dir,
143         context=context,
144         overwrite_if_exists=overwrite_if_exists,
145         output_dir=output_dir
146     )
147
```
--- 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/cookiecutter/main.py b/cookiecutter/main.py
--- a/cookiecutter/main.py
+++ b/cookiecutter/main.py
@@ -30,19 +30,18 @@
     'bb': 'https://bitbucket.org/{0}',
 }
 
-REPO_REGEX = """
-(
-((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.
- |                              # or
- (\w+@[\w\.]+)                  # something like user@...
+REPO_REGEX = re.compile(r"""
+(?x)
+((((git|hg)\+)?(git|ssh|https?):(//)?)  # something like git:// ssh:// etc.
+ |                                      # or
+ (\w+@[\w\.]+)                          # something like user@...
 )
-.*
-"""
+""")
 
 
 def is_repo_url(value):
     """Return True if value is a repository URL."""
-    return bool(re.match(REPO_REGEX, value, re.VERBOSE))
+    return bool(REPO_REGEX.match(value))
 
 
 def expand_abbreviations(template, config_dict):

{"golden_diff": "diff --git a/cookiecutter/main.py b/cookiecutter/main.py\n--- a/cookiecutter/main.py\n+++ b/cookiecutter/main.py\n@@ -30,19 +30,18 @@\n     'bb': 'https://bitbucket.org/{0}',\n }\n \n-REPO_REGEX = \"\"\"\n-(\n-((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.\n- |                              # or\n- (\\w+@[\\w\\.]+)                  # something like user@...\n+REPO_REGEX = re.compile(r\"\"\"\n+(?x)\n+((((git|hg)\\+)?(git|ssh|https?):(//)?)  # something like git:// ssh:// etc.\n+ |                                      # or\n+ (\\w+@[\\w\\.]+)                          # something like user@...\n )\n-.*\n-\"\"\"\n+\"\"\")\n \n \n def is_repo_url(value):\n     \"\"\"Return True if value is a repository URL.\"\"\"\n-    return bool(re.match(REPO_REGEX, value, re.VERBOSE))\n+    return bool(REPO_REGEX.match(value))\n \n \n def expand_abbreviations(template, config_dict):\n", "issue": "Fix the repo regex to handle + in URLs\nThe documentation said that you could do git+https:// or git+ssh:// but that was not, in fact, true.\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.main\n-----------------\n\nMain entry point for the `cookiecutter` command.\n\nThe code in this module is also a good example of how to use Cookiecutter as a\nlibrary rather than a script.\n\"\"\"\n\nfrom __future__ import unicode_literals\nimport logging\nimport os\nimport re\n\nfrom .config import get_user_config, USER_CONFIG_PATH\nfrom .exceptions import InvalidModeException, RepositoryNotFound\nfrom .prompt import prompt_for_config\nfrom .generate import generate_context, generate_files\nfrom .vcs import clone\nfrom .replay import dump, load\n\nlogger = logging.getLogger(__name__)\n\nbuiltin_abbreviations = {\n    'gh': 'https://github.com/{0}.git',\n    'bb': 'https://bitbucket.org/{0}',\n}\n\nREPO_REGEX = \"\"\"\n(\n((git|ssh|https|http):(//)?)    # something like git:// ssh:// etc.\n |                              # or\n (\\w+@[\\w\\.]+)                  # something like user@...\n)\n.*\n\"\"\"\n\n\ndef is_repo_url(value):\n    \"\"\"Return True if value is a repository URL.\"\"\"\n    return bool(re.match(REPO_REGEX, value, re.VERBOSE))\n\n\ndef expand_abbreviations(template, config_dict):\n    \"\"\"\n    Expand abbreviations in a template name.\n\n    :param template: The project template name.\n    :param config_dict: The user config, which will contain abbreviation\n        definitions.\n    \"\"\"\n\n    abbreviations = builtin_abbreviations.copy()\n    abbreviations.update(config_dict.get('abbreviations', {}))\n\n    if template in abbreviations:\n        return abbreviations[template]\n\n    # Split on colon. If there is no colon, rest will be empty\n    # and prefix will be the whole template\n    prefix, sep, rest = template.partition(':')\n    if prefix in abbreviations:\n        return abbreviations[prefix].format(rest)\n\n    return template\n\n\ndef cookiecutter(\n        template, checkout=None, no_input=False, extra_context=None,\n        replay=False, overwrite_if_exists=False, output_dir='.',\n        config_file=USER_CONFIG_PATH):\n    \"\"\"\n    API equivalent to using Cookiecutter at the command line.\n\n    :param template: A directory containing a project template directory,\n        or a URL to a git repository.\n    :param checkout: The branch, tag or commit ID to checkout after clone.\n    :param no_input: Prompt the user at command line for manual configuration?\n    :param extra_context: A dictionary of context that overrides default\n        and user configuration.\n    :param: overwrite_if_exists: Overwrite the contents of output directory\n        if it exists\n    :param output_dir: Where to output the generated project dir into.\n    :param config_file: User configuration file path.\n    \"\"\"\n    if replay and ((no_input is not False) or (extra_context is not None)):\n        err_msg = (\n            \"You can not use both replay and no_input or extra_context \"\n            \"at the same time.\"\n        )\n        raise InvalidModeException(err_msg)\n\n    # Get user config from ~/.cookiecutterrc or equivalent\n    # If no config file, sensible defaults from config.DEFAULT_CONFIG are used\n    config_dict = get_user_config(config_file=config_file)\n\n    template = expand_abbreviations(template, config_dict)\n\n    if is_repo_url(template):\n        repo_dir = clone(\n            repo_url=template,\n            checkout=checkout,\n            clone_to_dir=config_dict['cookiecutters_dir'],\n            no_input=no_input\n        )\n    else:\n        # If it's a local repo, no need to clone or copy to your\n        # cookiecutters_dir\n        repo_dir = template\n\n    if not os.path.isdir(repo_dir):\n        raise RepositoryNotFound(\n            'The repository {0} could not be located.'.format(template)\n        )\n\n    template_name = os.path.basename(template)\n\n    if replay:\n        context = load(config_dict['replay_dir'], template_name)\n    else:\n        context_file = os.path.join(repo_dir, 'cookiecutter.json')\n        logging.debug('context_file is {0}'.format(context_file))\n\n        context = generate_context(\n            context_file=context_file,\n            default_context=config_dict['default_context'],\n            extra_context=extra_context,\n        )\n\n        # prompt the user to manually configure at the command line.\n        # except when 'no-input' flag is set\n        context['cookiecutter'] = prompt_for_config(context, no_input)\n\n        dump(config_dict['replay_dir'], template_name, context)\n\n    # Create project from local context and project template.\n    return generate_files(\n        repo_dir=repo_dir,\n        context=context,\n        overwrite_if_exists=overwrite_if_exists,\n        output_dir=output_dir\n    )\n", "path": "cookiecutter/main.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ncookiecutter.main\n-----------------\n\nMain entry point for the `cookiecutter` command.\n\nThe code in this module is also a good example of how to use Cookiecutter as a\nlibrary rather than a script.\n\"\"\"\n\nfrom __future__ import unicode_literals\nimport logging\nimport os\nimport re\n\nfrom .config import get_user_config, USER_CONFIG_PATH\nfrom .exceptions import InvalidModeException, RepositoryNotFound\nfrom .prompt import prompt_for_config\nfrom .generate import generate_context, generate_files\nfrom .vcs import clone\nfrom .replay import dump, load\n\nlogger = logging.getLogger(__name__)\n\nbuiltin_abbreviations = {\n    'gh': 'https://github.com/{0}.git',\n    'bb': 'https://bitbucket.org/{0}',\n}\n\nREPO_REGEX = re.compile(r\"\"\"\n(?x)\n((((git|hg)\\+)?(git|ssh|https?):(//)?)  # something like git:// ssh:// etc.\n |                                      # or\n (\\w+@[\\w\\.]+)                          # something like user@...\n)\n\"\"\")\n\n\ndef is_repo_url(value):\n    \"\"\"Return True if value is a repository URL.\"\"\"\n    return bool(REPO_REGEX.match(value))\n\n\ndef expand_abbreviations(template, config_dict):\n    \"\"\"\n    Expand abbreviations in a template name.\n\n    :param template: The project template name.\n    :param config_dict: The user config, which will contain abbreviation\n        definitions.\n    \"\"\"\n\n    abbreviations = builtin_abbreviations.copy()\n    abbreviations.update(config_dict.get('abbreviations', {}))\n\n    if template in abbreviations:\n        return abbreviations[template]\n\n    # Split on colon. If there is no colon, rest will be empty\n    # and prefix will be the whole template\n    prefix, sep, rest = template.partition(':')\n    if prefix in abbreviations:\n        return abbreviations[prefix].format(rest)\n\n    return template\n\n\ndef cookiecutter(\n        template, checkout=None, no_input=False, extra_context=None,\n        replay=False, overwrite_if_exists=False, output_dir='.',\n        config_file=USER_CONFIG_PATH):\n    \"\"\"\n    API equivalent to using Cookiecutter at the command line.\n\n    :param template: A directory containing a project template directory,\n        or a URL to a git repository.\n    :param checkout: The branch, tag or commit ID to checkout after clone.\n    :param no_input: Prompt the user at command line for manual configuration?\n    :param extra_context: A dictionary of context that overrides default\n        and user configuration.\n    :param: overwrite_if_exists: Overwrite the contents of output directory\n        if it exists\n    :param output_dir: Where to output the generated project dir into.\n    :param config_file: User configuration file path.\n    \"\"\"\n    if replay and ((no_input is not False) or (extra_context is not None)):\n        err_msg = (\n            \"You can not use both replay and no_input or extra_context \"\n            \"at the same time.\"\n        )\n        raise InvalidModeException(err_msg)\n\n    # Get user config from ~/.cookiecutterrc or equivalent\n    # If no config file, sensible defaults from config.DEFAULT_CONFIG are used\n    config_dict = get_user_config(config_file=config_file)\n\n    template = expand_abbreviations(template, config_dict)\n\n    if is_repo_url(template):\n        repo_dir = clone(\n            repo_url=template,\n            checkout=checkout,\n            clone_to_dir=config_dict['cookiecutters_dir'],\n            no_input=no_input\n        )\n    else:\n        # If it's a local repo, no need to clone or copy to your\n        # cookiecutters_dir\n        repo_dir = template\n\n    if not os.path.isdir(repo_dir):\n        raise RepositoryNotFound(\n            'The repository {0} could not be located.'.format(template)\n        )\n\n    template_name = os.path.basename(template)\n\n    if replay:\n        context = load(config_dict['replay_dir'], template_name)\n    else:\n        context_file = os.path.join(repo_dir, 'cookiecutter.json')\n        logging.debug('context_file is {0}'.format(context_file))\n\n        context = generate_context(\n            context_file=context_file,\n            default_context=config_dict['default_context'],\n            extra_context=extra_context,\n        )\n\n        # prompt the user to manually configure at the command line.\n        # except when 'no-input' flag is set\n        context['cookiecutter'] = prompt_for_config(context, no_input)\n\n        dump(config_dict['replay_dir'], template_name, context)\n\n    # Create project from local context and project template.\n    return generate_files(\n        repo_dir=repo_dir,\n        context=context,\n        overwrite_if_exists=overwrite_if_exists,\n        output_dir=output_dir\n    )\n", "path": "cookiecutter/main.py"}]}