Skip to content

Commit

Permalink
Check commits even with shallow clone of tags (#15023)
Browse files Browse the repository at this point in the history
* Check commits even with shallow clone of tags

Signed-off-by: John Sallay <jasallay@gmail.com>

* Fix unit test issues

Signed-off-by: John Sallay <jasallay@gmail.com>

* Add unit tests for git fetch functionality

* Update conans/test/functional/tools/scm/test_git.py

---------

Signed-off-by: John Sallay <jasallay@gmail.com>
Co-authored-by: James <memsharded@gmail.com>
  • Loading branch information
jsallay and memsharded authored Nov 5, 2023
1 parent bc24f92 commit fc8640d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 1 deletion.
13 changes: 12 additions & 1 deletion conan/tools/scm/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,23 @@ def commit_in_remote(self, commit, remote="origin"):
"""
if not remote:
return False
# Potentially do two checks here. If the clone is a shallow clone, then we won't be
# able to find the commit.
try:
branches = self.run("branch -r --contains {}".format(commit))
return "{}/".format(remote) in branches
if "{}/".format(remote) in branches:
return True
except Exception as e:
raise ConanException("Unable to check remote commit in '%s': %s" % (self.folder, str(e)))

try:
# This will raise if commit not present.
self.run("fetch {} --dry-run --depth=1 {}".format(remote, commit))
return True
except Exception as e:
# Don't raise an error because the fetch could fail for many more reasons than the branch.
return False

def is_dirty(self):
"""
Returns if the current folder is dirty, running ``git status -s``
Expand Down
72 changes: 72 additions & 0 deletions conans/test/functional/tools/scm/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,3 +889,75 @@ def set_version(self):
assert "pkg/1.2" in c.out
c.run("install --requires=pkg/1.2")
assert "pkg/1.2" in c.out


@pytest.mark.tool("git")
class TestGitShallowTagClone:
"""
When we do a shallow clone of a repo with a specific tag/branch, it doesn't
clone any of the git history. When we check to see if a commit is in the
repo, we fallback to a git fetch if we can't verify the commit locally.
"""
conanfile = textwrap.dedent("""
from conan import ConanFile
from conan.tools.scm import Git
class Pkg(ConanFile):
name = "pkg"
version = "0.1"
def export(self):
git = Git(self, self.recipe_folder)
commit = git.get_commit()
url = git.get_remote_url()
self.output.info("URL: {}".format(url))
self.output.info("COMMIT: {}".format(commit))
in_remote = git.commit_in_remote(commit)
self.output.info("COMMIT IN REMOTE: {}".format(in_remote))
self.output.info("DIRTY: {}".format(git.is_dirty()))
""")

def test_find_tag_in_remote(self):
"""
a shallow cloned repo won't have the new commit locally, but can fetch it.
"""
folder = temp_folder()
url, commit = create_local_git_repo(files={"conanfile.py": self.conanfile}, folder=folder)

c = TestClient()
# Create a tag
with c.chdir(folder):
c.run_command('git tag 1.0.0')

# Do a shallow clone of our tag
c.run_command('git clone --depth=1 --branch 1.0.0 "{}" myclone'.format(folder))
with c.chdir("myclone"):
c.run("export .")
assert "pkg/0.1: COMMIT: {}".format(commit) in c.out
assert "pkg/0.1: URL: {}".format(url) in c.out
assert "pkg/0.1: COMMIT IN REMOTE: True" in c.out
assert "pkg/0.1: DIRTY: False" in c.out

def test_detect_commit_not_in_remote(self):
"""
a shallow cloned repo won't have new commit in remote
"""
folder = temp_folder()
url, commit = create_local_git_repo(files={"conanfile.py": self.conanfile}, folder=folder)

c = TestClient()
# Create a tag
with c.chdir(folder):
c.run_command('git tag 1.0.0')

# Do a shallow clone of our tag
c.run_command('git clone --depth=1 --branch 1.0.0 "{}" myclone'.format(folder))
with c.chdir("myclone"):
c.save({"conanfile.py": self.conanfile + "\n# some coment!"})
new_commit = git_add_changes_commit(c.current_folder)

c.run("export .")
assert "pkg/0.1: COMMIT: {}".format(new_commit) in c.out
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

0 comments on commit fc8640d

Please sign in to comment.