Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save toolmantim/569530 to your computer and use it in GitHub Desktop.
Save toolmantim/569530 to your computer and use it in GitHub Desktop.

(a gist based on the old toolmantim article on setting up remote repos)

To collaborate in a distributed development process you’ll need to push code to remotely accessible repositories.

This is somewhat of a follow-up to the previous article setting up a new rails app with git.

For the impatient

Set up the new bare repo on the server:

$ ssh myserver.com
Welcome to myserver.com!
$ mkdir /var/git/myapp.git && cd /var/git/myapp.git
$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$ exit
Bye!

Add the remote repository to your existing local git repo and push:

$ cd ~/Sites/myapp
$ git remote add origin [email protected]:/var/git/myapp.git
$ git push origin master

Set the local master branch to track the remote branch.

Read further for a step-by-step explanation of what’s going on.

Pre-flight sanity check

Setting up a remote repository is fairly simple but somewhat confusing at first. Firstly, let’s check out what remote repositories are being tracked in our git repo:

$ cd ~/Sites/myapp
$ git remote

None. Looking good. Now let’s list all the branches:

$ git branch -a
* master

Just one branch, the master branch. Let’s have a look at .git/config:

$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true

A pretty bare-minimum config file.

Creating the bare remote repository

Before we can push our local master branch to a remote repository we need to create the remote repository. To do this we’ll ssh in and create it on the server:


$ ssh myserver.com
Welcome to myserver.com!
$ cd /var/git
$ mkdir myapp.git
$ cd myapp.git
$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$ exit
Bye!

A short aside about what git means by bare: A default git repository assumes that you’ll be using it as your working directory, so git stores the actual bare repository files in a .git directory alongside all the project files. Remote repositories don’t need copies of the files on the filesystem unlike working copies, all they need are the deltas and binary what-nots of the repository itself. This is what “bare” means to git. Just the repository itself.

Adding the remote repository to our local git repository configuration

Now that we’ve created the remote repository we’ll add it to our local repository as a remote server called “origin” using git remote add, which is just a nicer way of updating our config file for us:


$ git remote add origin [email protected]:/var/git/myapp.git

Let’s see what it added to the config file:

[core]
  repositoryformatversion = 0
  filemode = true
  bare = false
  logallrefupdates = true
