diff --git a/crates/ubrn_cli/src/repo.rs b/crates/ubrn_cli/src/repo.rs index e38a82fe..e46a0252 100644 --- a/crates/ubrn_cli/src/repo.rs +++ b/crates/ubrn_cli/src/repo.rs @@ -79,21 +79,33 @@ impl GitRepoArgs { run_cmd(&mut cmd)?; } - // git ls-remote origin $branch + // git remote set-branches origin '*' to start tracking all branches and + // enable checking out branch names + let mut cmd = Command::new("git"); + cmd.current_dir(self.directory(project_root)?) + .arg("remote") + .arg("set-branches") + .arg("origin") + .arg("*"); + run_cmd(&mut cmd)?; + + // git ls-remote --tags origin $branch let output = Command::new("git") .current_dir(self.directory(project_root)?) .arg("ls-remote") + .arg("--tags") .arg("origin") .arg(&self.branch) .output()?; let output = String::from_utf8(output.stdout)?; - // Find $branch in the output and resolve the SHA or fall back to $branch - let branch_ref = format!("refs/heads/{}", &self.branch); + // Find $branch in the output and resolve the SHA or fall back to $branch. We + // deliberately don't resolve branch names to their SHAs because checking out + // with the SHA would cause a detached HEAD state. let tag_ref = format!("refs/tags/{}", &self.branch); let sha = output .lines() - .find(|line| line.ends_with(&branch_ref) || line.ends_with(&tag_ref)) + .find(|line| line.ends_with(&tag_ref)) .map(|line| { line.split_whitespace() .next() diff --git a/scripts/run-checkout-tests.sh b/scripts/run-checkout-tests.sh index 85b30a63..95267274 100755 --- a/scripts/run-checkout-tests.sh +++ b/scripts/run-checkout-tests.sh @@ -9,16 +9,34 @@ function clean_up { } function announce { - echo "[TEST] $1" + echo -e "\033[0;36m[TEST] $1\033[0m" } rc=0 function assert_eq { if [[ $1 == $2 ]]; then - echo "✅ OK" + echo "✅ OK: '$1' == '$2'" else - echo "❌ FAILURE: '$1' != '$2'" + echo "❌ FAILURE: '$1' == '$2'" + rc=1 + fi +} + +function assert_contains { + if [[ $1 == *$2* ]]; then + echo "✅ OK: contains '$2'" + else + echo "❌ FAILURE: contains '$2'" + rc=1 + fi +} + +function assert_does_not_contain { + if [[ $1 != *$2* ]]; then + echo "✅ OK: does not contain '$2'" + else + echo "❌ FAILURE: does not contain '$2'" rc=1 fi } @@ -26,33 +44,37 @@ function assert_eq { clean_up announce "checkout with default" -"$ubrn" checkout https://github.com/actions/checkout +stderr=$("$ubrn" checkout https://github.com/actions/checkout 2> >(tee /dev/stderr)) pushd rust_modules/checkout assert_eq $(git ls-remote --heads origin | grep refs/heads/main | cut -f1) $(git rev-parse HEAD) +assert_does_not_contain "$stderr" "detached HEAD" popd clean_up announce "checkout with branch" -"$ubrn" checkout https://github.com/actions/checkout --branch releases/v1 +stderr=$("$ubrn" checkout https://github.com/actions/checkout --branch releases/v1 2> >(tee /dev/stderr)) pushd rust_modules/checkout assert_eq $(git ls-remote --heads origin | grep refs/heads/releases/v1 | cut -f1) $(git rev-parse HEAD) +assert_does_not_contain "$stderr" "detached HEAD" popd clean_up announce "checkout with tag" -"$ubrn" checkout https://github.com/actions/checkout --branch v4.0.0 +stderr=$("$ubrn" checkout https://github.com/actions/checkout --branch v4.0.0 2> >(tee /dev/stderr)) pushd rust_modules/checkout assert_eq $(git ls-remote --tags origin | grep refs/tags/v4.0.0 | cut -f1) $(git rev-parse HEAD) +assert_contains "$stderr" "detached HEAD" popd clean_up announce "checkout with sha" -"$ubrn" checkout https://github.com/actions/checkout --branch c533a0a4cfc4962971818edcfac47a2899e69799 +stderr=$("$ubrn" checkout https://github.com/actions/checkout --branch c533a0a4cfc4962971818edcfac47a2899e69799 2> >(tee /dev/stderr)) pushd rust_modules/checkout assert_eq c533a0a4cfc4962971818edcfac47a2899e69799 $(git rev-parse HEAD) +assert_contains "$stderr" "detached HEAD" popd clean_up