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!!!