[remote "origin"]
  url = [email protected]:/var/git/myapp.git
  fetch = +refs/heads/*:refs/remotes/origin/*

We now have a remote repository “origin” that will fetch all of its refs/heads/* branches and store them in our local repo in refs/remotes/origin/* when a git fetch is performed.

Pushing to the remote repository

The time has come to push our local master branch to the origin’s master branch. We do that using the git push <target> <local> command.


$ git push origin master
updating 'refs/heads/master'
  from 0000000000000000000000000000000000000000
  to   b379203bc187c2926f44a71eca3f901321ea42c6
 Also local refs/remotes/origin/master
Generating pack...
Done counting 1374 objects.
Deltifying 1374 objects...
 100% (1374/1374) done
Writing 1374 objects...
 100% (1374/1374) done
Total 1374 (delta 89), reused 0 (delta 0)
refs/heads/master: 0000000000000000000000000000000000000000 -> b379203bc187c2926f44a71eca3f901321ea42c6

and that’s all, folks. Further pushes can be done by repeating the git push command.

Now you can tell your co-conspirators to:

$ git clone [email protected]:/var/git/myapp.git

and push and pull to your heart’s content.

Track the remote branch

You can specify the default remote repository for pushing and pulling using git-branch’s track option. You’d normally do this by specifying the --track option when creating your local master branch, but as it already exists we’ll just update the config manually like so:

[branch "master"]
  remote = origin
  merge = refs/heads/master

Now you can simply git push and git pull.

Sharing the remote repository with the world

If you want to set it up as a public repository be sure to check out the Git manual’s chapter on public git repositories.

Working with remote repository branches

git remote show is used to inspect a remote repository. It goes and checks the remote repository to see what branches have been added and removed since the last git fetch.

Doing a git remote show at the moment only shows us the remote repo’s master branch which we pushed earlier:

$ git remote show origin
* remote origin
  URL: [email protected]:/var/git/myapp.git
  Tracked remote branches
    master

Let’s create a new local git repository and push to a new branch on the remote repository. We can then use git remote show to see the new remote branch, git fetch to mirror it into our local repo and git checkout --track -b to create a local branch to do some work on it.

We’ll start by creating a new local repo and pushing some code to a new branch in the remote repository.

$ mkdir /tmp/other-git
$ cd /tmp/other-git
$ git init
Initialized empty Git repository in /tmp/other-git
$ git remote add origin [email protected]:/var/git/myapp.git
$ echo "Rails 2... woo" > afile
$ git add afile
$ git commit -m "Added afile"
Created initial commit 0ac9a74: Added afile
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 something
$ git push origin master:rails-2
updating 'refs/heads/rails-2' using 'refs/heads/master'
  from 0000000000000000000000000000000000000000
  to   0ac9a7457f4b21c9e058d4c54d262584bf35e528
 Also local refs/remotes/origin/rails-2
Generating pack...
Done counting 3 objects.
Deltifying 3 objects...
 100% (3/3) done
Writing 3 objects...
 100% (3/3) done
Total 3 (delta 0), reused 0 (delta 0)
Unpacking 3 objects...
 100% (3/3) done
refs/heads/rails-2: 0000000000000000000000000000000000000000 -> 0ac9a7457f4b21c9e058d4c54d262584bf35e528

Now let’s switch back to our old git repository and see if it detects the new branch on the remote repository:

$ git remote show origin
* remote origin
  URL: [email protected]:/var/git/myapp.git
  New remote branches (next fetch will store in remotes/origin)
    rails-2
  Tracked remote branches
    master

Let’s update our mirror of the remote repository by doing a git fetch:

$ git fetch
* refs/remotes/origin/master: storing branch 'rails-2' of [email protected]:/var/git/myapp.git
  commit: b379203
$ git remote show origin
* remote origin
  URL: [email protected]:/var/git/myapp.git
  Tracked remote branches
    master
    rails-2

We should now be able to see this in a our list of remote branches:

$ git branch -a
* master
origin/rails-2
origin/master

If we then wanted to do some work on this remote rails-2 branch we create a new local tracking branch like so:

$ git checkout --track -b rails-2 origin/rails-2
Branch rails-2 set up to track remote branch refs/remotes/origin/rails-2.
Switched to a new branch "rails-2"

To keep up-to-date and push new changesets we simply use git push and git pull when working in the local rails-2 branch.

Also notice, like we manually changed for master, .git/config has a new entry for this new tracking branch:

[branch "rails-2"]
  remote = origin
  merge = refs/heads/rails-2

Further Reading

Sourcemage’s Git Guide has some very very handy real-life examples of git commands you’ll often need.

@amitkumar
Copy link

Thoroughly useful. I've been trying to figure out how to set up a remote repo from an existing codebase, and this had (almost) all the info I needed (I just had to "git init", "git add ." to initialize the local repo). Thanks!

@toolmantim
Copy link
Author

toolmantim commented Mar 21, 2011 via email

@amitkumar
Copy link

amitkumar commented Mar 21, 2011 via email

@limeyd
Copy link

limeyd commented May 18, 2011

For the really lazy people why not do the creation in a single line one session nice and simple, even stick it in a bash script.
ssh myserver.com "mkdir -p /var/git/myapp.git && cd /var/git/myapp.git && git --bare init"

thanks for the bare.

@organouille
Copy link

Your explanations helped me a lot in understanding the --bare concept and how it interacts with existing local repositories. thanks

@akinsgre
Copy link

I struggled with this line "git remote add origin ssh://myserver.com/var/git/myapp.git" Not sure if changed and maybe everyone knows that.. But I kept getting "fatal: The remote end hung up unexpectedly" until I finally found a post that suggested using remote.origin.url = [email protected]:/app-dir/

@incredimike
Copy link

I found this via Googling for "git remote default". Awesome resource!

@deadlydog
Copy link

When I do "git push origin master" I get the error message:

error: src refspec master does not match any.
error: failed to push some refs to 'http://myGitUrl.com/Test.git'

and when I look in my remote repository's refs/heads folder it is empty, so it appears that there is no 'master' branch in my remote repo to merge with. Any suggestions? Thanks in advance.

-- EDIT --
Ok, I figured it out. The problem was I had to add and commit a file into my local repo before trying to push to the remote one. So this is the full code that I had to do:

// On the remote repo server (nothing different here from what was shown in the original post).
$ ssh myserver.com
Welcome to myserver.com!
$ mkdir /var/git/myapp.git && cd /var/git/myapp.git
$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$ exit
Bye!

// Then on my local PC
$ cd C:/dev/git
$ git init Test
Initialized empty Git repository in C:/dev/git/Test/.git/
$ cd Test
$ git remote add origin [email protected]:/var/git/myapp.git

// Here is where I create, add, and commit a new file (which then creates the 'master' branch) before trying to push to the remote origin.
$ touch SomeNewFile
$ git add SomeNewFile
$ git commit -m "first commit"
[master (root-commit) 8d8901d] first commit
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 10064 SomeNewFile

$ git push origin master

@geforceGTX480
Copy link

Awesome!
Question though: So you don't need to generate RSA Keys on your local machine and add your public key to your hosting server to successfully run $git remote add ?

@sam-baumann
Copy link

what are you supposed to use for

ssh myserver.com

sorry, git noob

@bextra
Copy link

bextra commented Jan 10, 2014

Very helpful guide! Especially for tracking the remote branch. I am using RStudio and it can't automatically pull or push without that addition to the .git/config

@mulisi
Copy link

mulisi commented Jul 16, 2014

Thank you very much; this is what I've been looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment