Commands discussed in this section:
- git init –bare
- git clone
- git remote
- git pull
- git push
Scenario: Example Remote Repository
Let’s set up our own little “remote” repository and then share it. (The repository will be “remote” to the users sharing it.)
In these examples, the other users sharing the repository will not be very remote since the repository will be on the same disk as the users’ home directories. But the git workflow and commands are identical, whether the users and repositories are just a few millimeters away on the same disk, or on a remote network across the world.
We’ll have the repository created by the user gitadmin. The gitadmin‘s repository will be be the repository where everybody on the project both publishes their work and also retrieves the latest work done by others.
- gitadmin will create a repository.
- Other users, like Amy and Zack will then get (“git clone”) copies of gitadmin‘s remote repository.
- Changes will be pulled and pushed to and from gitadmin‘s repository.
If you are creating a git repository for only your own use on projects or days when you just don’t feel like sharing, you type:
gitadmin$ git init project1 Initialized empty Git repository in /home/gitadmin/project1/.git/
However, if you are creating a git repository for sharing with git clone/pull/fetch/push, Use the –bare option to git init:
gitadmin$ git init --bare project1.git Initialized empty Git repository in /home/gitadmin/project1.git/
If you want to know why, see Shared Repositories Should Be Bare Repositories.
Bare Repositories End in “.git”
You might have noticed the –bare repository created above ended in .git. By convention, bare git repositories should end in .git. For example, project1.git or usplash.git, etc. The .git ending of a directory signals to others that the git repository is bare.
Amy is ready to add to the remote repository
In our example, since Amy’s name begins with the first letter of the alphabet, she gets to work on the repository first.
Amy clones it:
amy$ git clone file:///home/gitadmin/project1.git Initialized empty Git repository in /home/amy/project1/.git/ warning: You appear to have cloned an empty repository.
Git just told us the repository that Amy just cloned is empty.
We can now start creating files and publishing (“git push“) them to the shared repository.
Amy wants to see if there are any branches in the repository she just retrieved/cloned:
amy$ cd project1 amy$ git branch amy$
The empty output from the git branch command showed are no branches in the new repository.
Amy creates her first file and commit’s the new file to the repository.
amy$ echo The beginnings of project1 > amy.file amy$ git add . amy$ git commit -m"Amy's initial commit" [master (root-commit) 01d7520] Amy's initial commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 amy.file amy$ git branch * master
The cloned, bare repository didn’t have any branches, not even the master repository. When Amy did the first git commit, the master branch was created in Amy’s local repository.
Amy tries to publish her local repository to the remote repository:
amy$ git push No refs in common and none specified; doing nothing. Perhaps you should specify a branch such as 'master'. fatal: The remote end hung up unexpectedly error: failed to push some refs to 'file:///home/gitadmin/project1.git'
Oops, that didn’t work. The above happens on brand new, completely empty, branchless repositories (immediately after doing the git init –bare …).
Amy’s local repository created the master branch, but the shared repository that gitadmin created does not have any branches on it still.
Amy will take git’s advice and tell git the name of the branch she wants pushed to which remote repository. She must specify both the remote repository name and branch name.
What are the branch and repository names? Amy has been distracted lately and forgot the name of remote repository, so she’ll use the git remote command to list the names of her remote repositories:
amy$ git remote origin
She is shown there is only one remote repository named origin. The default remote repository when you git clone a repository is named origin, so the above output isn’t surprising.
Similarly, Amy can find out the branch name in her local repository by using the git branch command:
amy$ git branch * master
The branch name master isn’t surprising either, since master is the default branch name for git.
Armed with the remote repository name (origin) and local branch name (master) Amy can now push (publish) the changes.
The git push syntax is:
git push [remote-repository-name] [branch-or-commit-name].
Amy will push the branch named master to the remote repository named origin:
amy$ git push origin master Counting objects: 3, done. Writing objects: 100% (3/3), 245 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To file:///home/gitadmin/project1.git * [new branch] master -> master
The last line above reports a new branch was created: the master branch (referred to in some places as the “source”) on the local repository was mapped to the master branch (referred to in some places as the “destination”) on the remote repository.
Amy will no longer need to type git push origin master, but will be able to type git push, since the master branch now exists on the remote repository named origin:
amy$ git push Everything up-to-date
Zack wants to play too
Now it’s Zack’s turn to play with the repository. He clones it:
zack$ git clone file:///home/gitadmin/project1.git Initialized empty Git repository in /home/zack/project1/.git/ remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0) Receiving objects: 100% (3/3), done. zack$ ls amy.file
Above, the file Amy added, amy.file is copied from the shared repository to Zack’s working directory.
Zack adds a file and pushes it up to the shared repository:
zack$ cd project1 zack$ echo I am zack > zack.file zack$ git add . zack$ git commit -m 'zack initial commit' [master 05affb3] zack initial commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 zack.file zack$ git push Counting objects: 4, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 283 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To file:///home/gitadmin/project1.git 01d7520..05affb3 master -> master
Note that Zack didn’t have to do the git push origin master to create the master branch on the remote repository, since Amy had already created the master branch on the remote repository.
Amy wants to get the latest
amy$ git pull remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From file:///home/gitadmin/project1 01d7520..05affb3 master -> origin/master Updating 01d7520..05affb3 Fast-forward zack.file | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 zack.file amy$ ls amy.file zack.file
Things are working pretty well: Amy and Zack are sharing nicely: They are contributing to (“git push“) and receiving from (“git pull“) the shared repository.
The above summarizes how to get moving with shared, remote repostitories. But there’s a lot more fun you can have with remote repositories.
Next: Shared Repositories Should Be Bare Repositories
Adding and Removing Branches with Remote Repositories
Previous: Git and Remote Repositories
Git Remotes Example: Creating a Shared Repository; Users Sharing The Repository
Git Remotes Behind The Scenes: “Tracking Branches” and “Remote-Tracking Branches”
Git Remotes Up Close: The Configuration File – “remote” section
Git Remotes Up Close: The Configuration File – “branch” section
Git Remotes: Fun Commands You Can Use