Skip to content
Git Basics: Build an Explicit Local Branch Inventory

Git Basics: Build an Explicit Local Branch Inventory

October 28, 2026

A script can list branches with a stable field selection instead of parsing the human-oriented branch display. for-each-ref also lets you restrict the namespace being inspected.

Prepare a scratch directory

Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need Bash, a text editor, the named runtime, and standard mktemp, rm, and rmdir utilities. The examples use only controlled local data; generated fixture directories are cleaned automatically.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as demonstrate-for-each-ref.sh:

#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author'
export GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_AUTHOR_DATE='2026-10-28T00:00:00+00:00'
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git init -q -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config commit.gpgsign false
git config core.hooksPath /dev/null
git commit -qm 'Base snapshot' --allow-empty
git branch topic
git tag v1
git switch -q topic
git commit -qm 'Topic snapshot' --allow-empty
printf 'Branch inventory:\n'
git for-each-ref --sort=refname --format='%(refname:short)|%(objecttype)|%(subject)' refs/heads/
printf 'Tag inventory:\n'
git for-each-ref --sort=refname --format='%(refname:short)' refs/tags/
test "$(git for-each-ref --format='%(refname)' refs/heads/ | wc -l)" -eq 2

Run it:

bash demonstrate-for-each-ref.sh

Observed output:

Branch inventory:
main|commit|Base snapshot
topic|commit|Topic snapshot
Tag inventory:
v1

Read the result

refs/heads selects local branches, while refs/tags selects tags. Sorting by full ref name gives a repeatable order. The branch records expose the short ref name, target object type, and commit subject without including transient terminal decorations.

Apply it carefully

The vertical bar is only a convenient display delimiter for these controlled subjects. Arbitrary commit text can contain delimiters; choose an appropriate machine-safe format before parsing untrusted metadata. This local inventory does not contact a remote or refresh tracking refs. Run this script from an ordinary shell with no repository-selection variables such as GIT_DIR or GIT_WORK_TREE set. All commits and cleanup stay inside the newly created temporary fixture.

The official reference describes the behavior and options. These checks cover the fixture above rather than every input or platform.

Clean up

Remove the saved source, return to the starting directory, then remove the empty practice directory:

rm -- demonstrate-for-each-ref.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect its remaining contents rather than deleting unknown files.

Acknowledgements

This post was created with assistance from AI.

Last updated on