1. Overview

Assigning the current Git branch name to a variable in a shell script is useful in various scenarios, especially in automating tasks related to software development, continuous integration, and deployment. It can help us introduce a conditional flow in our automated scripts, such as deploying to production only from the master or main branch.

In this tutorial, we’ll learn multiple ways to get the current Git branch name and assign that to a Bash variable.

2. Scenario Setup

To explore the use case of getting the current Git branch, we need a test bed to run the Git commands. So, let’s create the git_workspace directory where we’ll add a Git project:

$ mkdir -p git_workspace && cd git_workspace

Further, we can get started by cloning one of the open-source Git projects within the git_workspace directory. In our case, we’ll clone the Kubernetes project:

$ git clone https://github.com/kubernetes/kubernetes.git
Cloning into 'kubernetes'...
remote: Enumerating objects: 1473734, done.
remote: Counting objects: 100% (240/240), done.
remote: Compressing objects: 100% (137/137), done.
remote: Total 1473734 (delta 110), reused 162 (delta 94), pack-reused 1473494
Receiving objects: 100% (1473734/1473734), 959.83 MiB | 12.60 MiB/s, done.
Resolving deltas: 100% (1081314/1081314), done.
Updating files: 100% (24305/24305), done.

Next, let’s switch our current directory to the kubernetes directory so that we can run git commands:

$ cd kubernetes

Moving on, let’s create the dev/baeldung branch using the git checkout -b command so that we have at least two branches available locally:

$ git checkout -b dev/baeldung
Switched to a new branch 'dev/baeldung'

Lastly, let’s switch to the previous branch using the git checkout – command:

$ git checkout -
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

Great! We’re ready to try different approaches to solve our use case now.

3. Using git branch

The git branch command in Git helps us to manage branches in a Git repository.

In this section, let’s explore a few ways based on the git branch to get the current branch and assign it to a variable.

3.1. With –show-current Option

The –show-current option is the most straightforward and convenient way to get the current branch. However, it’s only available with Git  2.22.0 and onwards. So, let’s check the version before proceeding further:

$ git --version
git version 2.34.1

For legacy systems, the version could be older where we don’t have the –show-current option available. So, this validation is especially required if our script is required to run on a legacy server.

Next, let’s confirm that the –show-current option is giving us the correct branch name:

$ git branch --show-current
master

Lastly, we can use command substitution to store this value in the current_branch variable:

current_branch=$(git branch --show-current)

3.2. With grep

Alternatively, we can list down all the local branches using the git branch command:

$ git branch
  dev/baeldung
* master

The output shows an asterisk (*) before the current branch.

Now, let’s pipe this output to grep and filter out the remaining ones:

$ git branch | grep -oP '^\* \K.*'
master

We used the -o option with grep to output only the matched part from the input. We also add the -P option to use the \K feature in Perl-compatible regular expressions (PCRE).

Further, it’s worth noting that the \K flag resets the start of the reported match. Any text matched before the \K won’t be included in the final output. So, the asterisk (*) and a space after it are removed from the matched part.

Lastly, let’s assign the output to the current_branch variable:

current_branch=$(git branch | grep -oP '^\* \K.*')

3.3. With sed

Instead of filtering the branches with grep, we can also write a one-liner sed script:

$ git branch | sed -n -E 's/\* (.*)/\1/p'
master

We used the “*\* (.*)*” regular expression to match the line starting with an asterisk. Further, we applied substitution with grouping to replace the entire line with the first group (\1) from the regular expression.

Like earlier, let’s store this in the current_branch variable:

current_branch=$(git branch | sed -n -E 's/\* (.*)/\1/p')

That’s it!

3.4. With awk

Since the line containing the current branch name has a space as a separator between the asterisk (*) and the branch name, we can also use awk to get the current branch:

$ git branch | awk '/*/{print $2}'
master

We only print the second field ($2).

Again, let’s save it in the current_branch variable with command substitution:

$ current_branch=$(git branch | awk '/*/{print $2}')

Fantastic! This one was quite convenient.

3.5. With Parameter Expansion

We can also use parameter expansion to get the current branch. For this purpose, let’s start by assigning the output from the git branch command to the branches variable:

branches=$(git branch)

Now, we can get the current branch name from the branches variable in two steps:

Firstly, we must remove everything before the asterisk (*) and the space after the asterisk (*):

current_branch="${branches#*$'\n'\* }"

It’s important to note that we used # to remove the shortest match for the *$’\n\* ‘ pattern. Further, we used the special syntax, $’\n’  for newline, and escaped the asterisk (\*)to differentiate it from the wildcard pattern.

Secondly, from the latest value of current_branch, we must remove everything that falls after the branch name, including the newline character (\n) at the end of the current line:

