Home > Blockchain >  how to rename multiple git branches into lowercase using bash
how to rename multiple git branches into lowercase using bash

Time:06-02

I want to rename multiple branches in lowercase, as before migration we have to convert all uppercase branches to lowercase. git branch:

CPORT_121

GC_211

Lower-Upper_DEMO

Now I tried the below one but it is not working.

git branch | tr A-Z a-z | xargs -n 2 git branch -m

error: refname refs/heads/cport_121 not found
fatal: Branch rename failed
fatal: '*' is not a valid branch name.

CodePudding user response:

This is the wrong way to code the loop. (Your checkout loop in the comments is also not really the right way to go.) For script purposes we should use git for-each-ref whenever possible, and here it's entirely possible. We would start with this, if we want to create local branch names for each refs/remotes/origin/* remote-tracking name that needs renaming:

git for-each-ref \
  --format="%(if)%(symref)%(then)%(else)%(refname:strip=3)%(end)" \
  refs/remotes/origin | sed '/^$/d' > /tmp/branchlist

This creates a file (/tmp/branchlist) containing all the remote-tracking names. The if/then/else/end sequence drops the HEAD symbolic ref and the sed cleans out the corresponding blank line (not strictly necessary, but useful).

Some of these branch names might already be fine! We probably don't want to fuss with those. So now we can grep for uppercase:

LC_ALL=C grep -E '^[A-Z] $' /tmp/branchlist > /tmp/upper

The LC_ALL here is necessary in case your grep uses POSIX collation (mine does on at least some systems).

It's now probably wise to inspect /tmp/upper to make sure that none of the names in it also appear as lowercase in /tmp/branchlist. This is a one-time manual operation, but you can automate it if you like:

tr A-Z a-z < /tmp/upper | grep -F -f - /tmp/branchlist

Note that this will erroneously match substrings, e.g., if there's a "bad" name OOPS and a "good" name whoops, this will find the "good" name even though it's different; fixing that is harder and I won't bother.

We now want to create, in our local repository, one lowercase-name branch whose name matches the uppercase name:

awk '{ print "git branch --no-track " tolower($0) " refs/remotes/origin/" $0 }' \
  < /tmp/upper

Make sure this generates the desired commands and then pipe into sh:

awk '{ print "git branch --no-track " tolower($0) " refs/remotes/origin/" $0 }' \
  < /tmp/upper | sh

and we've generated the desired branch names.

Rather than creating such branch names, though, it makes more sense to me to run a git push command that creates the names directly on the remote.

To do that, we want:

git push origin

followed by a series of local remote-tracking names and the desired branch names: for each uppercase name, we want a lowercase-ified version of that name as a branch name. So that would be:

(printf "git push origin"
awk '{ printf(" %s:%s", "refs/remotes/origin/" $0, "refs/heads/" tolower($0)) }' \
  < /tmp/upper
echo "")

Verify that this produces the desired git push command, then pipe to sh.

You may wish to git push --delete the uppercase-only names later; it should now be obvious how to do this. After that, other users of this repository might want to run git fetch --prune to update their remote-tracking names.

CodePudding user response:

I will try but I'm really afraid about actions like this :|. So, be careful and ensure you are not going to loose your data.

# Create three random branches for the test
git branch www_FUNK0 origin/master
git branch WWW_funk1 origin/master
git branch WWW_FuNk2 origin/master

git branch | grep -i www_funk
# This is the output of this command:
#  www_FUNK0
#  WWW_funk1
#  WWW_FuNk2

# Iterating through all WWW_FUNK* branches one by one
for b in $(git branch | grep WWW | tr -d ' ')
do 
    # Storing the $b branch into the tmp branch and then
    # delete $b branch
    # and rename tmp branch to the lowercase version of $b
    git checkout -B tmp $b
    git branch -D $b
    git branch -m ${b,,}
done

git checkout master
git branch -D tmp

git branch | grep -i www_funk
# Finally we have this result:
#  www_funk0
#  www_funk1
#  www_funk2

Please do not try those drills in a repo with useful data!!!

  • Related