We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[SCM] Inability to export (and create) when using the `scm` feature while the conanfile is in a subfolder
(Working with conan 1.61 on both OS X and Windows)

This issue is following the second part of the problem described in #3069.
Our workflow relies on the *conanfile.py* `scm` feature for revision auto-deduction. We don't place said *conanfile.py* at the root of the repository, but at *conan/conanfile.py* instead.

With this configuration, any attempt to run 

    cd $gitrepo
    conan export conan/ com/develop

Will fail with

> ERROR: Not a git repository

This seems to be because the folder containing the recipe is **not** the root of the repository (it does not contain the .git/ repository), yet its parent does.

Is hosting the recipe in subfolders supported by conan? It seemed to work well for our use case, until this issue.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conans/client/tools/scm.py`
Content:
```
1 import os
2 
3 import re
4 import subprocess
5 from six.moves.urllib.parse import urlparse, quote_plus
6 from subprocess import CalledProcessError, PIPE, STDOUT
7 
8 from conans.client.tools.env import no_op, environment_append
9 from conans.client.tools.files import chdir
10 from conans.errors import ConanException
11 from conans.util.files import decode_text, to_file_bytes
12 
13 
14 class Git(object):
15 
16     def __init__(self, folder=None, verify_ssl=True, username=None, password=None, force_english=True,
17                  runner=None):
18         self.folder = folder or os.getcwd()
19         if not os.path.exists(self.folder):
20             os.mkdir(self.folder)
21         self._verify_ssl = verify_ssl
22         self._force_eng = force_english
23         self._username = username
24         self._password = password
25         self._runner = runner
26 
27     def run(self, command):
28         command = "git %s" % command
29         with chdir(self.folder) if self.folder else no_op():
30             with environment_append({"LC_ALL": "en_US.UTF-8"}) if self._force_eng else no_op():
31                 if not self._runner:
32                     return subprocess.check_output(command, shell=True).decode().strip()
33                 else:
34                     return self._runner(command)
35 
36     def get_url_with_credentials(self, url):
37         if not self._username or not self._password:
38             return url
39         if urlparse(url).password:
40             return url
41 
42         user_enc = quote_plus(self._username)
43         pwd_enc = quote_plus(self._password)
44         url = url.replace("://", "://" + user_enc + ":" + pwd_enc + "@", 1)
45         return url
46 
47     def _configure_ssl_verify(self):
48         return self.run("config http.sslVerify %s" % ("true" if self._verify_ssl else "false"))
49 
50     def clone(self, url, branch=None):
51         url = self.get_url_with_credentials(url)
52         if os.path.exists(url):
53             url = url.replace("\\", "/")  # Windows local directory
54         if os.path.exists(self.folder) and os.listdir(self.folder):
55             if not branch:
56                 raise ConanException("The destination folder '%s' is not empty, "
57                                      "specify a branch to checkout (not a tag or commit) "
58                                      "or specify a 'subfolder' "
59                                      "attribute in the 'scm'" % self.folder)
60             output = self.run("init")
61             output += self._configure_ssl_verify()
62             output += self.run('remote add origin "%s"' % url)
63             output += self.run("fetch ")
64             output += self.run("checkout -t origin/%s" % branch)
65         else:
66             branch_cmd = "--branch %s" % branch if branch else ""
67             output = self.run('clone "%s" . %s' % (url, branch_cmd))
68             output += self._configure_ssl_verify()
69 
70         return output
71 
72     def checkout(self, element, submodule=None):
73         self._check_git_repo()
74         output = self.run('checkout "%s"' % element)
75 
76         if submodule:
77             if submodule == "shallow":
78                 output += self.run("submodule sync")
79                 output += self.run("submodule update --init")
80             elif submodule == "recursive":
81                 output += self.run("submodule sync --recursive")
82                 output += self.run("submodule update --init --recursive")
83             else:
84                 raise ConanException("Invalid 'submodule' attribute value in the 'scm'. "
85                                      "Unknown value '%s'. Allowed values: ['shallow', 'recursive']" % submodule)
86         # Element can be a tag, branch or commit
87         return output
88 
89     def excluded_files(self):
90         try:
91 
92             file_paths = [os.path.normpath(os.path.join(os.path.relpath(folder, self.folder), el)).replace("\\", "/")
93                           for folder, dirpaths, fs in os.walk(self.folder)
94                           for el in fs + dirpaths]
95             p = subprocess.Popen(['git', 'check-ignore', '--stdin'],
96                                  stdout=PIPE, stdin=PIPE, stderr=STDOUT, cwd=self.folder)
97             paths = to_file_bytes("\n".join(file_paths))
98             grep_stdout = decode_text(p.communicate(input=paths)[0])
99             tmp = grep_stdout.splitlines()
100         except CalledProcessError:
101             tmp = []
102         return tmp
103 
104     def get_remote_url(self, remote_name=None):
105         self._check_git_repo()
106         remote_name = remote_name or "origin"
107         try:
108             remotes = self.run("remote -v")
109             for remote in remotes.splitlines():
110                 try:
111                     name, url = remote.split(None, 1)
112                     url, _ = url.rsplit(None, 1)
113                     if name == remote_name:
114                         return url
115                 except Exception:
116                     pass
117         except subprocess.CalledProcessError:
118             pass
119         return None
120 
121     def get_commit(self):
122         self._check_git_repo()
123         try:
124             commit = self.run("rev-parse HEAD")
125             commit = commit.strip()
126             return commit
127         except Exception as e:
128             raise ConanException("Unable to get git commit from %s\n%s" % (self.folder, str(e)))
129 
130     get_revision = get_commit
131 
132     def _check_git_repo(self):
133         if not os.path.exists(os.path.join(self.folder, ".git")):
134             raise ConanException("Not a git repository")
135 
136     def get_branch(self):
137         self._check_git_repo()
138         try:
139             status = self.run("status -bs --porcelain")
140             # ## feature/scm_branch...myorigin/feature/scm_branch
141             branch = status.splitlines()[0].split("...")[0].strip("#").strip()
142             # Replace non alphanumeric
143             branch = re.sub('[^0-9a-zA-Z]+', '_', branch)
144             return branch
145         except Exception as e:
146             raise ConanException("Unable to get git branch from %s\n%s" % (self.folder, str(e)))
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/conans/client/tools/scm.py b/conans/client/tools/scm.py
--- a/conans/client/tools/scm.py
+++ b/conans/client/tools/scm.py
@@ -130,8 +130,10 @@
     get_revision = get_commit
 
     def _check_git_repo(self):
