diff --git a/easybuild/tools/filetools.py b/easybuild/tools/filetools.py index 366f7b87fc..91f32613dd 100644 --- a/easybuild/tools/filetools.py +++ b/easybuild/tools/filetools.py @@ -2821,7 +2821,9 @@ def get_source_tarball_from_git(filename, target_dir, git_config): # Ensure URL is also processed correctly by tools that don't collapse double slashes url = url.rstrip('/') - clone_cmd.append(f'{url}/{repo_name}.git') + repo_url = f'{url}/{repo_name}.git' + + clone_cmd.append(repo_url) if clone_into: clone_cmd.append(clone_into) @@ -2841,6 +2843,10 @@ def get_source_tarball_from_git(filename, target_dir, git_config): # if a specific commit is asked for, check it out if commit: checkout_cmd.append(f"{commit}") + # The commit might not be reachable from the default branch that is fetched, so fetch it explicitely + # Only works for long commit hashes + if len(commit) == 40: + run_shell_cmd(f'{git_cmd} fetch {repo_url}', hidden=True, verbose_dry_run=True, work_dir=tmpdir) elif tag: checkout_cmd.append(f"refs/tags/{tag}") diff --git a/test/framework/filetools.py b/test/framework/filetools.py index 5da4f55cc9..fa72f09993 100644 --- a/test/framework/filetools.py +++ b/test/framework/filetools.py @@ -3166,16 +3166,31 @@ def run_check(): del git_config['extra_config_params'] del git_config['tag'] + git_config['commit'] = '90366eac4408c5d615d69c5444ed784734b167c8' + string_args['commit'] = git_config['commit'] + expected = '\n'.join([ + r' running command "git clone --no-checkout %(git_repo)s"', + r" \(in .*/tmp.*\)", + r' running command "git fetch %(git_repo)s %(commit)s"', + r" \(in testrepository\)", + r' running command "git checkout %(commit)s && git submodule update --init --recursive"', + r" \(in testrepository\)", + r' running command "tar cfvz .*/target/test.tar.gz --exclude .git testrepository"', + r" \(in .*/tmp.*\)", + ]) % string_args + run_check() + + # clone & fetch does not work for short hashes git_config['commit'] = '8456f86' + string_args['commit'] = git_config['commit'] expected = '\n'.join([ r' running shell command "git clone --no-checkout {git_repo}"', r" \(in .*/tmp.*\)", - r' running shell command "git checkout 8456f86"', - r" \(in .*/{repo_name}\)", - r' running shell command "git submodule update --init --recursive"', - r" \(in .*/{repo_name}\)", - r"Archiving '.*/{repo_name}' into '{test_prefix}/target/test.tar.xz'...", - ]).format(**string_args, repo_name='testrepository') + r' running command "git checkout %(commit)s && git submodule update --init --recursive"', + r" \(in testrepository\)", + r' running command "tar cfvz .*/target/test.tar.gz --exclude .git testrepository"', + r" \(in .*/tmp.*\)", + ]) % string_args run_check() git_config['recurse_submodules'] = ['!vcflib', '!sdsl-lite'] @@ -3263,18 +3278,15 @@ def run_check(): self.assertFalse(os.path.isdir(os.path.join(extracted_repo_dir, '.git'))) del git_config['tag'] - git_config['commit'] = '90366ea' - res = ft.get_source_tarball_from_git('test2', target_dir, git_config) - test_file = os.path.join(target_dir, 'test2.tar.xz') - self.assertEqual(res, test_file) - self.assertTrue(os.path.isfile(test_file)) - test_tar_files.append(os.path.basename(test_file)) - self.assertCountEqual(sorted(os.listdir(target_dir)), test_tar_files) - extracted_dir = tempfile.mkdtemp(prefix='extracted_dir') - with self.mocked_stdout_stderr(): - extracted_repo_dir = ft.extract_file(test_file, extracted_dir, change_into_dir=False) - self.assertTrue(os.path.isfile(os.path.join(extracted_repo_dir, 'README.md'))) - self.assertFalse(os.path.isdir(os.path.join(extracted_repo_dir, '.git'))) + test_tar_gzs = [] + for i, commit in enumerate(['90366eac4408c5d615d69c5444ed784734b167c8', '90366ea']): + git_config['commit'] = commit + test_file = os.path.join(target_dir, 'test2-%s.tar.gz' % i) + res = ft.get_source_tarball_from_git(os.path.basename(test_file), target_dir, git_config) + self.assertEqual(res, test_file) + self.assertTrue(os.path.isfile(test_file)) + test_tar_gzs.append(os.path.basename(test_file)) + self.assertEqual(sorted(os.listdir(target_dir)), test_tar_gzs) git_config['keep_git_dir'] = True res = ft.get_source_tarball_from_git('test3', target_dir, git_config)