How actions/checkout Determines the Default Branch to Checkout
When the ref input is omitted, actions/checkout queries the GitHub REST API to retrieve the repository's configured default branch and normalizes it to a full Git reference.
The actions/checkout action automatically resolves which branch to clone when your workflow doesn't specify a particular ref or commit SHA. This default branch detection logic is implemented in TypeScript and involves specific API calls to GitHub's REST API.
Detecting Missing Ref or Commit Inputs
The decision to look up the default branch occurs in the downloadRepository function within src/github-api-helper.ts. At lines 28-33, the code checks whether both the ref and commit parameters are undefined.
If neither value is present, the action logs "Determining the default branch" and calls getDefaultBranch to resolve the repository's primary branch. This ensures that the API lookup only happens when absolutely necessary, avoiding unnecessary requests for workflows that explicitly target a specific commit or branch.
Querying the GitHub API for the Default Branch
The getDefaultBranch function (lines 84-126 in src/github-api-helper.ts) handles the actual API communication. It creates an authenticated Octokit client and calls the GitHub REST API endpoint GET /repos/{owner}/{repo}.
The function extracts the default_branch field from the API response and asserts that it is non-empty. If the field is missing or empty, the action throws an error to fail the workflow. This value (e.g., main or master) is then passed through normalization logic to ensure it is a valid Git reference.
Handling the Wiki Repository Edge Case
Special logic exists for GitHub Wiki repositories. If the API request returns a 404 error and the repository name ends with .wiki, the action automatically falls back to using master as the default branch. This fallback is implemented within getDefaultBranch to accommodate the different default branch conventions historically used by GitHub Wikis.
Normalizing the Branch Reference
Before passing the resolved value to the archive-download routine, the action ensures the branch name is a full Git reference. At lines 121-124 of src/github-api-helper.ts, the code prefixes the branch name with refs/heads/ unless it already contains a full ref path.
The resulting string (e.g., refs/heads/main) is then used to fetch the tarball or zip archive for that specific branch, or passed to the Git checkout process depending on the repository configuration.
Complete Workflow Examples
The following examples demonstrate how the default branch detection behaves in practice.
Basic workflow relying on automatic detection:
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # no `ref` supplied → default branch is used
- run: echo "Checked out $(git rev-parse --abbrev-ref HEAD)"
Explicitly overriding the default branch:
steps:
- uses: actions/checkout@v4
with:
ref: develop # forces checkout of `develop` instead of the repo's default
Inspecting which ref was actually used:
steps:
- uses: actions/checkout@v4
id: checkout
- run: |
echo "Resolved ref: ${{ steps.checkout.outputs.ref }}"
git rev-parse --verify HEAD
Implementation Context
The default branch determination flows through several key files in the repository:
src/github-api-helper.ts– Contains the core logic indownloadRepository(lines 28-33) andgetDefaultBranch(lines 84-126)src/git-source-provider.ts– Orchestrates the checkout flow and triggers the API helper when neededsrc/main.ts– Entry point that parses inputs fromaction.ymland initiates the checkout process
This architecture ensures that actions/checkout respects your repository's GitHub settings while providing flexible override options through workflow inputs.
Summary
- actions/checkout determines the default branch by querying the GitHub API when the
refinput is omitted - The detection logic resides in
downloadRepositoryat lines 28-33 ofsrc/github-api-helper.ts - The API call to
GET /repos/{owner}/{repo}happens ingetDefaultBranch(lines 84-126) - Wiki repositories ending in
.wikifall back tomasterif the API returns a 404 error - The resolved reference is prefixed with
refs/heads/to ensure valid Git reference format
Frequently Asked Questions
What happens if I don't specify a ref in actions/checkout?
When you omit the ref input, the action automatically queries the GitHub API to discover your repository's default branch (usually main or master). It then checks out that branch at the latest commit. This behavior is implemented in src/github-api-helper.ts within the getDefaultBranch function.
How does actions/checkout handle wiki repositories?
For repositories ending in .wiki, if the GitHub API returns a 404 error when fetching repository metadata, the action falls back to using master as the default branch. This special case exists in src/github-api-helper.ts to handle the different default branch conventions historically used by GitHub Wikis.
Can I see which branch was actually checked out?
Yes. The action exposes the resolved reference through the ref output. You can access this value using ${{ steps.checkout.outputs.ref }} after giving the checkout step an ID. Additionally, you can run git rev-parse --abbrev-ref HEAD to verify the current branch name in subsequent steps.
What API endpoint does actions/checkout use to find the default branch?
The action uses the GitHub REST API endpoint GET /repos/{owner}/{repo} via the Octokit client. It reads the default_branch field from the response, which is then normalized to a full Git reference by prepending refs/heads/. This logic is contained in the getDefaultBranch function in src/github-api-helper.ts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →