planetp
planetp

Reputation: 16115

How to update the remote url for multiple git repositories in Bash?

I have a bunch of git repos which have been moved to another host. I can update the remote for an individual repo with

git remote set-url origin <url>

How do I automate this for a few dozens of repos? Basically, I need to replace the hostname/path part of the url.

Upvotes: 3

Views: 3196

Answers (5)

Samar
Samar

Reputation: 1955

While finding .git directory and seding on config under that directory works perfectly, I like to let git handle this. This should work for any nested directories that may have git repositories. It will find any .git directories, cd to one directory above that .git and check for given remote type (origin by default) and modify the old remote with new remote. Usage is: ./thisscript '[email protected]:oldcompany' '[email protected]:newcompany' origin If your remote is origin, you don't need to pass the 3rd argument. Hope this helps people.

#!/usr/bin/env bash

# Usage: ${0} [OLD_REMOTE] [NEW_REMOTE] [REMOTE_NAME]

OLD_REMOTE="${1:-bitbucket.org:mybbcompany}"
NEW_REMOTE="${2:-github.com:myghcompany}"
REMOTE_NAME="${3:-origin}"

find "${PWD}" -type d -name '.git' | while read dir; do
  cd "${dir}/.."
  current_remote_url=$(git remote get-url "${REMOTE_NAME}")
  if grep "${OLD_REMOTE}" <<< "${current_remote_url}"; then
    new_remote_url=$(sed "s/${OLD_REMOTE}/${NEW_REMOTE}/" <<< "${current_remote_url}")
    echo "Changing ${current_remote_url} to ${new_remote_url}"
    git remote set-url "${REMOTE_NAME}" "${new_remote_url}"
  fi
done

Hope this will be useful for someone.

Upvotes: 0

RVM
RVM

Reputation: 2277

Answer from @match worked for me. Though I have to admit I've added something else from a different answer. People who are here using OSX, you might wanna add ' ' -e before the old and new part. So the whole thing could be:

    find . -name ".git" -exec sed -i '' 
 -e 's/old\.example\.com/new\.example\.com/g' {}/config \;

It worked for me and I got this from: invalid command code ., despite escaping periods, using sed

Upvotes: 1

Eugene Yarmash
Eugene Yarmash

Reputation: 149971

If your repositories are in a single directory, you can use a simple script like this:

for r in *; do
    git -C "$r" remote set-url origin "$(git -C "$r" remote get-url origin | sed s/old/new/)"
done

git -C <dir> tells Git to go into the repo directory before doing anything else. Then read the current remote URL and do the substitution using sed.
Needless to say, it's a good idea to make a backup before you start messing with configs of Git repositories.

Upvotes: 1

phd
phd

Reputation: 94696

For simplicity let's pretend all repositories are in the same parent directory; run a loop over subdirectories getting the current URL, replacing host and putting the URL back:

cd parent_dir &&
for repo in *; do
    cd $repo &&
    remote=`git remote get-url origin` &&
    remote=`echo $remote | sed s/oldhost/newhost/` &&
    git remote set-url origin $remote &&
    cd .. # back to parent
done

Upvotes: 5

match
match

Reputation: 11070

While the git remote command can be used, it's easier to use sed against the config file in the repo .git directory.

Assuming the repos are all on old.example.com and are moved to new.example.com and you are currently in the parent directory containing all the repos:

find . -name ".git" -exec sed -i 's/old\.example\.com/new\.example\.com/g' {}/config \;

This will find all repos (with .git directories) then replace the old path with the new path on every line in the config file.

Upvotes: 10

Related Questions