-        if not os.path.exists(os.path.join(self.folder, ".git")):
-            raise ConanException("Not a git repository")
+        try:
+            self.run("status")
+        except Exception:
+            raise ConanException("Not a valid git repository")
 
     def get_branch(self):
         self._check_git_repo()

{"golden_diff": "diff --git a/conans/client/tools/scm.py b/conans/client/tools/scm.py\n--- a/conans/client/tools/scm.py\n+++ b/conans/client/tools/scm.py\n@@ -130,8 +130,10 @@\n     get_revision = get_commit\n \n     def _check_git_repo(self):\n-        if not os.path.exists(os.path.join(self.folder, \".git\")):\n-            raise ConanException(\"Not a git repository\")\n+        try:\n+            self.run(\"status\")\n+        except Exception:\n+            raise ConanException(\"Not a valid git repository\")\n \n     def get_branch(self):\n         self._check_git_repo()\n", "issue": "[SCM] Inability to export (and create) when using the `scm` feature while the conanfile is in a subfolder\n(Working with conan 1.61 on both OS X and Windows)\r\n\r\nThis issue is following the second part of the problem described in #3069.\r\nOur workflow relies on the *conanfile.py* `scm` feature for revision auto-deduction. We don't place said *conanfile.py* at the root of the repository, but at *conan/conanfile.py* instead.\r\n\r\nWith this configuration, any attempt to run \r\n\r\n    cd $gitrepo\r\n    conan export conan/ com/develop\r\n\r\nWill fail with\r\n\r\n> ERROR: Not a git repository\r\n\r\nThis seems to be because the folder containing the recipe is **not** the root of the repository (it does not contain the .git/ repository), yet its parent does.\r\n\r\nIs hosting the recipe in subfolders supported by conan? It seemed to work well for our use case, until this issue.\n", "before_files": [{"content": "import os\n\nimport re\nimport subprocess\nfrom six.moves.urllib.parse import urlparse, quote_plus\nfrom subprocess import CalledProcessError, PIPE, STDOUT\n\nfrom conans.client.tools.env import no_op, environment_append\nfrom conans.client.tools.files import chdir\nfrom conans.errors import ConanException\nfrom conans.util.files import decode_text, to_file_bytes\n\n\nclass Git(object):\n\n    def __init__(self, folder=None, verify_ssl=True, username=None, password=None, force_english=True,\n                 runner=None):\n        self.folder = folder or os.getcwd()\n        if not os.path.exists(self.folder):\n            os.mkdir(self.folder)\n        self._verify_ssl = verify_ssl\n        self._force_eng = force_english\n        self._username = username\n        self._password = password\n        self._runner = runner\n\n    def run(self, command):\n        command = \"git %s\" % command\n        with chdir(self.folder) if self.folder else no_op():\n            with environment_append({\"LC_ALL\": \"en_US.UTF-8\"}) if self._force_eng else no_op():\n                if not self._runner:\n                    return subprocess.check_output(command, shell=True).decode().strip()\n                else:\n                    return self._runner(command)\n\n    def get_url_with_credentials(self, url):\n        if not self._username or not self._password:\n            return url\n        if urlparse(url).password:\n            return url\n\n        user_enc = quote_plus(self._username)\n        pwd_enc = quote_plus(self._password)\n        url = url.replace(\"://\", \"://\" + user_enc + \":\" + pwd_enc + \"@\", 1)\n        return url\n\n    def _configure_ssl_verify(self):\n        return self.run(\"config http.sslVerify %s\" % (\"true\" if self._verify_ssl else \"false\"))\n\n    def clone(self, url, branch=None):\n        url = self.get_url_with_credentials(url)\n        if os.path.exists(url):\n            url = url.replace(\"\\\\\", \"/\")  # Windows local directory\n        if os.path.exists(self.folder) and os.listdir(self.folder):\n            if not branch:\n                raise ConanException(\"The destination folder '%s' is not empty, \"\n                                     \"specify a branch to checkout (not a tag or commit) \"\n                                     \"or specify a 'subfolder' \"\n                                     \"attribute in the 'scm'\" % self.folder)\n            output = self.run(\"init\")\n            output += self._configure_ssl_verify()\n            output += self.run('remote add origin \"%s\"' % url)\n            output += self.run(\"fetch \")\n            output += self.run(\"checkout -t origin/%s\" % branch)\n        else:\n            branch_cmd = \"--branch %s\" % branch if branch else \"\"\n            output = self.run('clone \"%s\" . %s' % (url, branch_cmd))\n            output += self._configure_ssl_verify()\n\n        return output\n\n    def checkout(self, element, submodule=None):\n        self._check_git_repo()\n        output = self.run('checkout \"%s\"' % element)\n\n        if submodule:\n            if submodule == \"shallow\":\n                output += self.run(\"submodule sync\")\n                output += self.run(\"submodule update --init\")\n            elif submodule == \"recursive\":\n                output += self.run(\"submodule sync --recursive\")\n                output += self.run(\"submodule update --init --recursive\")\n            else:\n                raise ConanException(\"Invalid 'submodule' attribute value in the 'scm'. \"\n                                     \"Unknown value '%s'. Allowed values: ['shallow', 'recursive']\" % submodule)\n        # Element can be a tag, branch or commit\n        return output\n\n    def excluded_files(self):\n        try:\n\n            file_paths = [os.path.normpath(os.path.join(os.path.relpath(folder, self.folder), el)).replace(\"\\\\\", \"/\")\n                          for folder, dirpaths, fs in os.walk(self.folder)\n                          for el in fs + dirpaths]\n            p = subprocess.Popen(['git', 'check-ignore', '--stdin'],\n                                 stdout=PIPE, stdin=PIPE, stderr=STDOUT, cwd=self.folder)\n            paths = to_file_bytes(\"\\n\".join(file_paths))\n            grep_stdout = decode_text(p.communicate(input=paths)[0])\n            tmp = grep_stdout.splitlines()\n        except CalledProcessError:\n            tmp = []\n        return tmp\n\n    def get_remote_url(self, remote_name=None):\n        self._check_git_repo()\n        remote_name = remote_name or \"origin\"\n        try:\n            remotes = self.run(\"remote -v\")\n            for remote in remotes.splitlines():\n                try:\n                    name, url = remote.split(None, 1)\n                    url, _ = url.rsplit(None, 1)\n                    if name == remote_name:\n                        return url\n                except Exception:\n                    pass\n        except subprocess.CalledProcessError:\n            pass\n        return None\n\n    def get_commit(self):\n        self._check_git_repo()\n        try:\n            commit = self.run(\"rev-parse HEAD\")\n            commit = commit.strip()\n            return commit\n        except Exception as e:\n            raise ConanException(\"Unable to get git commit from %s\\n%s\" % (self.folder, str(e)))\n\n    get_revision = get_commit\n\n    def _check_git_repo(self):\n        if not os.path.exists(os.path.join(self.folder, \".git\")):\n            raise ConanException(\"Not a git repository\")\n\n    def get_branch(self):\n        self._check_git_repo()\n        try:\n            status = self.run(\"status -bs --porcelain\")\n            # ## feature/scm_branch...myorigin/feature/scm_branch\n            branch = status.splitlines()[0].split(\"...\")[0].strip(\"#\").strip()\n            # Replace non alphanumeric\n            branch = re.sub('[^0-9a-zA-Z]+', '_', branch)\n            return branch\n        except Exception as e:\n            raise ConanException(\"Unable to get git branch from %s\\n%s\" % (self.folder, str(e)))\n", "path": "conans/client/tools/scm.py"}], "after_files": [{"content": "import os\n\nimport re\nimport subprocess\nfrom six.moves.urllib.parse import urlparse, quote_plus\nfrom subprocess import CalledProcessError, PIPE, STDOUT\n\nfrom conans.client.tools.env import no_op, environment_append\nfrom conans.client.tools.files import chdir\nfrom conans.errors import ConanException\nfrom conans.util.files import decode_text, to_file_bytes\n\n\nclass Git(object):\n\n    def __init__(self, folder=None, verify_ssl=True, username=None, password=None, force_english=True,\n                 runner=None):\n        self.folder = folder or os.getcwd()\n        if not os.path.exists(self.folder):\n            os.mkdir(self.folder)\n        self._verify_ssl = verify_ssl\n        self._force_eng = force_english\n        self._username = username\n        self._password = password\n        self._runner = runner\n\n    def run(self, command):\n        command = \"git %s\" % command\n        with chdir(self.folder) if self.folder else no_op():\n            with environment_append({\"LC_ALL\": \"en_US.UTF-8\"}) if self._force_eng else no_op():\n                if not self._runner:\n                    return subprocess.check_output(command, shell=True).decode().strip()\n                else:\n                    return self._runner(command)\n\n    def get_url_with_credentials(self, url):\n        if not self._username or not self._password:\n            return url\n        if urlparse(url).password:\n            return url\n\n        user_enc = quote_plus(self._username)\n        pwd_enc = quote_plus(self._password)\n        url = url.replace(\"://\", \"://\" + user_enc + \":\" + pwd_enc + \"@\", 1)\n        return url\n\n    def _configure_ssl_verify(self):\n        return self.run(\"config http.sslVerify %s\" % (\"true\" if self._verify_ssl else \"false\"))\n\n    def clone(self, url, branch=None):\n        url = self.get_url_with_credentials(url)\n        if os.path.exists(url):\n            url = url.replace(\"\\\\\", \"/\")  # Windows local directory\n        if os.path.exists(self.folder) and os.listdir(self.folder):\n            if not branch:\n                raise ConanException(\"The destination folder '%s' is not empty, \"\n                                     \"specify a branch to checkout (not a tag or commit) \"\n                                     \"or specify a 'subfolder' \"\n                                     \"attribute in the 'scm'\" % self.folder)\n            output = self.run(\"init\")\n            output += self._configure_ssl_verify()\n            output += self.run('remote add origin \"%s\"' % url)\n            output += self.run(\"fetch \")\n            output += self.run(\"checkout -t origin/%s\" % branch)\n        else:\n            branch_cmd = \"--branch %s\" % branch if branch else \"\"\n            output = self.run('clone \"%s\" . %s' % (url, branch_cmd))\n            output += self._configure_ssl_verify()\n\n        return output\n\n    def checkout(self, element, submodule=None):\n        self._check_git_repo()\n        output = self.run('checkout \"%s\"' % element)\n\n        if submodule:\n            if submodule == \"shallow\":\n                output += self.run(\"submodule sync\")\n                output += self.run(\"submodule update --init\")\n            elif submodule == \"recursive\":\n                output += self.run(\"submodule sync --recursive\")\n                output += self.run(\"submodule update --init --recursive\")\n            else:\n                raise ConanException(\"Invalid 'submodule' attribute value in the 'scm'. \"\n                                     \"Unknown value '%s'. Allowed values: ['shallow', 'recursive']\" % submodule)\n        # Element can be a tag, branch or commit\n        return output\n\n    def excluded_files(self):\n        try:\n\n            file_paths = [os.path.normpath(os.path.join(os.path.relpath(folder, self.folder), el)).replace(\"\\\\\", \"/\")\n                          for folder, dirpaths, fs in os.walk(self.folder)\n                          for el in fs + dirpaths]\n            p = subprocess.Popen(['git', 'check-ignore', '--stdin'],\n                                 stdout=PIPE, stdin=PIPE, stderr=STDOUT, cwd=self.folder)\n            paths = to_file_bytes(\"\\n\".join(file_paths))\n            grep_stdout = decode_text(p.communicate(input=paths)[0])\n            tmp = grep_stdout.splitlines()\n        except CalledProcessError:\n            tmp = []\n        return tmp\n\n    def get_remote_url(self, remote_name=None):\n        self._check_git_repo()\n        remote_name = remote_name or \"origin\"\n        try:\n            remotes = self.run(\"remote -v\")\n            for remote in remotes.splitlines():\n                try:\n                    name, url = remote.split(None, 1)\n                    url, _ = url.rsplit(None, 1)\n                    if name == remote_name:\n                        return url\n                except Exception:\n                    pass\n        except subprocess.CalledProcessError:\n            pass\n        return None\n\n    def get_commit(self):\n        self._check_git_repo()\n        try:\n            commit = self.run(\"rev-parse HEAD\")\n            commit = commit.strip()\n            return commit\n        except Exception as e:\n            raise ConanException(\"Unable to get git commit from %s\\n%s\" % (self.folder, str(e)))\n\n    get_revision = get_commit\n\n    def _check_git_repo(self):\n        try:\n            self.run(\"status\")\n        except Exception:\n            raise ConanException(\"Not a valid git repository\")\n\n    def get_branch(self):\n        self._check_git_repo()\n        try:\n            status = self.run(\"status -bs --porcelain\")\n            # ## feature/scm_branch...myorigin/feature/scm_branch\n            branch = status.splitlines()[0].split(\"...\")[0].strip(\"#\").strip()\n            # Replace non alphanumeric\n            branch = re.sub('[^0-9a-zA-Z]+', '_', branch)\n            return branch\n        except Exception as e:\n            raise ConanException(\"Unable to get git branch from %s\\n%s\" % (self.folder, str(e)))\n", "path": "conans/client/tools/scm.py"}]}