Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the name of the current git branch into a variable in a shell script? [duplicate]

I am new to shell scripting and can't figure this out. If you are unfamiliar, the command git branch returns something like

* develop   master 

, where the asterisk marks the currently checked out branch. When I run the following in the terminal:

git branch | grep "*" 

I get:

* develop 

as expected.

However, when I run

test=$(git branch | grep "*") 

or

test=`git branch | grep "*"` 

And then

echo $test 

, the result is just a list of files in the directory. How do we make the value of test="* develop"?

Then the next step (once we get "* develop" into a variable called test), is to get the substring. Would that just be the following?

currentBranch=${test:2}  

I was playing around with that substring function and I got "bad substitution" errors a lot and don't know why.

like image 722
Ben Avatar asked Jan 21 '10 16:01

Ben


People also ask

What is $_ in shell script?

$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.

What is $@ in bash script?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.

Which command rename the current branch to?

The git branch command lets you rename a branch. To rename a branch, run git branch -m <old> <new>. “old” is the name of the branch you want to rename and “new” is the new name for the branch.


2 Answers

The * is expanded, what you can do is use sed instead of grep and get the name of the branch immediately:

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

And a version using git symbolic-ref, as suggested by Noufal Ibrahim

branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,') 

To elaborate on the expansion, (as marco already did,) the expansion happens in the echo, when you do echo $test with $test containing * master then the * is expanded according to the normal expansion rules. To suppress this one would have to quote the variable, as shown by marco: echo "$test". Alternatively, if you get rid of the asterisk before you echo it, all will be fine, e.g. echo ${test:2} will just echo master. Alternatively you could assign it anew as you already proposed:

branch=${test:2} echo $branch 

This will echo master, like you wanted.

like image 68
wich Avatar answered Sep 27 '22 19:09

wich


Expanding on Noufal Ibrahim's answer, use the --short flag with git-symbolic-ref, no need to fuss with sed.

I've been using something like this in hooks and it works well:

#!/bin/bash  branch=$(git symbolic-ref --short HEAD)  echo echo "**** Running post-commit hook from branch $branch" echo 

That outputs "**** Running post-commit hook from branch master"

Note that git-symbolic-ref only works if you're in a repository. Luckily .git/HEAD, as a leftover from Git's early days, contains the same symbolic ref. If you want to get the active branch of several git repositories, without traversing directories, you could use a bash one-liner like this:

for repo in */.git; do branch=$(cat $repo/HEAD); echo ${repo%/.git} :  ${branch##*/}; done 

Which outputs something like:

repo1 : master   repo2 : dev   repo3 : issue12 

If you want to go further, the full ref contained in .git/HEAD is also a relative path to a file containing the SHA-1 hash of the branch's last commit.

like image 39
joemaller Avatar answered Sep 27 '22 19:09

joemaller