Skip to content
Eric Bouchut edited this page Mar 22, 2019 · 25 revisions

Change the URL of a remote

I recently cloned one of my github repository with hub using the wrong URL.

hub clone ebouchut/pygments-css # <=> git clone git://github.com/ebouchut/pygments-css.git

I forgot to use hub's private option -p to get a remote where I can both read and write. Here is what I should have done instead.

hub clone -p ebouchut/pygments-css # <=> git clone git@github.com:ebouchut/pygments-css.git

I therefore ended up with a read only remote using the git scheme (git://github.com/ebouchut/pygments-css.git) instead of the ssh one (git@github.com:ebouchut/pygments-css.git) which is read-write.

git remote -v
  origin	git://github.com/ebouchut/pygments-css.git (fetch)
  origin	git://github.com/ebouchut/pygments-css.git (push)

But I only figured it out when git refused to push because I was using the public git URL.

git push

  fatal: remote error:
    You can't push to git://github.com/ebouchut/pygments-css.git
    Use https://github.com/ebouchut/pygments-css.git

The fix consisted in changing the remote URL of the remote origin, like so:

git remote set-url origin git@github.com:ebouchut/pygments-css.git

I now have the correct read-write ssh remote URL.

git remote -v
  origin	git@github.com:ebouchut/pygments-css.git (fetch)
  origin	git@github.com:ebouchut/pygments-css.git (push)

In case you do not yet know hub and are using github daily, I encourage you to give it a try. I find it is a must have because it adds many useful git subcommands to create, clone (the command I used above), fork, browse a github repository, make github pull requests, push to multiple github remotes...

Make a local bare git repository

git init --bare ~/git/repo/project.git
cd /path/to/your/project
git remote add origin ~/git/repo/project.git

Push to 2 remotes using git

Say I clone a repository from github.

git clone git@github.com/ebouchut/learning-git.git

Every time I ask git to push to the remote origin, I want git to push to 2 repositories github (the one I cloned from) and bitbucket (which acts a secondary/backup git repository in this case).

Here is how to do this:

git remote set-url --add --push origin git@github.com/ebouchut/learning-git.git
git remote set-url --add --push origin git@bitbucket.org/ebouchut/learning-git.git

This adds 2 push URLs remote.origin.pushurl:

  • the first one for github: git@github.com:ebouchut/learning-git.git
  • the second one for bitbucket: ssh://git@bitbucket.org/ebouchut/learning-git.git.

Adding a remote.origin.pushurl overrides the default remote.origin.url for the push action.

git config  --local --get-regex remote.origin.\*
  remote.origin.url git@github.com:ebouchut/learning-git.git
  remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
  remote.origin.pushurl git@github.com:ebouchut/learning-git.git
  remote.origin.pushurl ssh://git@bitbucket.org/ebouchut/learning-git.git

From now using git push will push both to github and bitbucket. Now here is what happens when I do a git push. I ask git to be a bit verbose (using -v) so that it mentions where it is pushing to.

git push -v
  Pushing to git@github.com:ebouchut/learning-git.git
    To git@github.com:ebouchut/learning-git.git
    = [up to date]      master -> master
    updating local tracking ref 'refs/remotes/origin/master'
    Everything up-to-date
  Pushing to ssh://git@bitbucket.org/ebouchut/learning-git.git
    To ssh://git@bitbucket.org/ebouchut/learning-git.git
    = [up to date]      master -> master
    updating local tracking ref 'refs/remotes/origin/master'
    Everything up-to-date

Source

Push to 2 remotes using hub

First of make a private clone of your github repository.

git clone -p ebouchut/learning-git

You now have a remote named origin pointing to your repository on github.

git remote -v 
  origin	git@github.com:ebouchut/learning-git.git (fetch)
  origin	git@github.com:ebouchut/learning-git.git (push)

Then, add the other remote (bitbucket) in this case.

git remote add bitbucket ssh://git@bitbucket.org/ebouchut/learning-git.git

From now on, you can fetch and pull from the two repositories in one go like so:

git fetch origin,bitbucket
#...
# Hackety hack...
# Commit
#...
git push origin,bitbucket

Please note there is no space in between the name of the repositories and the comma.

Download a snapshot of a git repository

What I mean by snapshot is retrieving all the files without the .git repository. In the following examples HEAD denotes the branch you are in, you can replace it with the name of another branch or a tag you want to retrieve.

Git

Assuming your project is hosted on a remote git repository.

mkdir project
cd project
git archive --remote=ssh://git@git-server.example.com/username/project.git HEAD  | tar xvf -

Bitbucket

mkdir project
cd project
git archive --remote=ssh://git@git.bitbucket.com/username/project.git HEAD  | tar xvf -

If you want to get a single file instead of all the files of the repository, add the file path relative to the repository home. To get a single file from the root directory of the project:

git archive --remote=ssh://git@git.bitbucket.com/username/project.git HEAD  file | tar xvf -

Github

Ulinke Bitbuket, GitHub does not support remote git-archive, but offers 2 options:

  • A dedicated HTTP endpoint to retrieve an archive of the project
curl -O https://github.com/username/project/archive/master.tar.gz

Replace master with whatever branch name if you do not want to get a snapshot of master.

  • svn export

Github provides svn access to git repositories. No kidding...

svn export https://github.com/username/project/trunk project

Source: