wesleybliss
9/4/2014 - 10:01 PM

Rename GIT branches based on a pattern

Rename GIT branches based on a pattern

#! /usr/bin/env lua

print("")

local showUsage = function()
    print([[
Rename a set of branches, effectively DELETING old
branches and creating new ones based on the old ones.

USAGE
    ]] .. arg[0] .. [[ <find> <replace>
    
    find            A search query to grep for a set of branches
    replace         Text to replace the find query with

EXAMPLE
    ]] .. arg[0] .. [[ origin "1.2.2" "1.2.4"

]])
    os.exit( 1 )
end

local find      = select( 1, ... ) or showUsage()
local replace   = select( 2, ... ) or showUsage()

local trim = function( s )
    return s:gsub("^%s+", ""):gsub("%s+$", "")
end

local run = function( cmd )
    local lines = {}
    local file = io.popen( cmd )
    for line in file:lines() do
        table.insert( lines, line )
    end
    file:close()
    return lines
end

local confirm = function( prompt )
    local confirmations = { y = true, yes = true }
    io.write( prompt .. " [y/N] " )
    local answer = io.read()
    if ( answer ~= nil and confirmations[string.lower(answer)] ) then
        return true
    end
    return nil
end

-- Get a list of branches - local only, for now
-- local branches = os.execute( "git branch" )
-- print(branches)

local oldbranches = run( "git branch -l | grep " .. find )
local newbranches = {}

-- Example of iteration
-- for key, value in pairs(branches) do
--     print( value )
-- end

print( "Here are the branches and what they will be renamed to:" )
print("")

for i = 0, #oldbranches, 1 do
    if ( oldbranches[i] ) then
        oldbranches[i] = trim( oldbranches[i] )
        local newbranch = string.gsub( oldbranches[i], find, replace )
        table.insert( newbranches, newbranch )
        print( oldbranches[i] )
        print( newbranch )
        print("")
    end
end

-- Confirm rename
local conf = confirm( "Are you sure you want to rename these local branches?" )
if ( conf == nil ) then
    print( "Cancelled" )
    os.exit( 3 )
end

print( "OK" )
print("")

-- Move (rename) branches
for i = 0, #oldbranches, 1 do
    if ( oldbranches[i] and newbranches[i] ) then
        run( "git branch -m " .. oldbranches[i] .. " " .. newbranches[i] )
    end
end

print("")

-- Confirm remote delete
local conf = confirm( "Would you like to delete old branches from all remotes?" )
if ( conf == nil ) then
    print( "Cancelled")
    os.exit( 4 )
end

print( "OK" )
print("")

local remotes = run( "git remote | cut -f1" )

for _, branch in pairs(oldbranches) do
    for __, remote in pairs(remotes) do
        run( "git push " .. remote .. " :" .. branch )
    end
end

print("")

-- Confirm new push
local conf = confirm( "Would you like to push renamed branches to all remotes?" )
if ( conf == nil ) then
    print( "Cancelled" )
    os.exit( 5 )
end

print( "OK" )
print("")

-- Push all new branches
for _, newbranch in pairs(newbranches) do
    for __, remote in pairs(remotes) do
        run( "git push " .. remote .. " " .. newbranch )
    end
end

print("")
print("")
print( "Finished renaming " .. #newbranches .. " branches" )