0

I'm trying to make a git alias that shows branch names and descriptions. There is no dedicated command or switch to get the description of a branch; it must be sussed from configuration. However I want to get a list of all branches and their descriptions (if they have one).

One can get a sort of "raw data" like so:

$ git config -l
core.symlinks=false
core.autocrlf=false
core.fscache=true
color.diff=auto

So the entries that I'm interested in look like this:

branch.featureA.description=Mail templates
branch.featureB.description=Something else

Which I can get with this pipeline: git config -l | grep description | grep \^branch. For my desired output, I want this:

featureA Mail templates
featureB Something else

So one way to express this is that I want the second "column" after the period, and the first "column" after the equal sign. Or, I want .branchname. and .description= removed. I'm not sure the best way to go, but I tried using awk to treat the string as columns. I can get part of what I want with different delimiters:

$ git config -l | grep description | grep \^branch. | awk -F '.' '{ print $2 }'
featureA
featureB

$ git config -l | grep description | grep \^branch. | awk -F '=' '{ print $2 }'
Mail Templates
Something else

However trying to combine the two delimiters doesn't seem to work:

$ git config -l | grep description | grep \^branch. | awk -F '.=' '{ print $2 }'
Mail templates
Something else

How can I parse the data I want out of the string?

3 Answers 3

2

I would probably use sed for this:

sed -n '/^branch/{ s/[^.]*\.//; s/\.[^=]*=/ /p; }'

This catches any line starting with the string branch and for each of those lines

  1. deletes everything up to and including the first dot, then
  2. replaces everything from the first remaining dot up to and including the first = character with a space.

The modified line is then printed. Any other line is discarded.


With awk:

awk -F '=' '/^branch/ { split($1, a, "."); print a[2], $2 }'

This treats the input as delimited by the = and then splits the first part on dots. It then prints the second dot-delimited string and the bit after the =.

This would fail if the line contains more than one = (the bit after the second = would be lost).

2

Here's another way to do it with sed:

git config -l | sed -n 's/^branch[.]\(.*\)[.]description=/\1 /p'

Explanation: prints all lines of the form "branch.(something).description=(something)", with just a space between the (something)s. The -n keeps it from auto-printing the lines that don't match this pattern.

0

You can do this with bash:

while IFS="=" read key value; do 
    if [[ key == branch.*.description ]]; then
        branch=${key#branch.}        # remove "branch." prefix
        branch=${key%.description}   # remove ".description" suffix
        echo "$branch $value" 
    fi
done < <(git config -l)

I purposely "split" the line twice: first on equal then on dots. The "value" clearly can have dots in it, so I want full control over the word splitting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.