Repository: conan-io/conan (python)

Issue:
[bug] git remote parsing fails in treeless clones
### Describe the bug

When the local repository was cloned "treeless", then newer versions of git (tested with 2.43.0) add another token to the output of "git remote -v" that is then wrongly parsed in [conan/tools/scm/git.py#get_remote_url()](https://github.com/conan-io/conan/blob/8e0bca03824d7960a1668e65d274154347d93cde/conan/tools/scm/git.py#L72C9-L93)
because that code assumes that there are only three tokens in the output, not four.
As a result, the URL that is parsed from the output and "captured" via the `scm` attribute (for Conan 1.x) or presumably also `Git.coordinates_to_conandata()` (though I didn't test this) is invalid, because it contains the ` (fetch)` part of the output:
```
... Repo origin deduced by 'auto': https://github.com/google/googletest.git (fetch)
```

The use of treeless clones is quite common in CI systems, because it offers quick cloning that still allows branch and history inspection (unlike shallow clones).

Tested with conan 1.66.0, but the offending code seems equivalent in latest `develop2`.
(Apologies for only testing with 1.x but that's what I'm currently stuck with.)


A quick fix would be to change the `rsplit` into `split` in https://github.com/conan-io/conan/blob/develop2/conan/tools/scm/git.py, i.e.:
```
--- i/conan/tools/scm/git.py
+++ w/conan/tools/scm/git.py
@@ -87,7 +87,7 @@ class Git:
         for r in remotes.splitlines():
             name, url = r.split(maxsplit=1)
             if name == remote:
-                url, _ = url.rsplit(None, 1)
+                url, _ = url.split(None, 1)
                 if os.path.exists(url):  # Windows local directory
                     url = url.replace("\\", "/")
                 return url
```


### How to reproduce it

```
$ git --version
git version 2.43.0
$ git clone -q --filter=tree:0 --branch main https://github.com/google/googletest.git
$ git remote -v
origin  ssh://git@devstack.vwgroup.com:7999/e3swcdep/googletest.git (fetch) [tree:0]
origin  ssh://git@devstack.vwgroup.com:7999/e3swcdep/googletest.git (push)
```


Pull request description:
[fix] Add support for Git tree-less repository when getting the URL
Hello! :wave:

This PR addresses the reported bug #18415, when using a Git repository with the tree-less feature.

In the reported issue, it was commented to use `strip` instead of `rstrip` as originally designed in the PR #10594. That original PR has no explicit motivation of using `rstrip`, but it suggests when having a git URL which contains spaces (that's possible for local repositories), the `rstrip` will preserve all whitespace, but when using `strip`, it will cut the path on the first whitespace, which will be a bug. 

I added the test `test_treeless_clone` to exemplify the reported case. In case replacing `rsplit` by `split`, the test will fail due to the whitespace in the URL. 

~My suggested fix is to look for parentheses, because they are not valid in a URL (IINM), then remove that content from the URL.~

EDIT: Windows has C:/Program Files (x86) which will break in case only looking for parentheses as pointed by Memsharded. To improve the check, it will be better looking for explicit words (fetch) and (push) 

Changelog: Fix: Git.get_remote_url now returns only the URL when using treeless repository
Docs: Omit

fixes #18415

- [x] Refer to the issue that supports this Pull Request.
- [x] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop2/.github/CONTRIBUTING.md).
- [x] I've followed the PEP8 style guides for Python code.
- [ ] I've opened another PR in the Conan docs repo to the ``develop`` branch, documenting this one.


Patch:
diff --git a/conan/cli/commands/cache.py b/conan/cli/commands/cache.py
index 1f1240caf..52abdb58b 100644
--- a/conan/cli/commands/cache.py
+++ b/conan/cli/commands/cache.py
@@ -187,5 +187,6 @@ def cache_backup_upload(conan_api: ConanAPI, parser, subparser, *args):
     """
     Upload all the source backups present in the cache
     """
+    args = parser.parse_args(*args)
     files = conan_api.cache.get_backup_sources()
     conan_api.upload.upload_backup_sources(files)
diff --git a/conan/tools/scm/git.py b/conan/tools/scm/git.py
index 48ad9fe5d..190711e18 100644
--- a/conan/tools/scm/git.py
+++ b/conan/tools/scm/git.py
@@ -88,6 +88,9 @@ class Git:
             name, url = r.split(maxsplit=1)
             if name == remote:
                 url, _ = url.rsplit(None, 1)
+                # if the url still has (fetch) or (push) at the end
+                if url.endswith("(fetch)") or url.endswith("(push)"):
+                    url, _ = url.rsplit(None, 1)
                 if os.path.exists(url):  # Windows local directory
                     url = url.replace("\\", "/")
                 return url


Test patch:
diff --git a/test/functional/tools/scm/test_git.py b/test/functional/tools/scm/test_git.py
index 7e0a46d09..89f3c9a1d 100644
--- a/test/functional/tools/scm/test_git.py
+++ b/test/functional/tools/scm/test_git.py
@@ -1253,3 +1253,63 @@ class TestGitShallowTagClone:
             assert "pkg/0.1: URL: {}".format(url) in c.out
             assert "pkg/0.1: COMMIT IN REMOTE: False" in c.out
             assert "pkg/0.1: DIRTY: False" in c.out
+
+
+@pytest.mark.tool("git")
+class TestGitTreelessRemote:
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.scm import Git
+        import os
+
+        class Pkg(ConanFile):
+            name = "pkg"
+            version = "0.1"
+
+            def layout(self):
+                self.folders.source = "source"
+
+            def export(self):
+                git = Git(self)
+                git.clone(url="{url}", args=["--filter=tree:0"], target="target")
+                git.folder = "target"
+                cloned_url = git.run("remote -v")
+                self.output.info("git remote: %s ===" % cloned_url)
+                cloned_url = git.get_remote_url()
+                self.output.info("get_remote_url(): %s ===" % cloned_url)
+        """)
+
+    def test_treeless_clone(self):
+        """
+        When cloning a git repository with the `--filter=tree:0` option,
+        the Git.get_remote_url() should only the URL of the repository.
+
+        Validate the issue https://github.com/conan-io/conan/issues/18415
+        """
+        repository = temp_folder(path_with_spaces=False)
+        url, commit = create_local_git_repo(files={"README": "Lumen naturale ratum est"},
+                                            folder=repository)
+
+        client = TestClient()
+        client.save({"conanfile.py": self.conanfile.format(url=url)})
+        client.run("export .")
+        # We expect [tree:0] for regular git remote command. Requires Git +2.43
+        assert f"git remote: origin\t{url} (fetch) [tree:0]" in client.out
+        # Then get_remote_url filters it to only the URL
+        assert f"get_remote_url(): {url} ===" in client.out
+
+    def test_treeless_clone_with_parenthesis(self):
+        """
+        Windows can use C:\Program Files (x86) path, which contains parenthesis.
+        As the URL will have (fetch) or (push), get_remote_url() should be able to parse it.
+        """
+        repository = os.path.join(temp_folder(), "Program Files (x86)", "myrepo")
+        os.makedirs(repository)
+        url, commit = create_local_git_repo(files={"README": "Pacem in maribus."},
+                                            folder=repository)
+
+        client = TestClient()
+        client.save({"conanfile.py": self.conanfile.format(url=url)})
+        client.run("export .")
+        assert f"get_remote_url(): {url} ===" in client.out