current_branch="${current_branch%%$'\n'*}"

In this manipulation, we used %% to remove the longest match for the $’\n’* pattern.

Ultimately, the current branch name is available for use in the current_branch variable.

4. Using git rev-parse

We can use the git rev-parse command to parse and inspect the Git references. Let’s see how it can help us to get the current branch name.

4.1. With –abbrev-ref

Let’s start by using the git rev-parse command for HEAD, which is a reference for the current branch:

$ git rev-parse HEAD
fe6d64d080ab9b112b6a3b987e56835616ee4992

We see the commit reference in the output, which isn’t what we want.

However, by adding the –abbrev-ref option, we get an unambiguous name for the commit reference:

$ git rev-parse --abbrev-ref HEAD
master

It’s worth noting that for a Git branch, the unambiguous name for the HEAD pointer will always be its name.

Lastly, we can populate this value in the current_branch variable:

current_branch=$(git rev-parse --abbrev-ref HEAD)

Perfect! We got this one right.

5. Using git symbolic-ref

We can use the git symbolic-ref command to read, create, and modify symbolic references to Git references, such as branches and tags. Let’s use it to solve our use case of getting the current branch.

5.1. With –short

Internally, Git maintains files within the .git/ directory to keep track of symbolic references. Let’s see how Git tracks the HEAD reference within the .git/HEAD file:

$ cat .git/HEAD
ref: refs/heads/master

Moreover, if we change the branch, the contents of the .git/HEAD file will update accordingly:

$ git checkout dev/baeldung
Switched to branch 'dev/baeldung'
$ cat .git/HEAD
ref: refs/heads/dev/baeldung
$ git checkout - # switch back to original branch

Now, let’s execute the git symbolic-ref command for the HEAD reference to see its output:

$ git symbolic-ref HEAD
refs/heads/master

Interestingly, Git provides the –short option to retrieve the branch name mapped to a Git reference. So, let’s see this in action:

$ git symbolic-ref --short HEAD
master

Lastly, let’s save it in the current_branch variable:

current_branch=$(git symbolic-ref --short HEAD)

Great! It looks like we nailed this one.

6. Using git log

Using the git log command, we can get the commit history for the current checked-out branch. Moreover, we can add the –pretty=”%D” argument to show all the references for a commit:

$ git log -1 --pretty="%D"
HEAD -> master, origin/master, origin/HEAD, dev/baeldung

It’s important to note that we also added the -1 option to limit the output to the latest commit only. Further, the left-most entry in the list of references is the current branch.

Now, we can pipe the output from the git log command to a text extraction utility such as awk to get the branch name.

$ git log -1 --pretty="%D" | awk -F'[ ,]' '{print $3}'
master

We used the -F option to define space and comma as the possible delimiters. Then, we retrieved the branch name as the third field ($3).

Like earlier, we can now use command substitution to assign the output value to the current_branch variable:

$ current_branch=$(git log -1 --pretty="%D" | awk -F'[ ,]' '{print $3}')

7. Using git status

We can use the git status command to know about the current state of the working directory and staging area relative to the Git repository. Let’s use it to get the current branch and assign that to a variable.

7.1. With grep

Let’s see the output of the git status command:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

We can see that the first line of the output contains the branch name.

So, we can pipe this output to grep with the -o and -P options and retrieve the branch name:

$ git status | grep -oP '^On branch \K.*$'
master

We used the \K flag to remove the “On branch ” prefix from the matching string.

Lastly, let’s store this output in the current_branch variable:

$ current_branch=$(git status | grep -oP '^On branch \K.*$')

Great! We’ve solved our use case.

7.2. With Porcelain Format

Alternatively, we can use the –porcelain option to format the output of git status for getting a reliable machine-readable and script-friendly output:

$ git status --porcelain=v2 --branch
# branch.oid fe6d64d080ab9b112b6a3b987e56835616ee4992
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0

We can see metadata about the branch in the output, including the name of the branch against the branch.head field.

Now, we can pipe this output to a text extraction utility such as sed and get the value of the branch name:

$ git status --porcelain=v2 --branch | sed -n -E 's/^# branch\.head (.*)/\1/p'
master

We used group substitution to capture the branch name in the first group and used \1 for a backreference in the replacement string.

Lastly, let’s capture this value in the current_branch variable:

$ current_branch=$(git status --porcelain=v2 --branch | sed -n -E 's/^# branch\.head (.*)/\1/p')

Fantastic! It’s done.

8. Conclusion

In this article, we learned how to get the current branch name and assign it to a variable. While solving the use case, we explored different git sub-commands, such as git branch, git status, git log, git symbolic-ref, and git rev-parse.

Additionally, we combined the Git commands with a few other command-line utilities, such as sed, awk, and grep, for text matching and extraction purposes.