linuxbashgitsshwindows-subsystem-for-linux

Change the remote of all git repositories on a system from http to ssh


Recently Github came up with a deprecation notice that the HTTP method of pushing to our repositories is going to expire soon. I've decided to change to the SSH method. On doing that I found that we need to change the remote URL of the repos after setting up keys.

But the change is a tedious process and to do it for all the repositories I have on my local system is quite a lengthy job. Is there some way we can write a Bash script that will go through the directories one by one and then change the remote URL from the HTTP version to the SSH version?

This makes the necessary change from HTTP -> SSH.

git remote set-url origin git@github.com:username/repo-name

The things that we need to change would be the repo-name which can be the same as the directory name.

What I thought about was to run a nested for loop on the parent directory that contains all the git repos. This would be something like:

for DIR in *; do
    for SUBDIR in DIR; do
        ("git remote set-url..."; cd ..;)
    done
done

Solution

  • This will identify all subfolders containing a file or folder named .git, consider it a repo, and run your command.

    I strongly recommend you make a backup before running it.

    #!/bin/bash
    
    USERNAME="yourusername"
    
    for DIR in $(find . -type d); do
    
        if [ -d "$DIR/.git" ] || [ -f "$DIR/.git" ]; then
    
            # Using ( and ) to create a subshell, so the working dir doesn't
            # change in the main script
    
            # subshell start
            (
                cd "$DIR"
                REMOTE=$(git config --get remote.origin.url)
                # uses quotes to allow spaces in path
                REPO=$(basename "`git rev-parse --show-toplevel`")
    
                if [[ "$REMOTE" == "https://github.com/"* ]]; then
    
                    echo "HTTPS repo found ($REPO) $DIR"
                    git remote set-url origin git@github.com:$USERNAME/$REPO
    
                    # Check if the conversion worked
                    REMOTE=$(git config --get remote.origin.url)
                    if [[ "$REMOTE" == "git@github.com:"* ]]; then
                        echo "Repo \"$REPO\" converted successfully!"
                    else
                        echo "Failed to convert repo $REPO from HTTPS to SSH"
                    fi
    
                elif [[ "$REMOTE" == "git@github.com:"* ]]; then
                    echo "SSH repo - skip ($REPO) $DIR"
                else
                    echo "Not Github - skip ($REPO) $DIR"
                fi
            )
            # subshell end
    
        fi
    
    done