bash - Switch git protocol for multiple git repository via bash

On linux, there are some git repo, whose .git/config contain following 3 lines:

[remote "origin"]
    url = git@github-eo:eric/workspace.git
    # url = https://eric@github.com/eric/workspace.git

(Tip: the last 2 line begin with a tab.)

The question is:

  • I want to move the # from 3rd line to 2nd line by bash, via sed maybe, and also be able to move it back. I mean trigger the 2 lines, how to call the sed in bash?

@Update:

Choose protocol via argument to script:

Actually, I will provide an argument to the script, it should be either ssh or https, the argument will decide which line to uncomment, and which to comment, if a line for one of the 2 protocol don't exists, then ignore it.

By the way, I just need the sed part to modify the 2 lines, I can write other parts of the bash, to save your time.

Reason I want to do this:

I want to do this, because sometime ssh won't work due to network or github bug, I don't know, at that time I need to switch all git repo from ssh to https, but when ssh works well, I will use it because I don't need to input password each time.

I have also asked this question about why ssh not working from time to time, but not solved, so I have to write a script to help trigger it with one command.


Summary:

Thanks for answers & comments, I would summary the solutions as following.

Solutions:

  • Use bash & sed, see the answer by Eric Wang (me). It works for linux I guess, mac might need some modification for the tab match, windows might can't use it.
  • Use bash & awk, see answer by anubhava.
  • Define multiple remote, 1 for ssh, 1 for https, then choosing protocol by select the remote, see comments under question by William Pursell. This would work for all system I guess.
  • Use [include] to another file that specify the protocol lines, and change the soft link when need, could write a shell script to help switch the soft link instead of change file content, see comments under question by gniourf_gniourf. This works at least for unix-like system I guess.

Answers


awk might be better option here:

awk -v kw='(https|ssh):' 'p ~ /^\turl/ && $0 ~ kw && $0 ~ /^\t#[[:blank:]]*url/ {
   sub(/^\t/, "\t# ", p)
   sub(/^\t*#[[:blank:]]*/, "\t")
}
p!="" {
   print p
}
{
   p=$0
}
END {
   print p
}' file

[remote "origin"]
    # url = git@github-eo:eric/workspace.git
    url = https://eric@github.com/eric/workspace.git

I just figured out how to do that via sed, following is the script:


Code

git_protocol_switch.sh:

#!/bin/bash

# repo array,
repo_arr=(
    "/mnt/star/git_repository/workspace" 
    "/media/ERIC/node"
    "/mnt/star/workplace/eclipse_j2ee_workplace/eric"
)

protocol="null"

url_prefix_comment=""
url_prefix_uncomment=""

repo_count=0

# read protocol,
if [ $# -ge 1 ]; then
    protocol=$1
fi

# check protocol,
if [ $protocol == "ssh" ]; then
    url_prefix_comment="https"
    url_prefix_uncomment="git"
elif [ $protocol == "https" ]; then
    url_prefix_comment="git"
    url_prefix_uncomment="https"
else
    echo "invalid protocol: $protocol"
    exit 1;
fi


# switch protocol for repo in array,
for i in "${!repo_arr[@]}"; do 
    if [ -d "${repo_arr[$i]}" ]; then
        sed -i "s/^\turl = $url_prefix_comment/\t# url = $url_prefix_comment/g" "${repo_arr[$i]}/.git/config"
        sed -i "s/^\t# url = $url_prefix_uncomment/\turl = $url_prefix_uncomment/g" "${repo_arr[$i]}/.git/config"

        repo_count=$(expr $repo_count + 1)
    else
        echo "non exists repo: ${repo_arr[$i]}"
    fi
done

echo "Done, switch to protocol [$protocol], repo count: {$repo_count}."

exit 0

Call it
# switch to ssh
./git_protocol_switch.sh ssh


# switch to https
./git_protocol_switch.sh https

What it do

It will help to switch protocol for all repo listed in the bash array. Ofcause, need to add the 2 line for 2 protocol for each repo first by hand.

Cheers :}


Need Your Help

How/whether to make a universal storyboard in Xcode

ios ipad uistoryboard uistoryboardsegue ios-universal-app

When creating a storyboard file in Xcode, you must select if it is for iPhone or iPad. This implies one should always put iPhone and iPad UIs into separate storyboards. Is this true?

How does Java standard libraries comunicate with native code?

java jvm java-native-interface jvm-hotspot

Do they use something like Mono's PInvoke? Or is it more like internal calls registered before the runtime is started? Does java have a base library for handling native calls like mscorlib.dll? If ...