The remote Git repositories host our projects through the Internet or network.
The main purpose of a remote repository is to place the repository to a central location so that it can be accessed by multiple developers.
A remote repository can be accessed via http, ssh or even local (file-system) protocols.
In this tutorial we will keep the things simple and see how to push, clone and pull projects over the local protocol (local file system). Let's see that step by step with an example.
Creating and Adding a project to Git
Let's start git bash from which we will create a project under a directory 'my-project' and will add that to Git.
Joe@jpc MINGW64 /c/git-local-repository-example
$ dir
Joe@jpc MINGW64 /c/git-local-repository-example
$ mkdir my-project
Joe@jpc MINGW64 /c/git-local-repository-example
$ cd my-project/
Joe@jpc MINGW64 /c/git-local-repository-example/my-project
$ git init
Initialized empty Git repository in C:/git-local-repository-example/my-project/.git/
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ echo test content > readMe.txt
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ git add *
warning: LF will be replaced by CRLF in readMe.txt.
The file will have its original line endings in your working directory
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ git commit -m "adding my-project"
[master (root-commit) 6decbea] adding
1 file changed, 1 insertion(+)
create mode 100644 readMe.txt
So far there's nothing new, we have been doing same thing in previous tutorials. Now let's host above project from a central location on the file-system which will be acting as remote repository.
Creating Remote Repository
Let's create a directory (my-project.git) representing the remote repository for our above project:
Joe@jpc MINGW64 /c/git-local-repository-example
$ mkdir my-project.git
Joe@jpc MINGW64 /c/git-local-repository-example
$ cd my-project.git
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git
$ git init --bare
Initialized empty Git repository in C:/git-local-repository-example/my-project.git/
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git (BARE:master)
$ ls -la
total 15
drwxr-xr-x 1 Joe 197610 0 Feb 2 13:41 ./
drwxr-xr-x 1 Joe 197610 0 Feb 2 13:40 ../
-rw-r--r-- 1 Joe 197610 86 Feb 2 13:41 config
-rw-r--r-- 1 Joe 197610 73 Feb 2 13:41 description
-rw-r--r-- 1 Joe 197610 23 Feb 2 13:41 HEAD
drwxr-xr-x 1 Joe 197610 0 Feb 2 13:41 hooks/
drwxr-xr-x 1 Joe 197610 0 Feb 2 13:41 info/
drwxr-xr-x 1 Joe 197610 0 Feb 2 13:41 objects/
drwxr-xr-x 1 Joe 197610 0 Feb 2 13:41 refs/
In above example we used git init --bare to create a bare repository.
What is a bare repository? A bare repository doesn't contain a working directory. It does not have .git directory. It has similar directory structure what we see inside the .git directory. It has all commit history but without a parent .git directory and without a working tree.
By convention, bare repository main directory name ends with the suffix .git
Viewing bare repository logs
We can use git log for the bare repository to see the commit history. In above example, since my-project.git does not yet have any projects, it will return an error:
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git (BARE:master)
$ git log
fatal: your current branch 'master' does not have any commits yet
We can also use git branch command (but right now we have no project branches)
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git (BARE:master)
$ git branch -a
Pushing a project to the repository
So far there's no relation between our project (my-project) and the repository (my-project.git), but now we are going to push our project to the repository for the first time.
The push command syntax
git push <remote-url> <branch-to-push>
Let's use push command in our example:
Joe@jpc MINGW64 /c/git-local-repository-example
$ ls
my-project/ my-project.git/
Joe@jpc MINGW64 /c/git-local-repository-example
$ cd my-project
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ git push file:///c/git-local-repository-example/my-project.git/ master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 215 bytes | 107.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To file:///c/git-local-repository-example/my-project.git/
* [new branch] master -> master
Note that we used file:// at the beginning of our repository url, indicating the repository is located on the local file system.
Let's see the logs again inside our repository:
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git (BARE:master)
$ git log
commit 6decbea4a2b4e9fe4f54814e9821d95ba74171b7 (HEAD -> master)
Author: Joe <joe@example.com>
Date: Sat Feb 2 13:14:28 2019 -0600
adding my-project
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git (BARE:master)
$ git branch
* master
Cloning remote project from a new client
Cloning a remote repository copies the target repository to local file system.
The clone command syntax
git clone <repository-url> [<target-directory>]
Let's create a new directory representing another client (other than the original one my-project) and clone the remote project
Joe@jpc MINGW64 /c/git-local-repository-example
$ mkdir other-client
Joe@jpc MINGW64 /c/git-local-repository-example
$ mkdir other-client/my-project
Joe@jpc MINGW64 /c/git-local-repository-example
$ cd other-client/my-project/
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project
$ git clone file:///c/git-local-repository-example/my-project.git/ .
Cloning into '.'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ ls -la
total 5
drwxr-xr-x 1 Joe 197610 0 Feb 2 14:42 ./
drwxr-xr-x 1 Joe 197610 0 Feb 2 14:18 ../
drwxr-xr-x 1 Joe 197610 0 Feb 2 14:42 .git/
-rw-r--r-- 1 Joe 197610 14 Feb 2 14:42 readMe.txt
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ git log
commit 6decbea4a2b4e9fe4f54814e9821d95ba74171b7 (HEAD -> master, origin/master, origin/HEAD)
Author: Joe <joe@example.com>
Date: Sat Feb 2 13:14:28 2019 -0600
adding my-project
Tracking of repository
The time when we invoke the 'clone' command with the specified remote url, git automatically saves that as a tracked repository by the name of 'origin'. We can see that info by using git remote -v (-v flag is for verbose).
In above example after cloning:
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ git remote -v
origin file:///c/git-local-repository-example/my-project.git/ (fetch)
origin file:///c/git-local-repository-example/my-project.git/ (push)
That means next time we don't have to specify the whole url, just use the reference name 'origin' instead. We can also add a remote explicitly by using following command:
git remote add my-origin-name <the-url>
Or we can edit the repository info by using following command:
git remote set-url my-origin-name <the-url>
Pushing new changes
Let's add a new file to our new client project and push that to the central repository:
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ echo new content > newFile.txt
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ ls -la
total 6
drwxr-xr-x 1 Joe 197610 0 Feb 2 15:23 ./
drwxr-xr-x 1 Joe 197610 0 Feb 2 14:18 ../
drwxr-xr-x 1 Joe 197610 0 Feb 2 14:42 .git/
-rw-r--r-- 1 Joe 197610 12 Feb 2 15:23 newFile.txt
-rw-r--r-- 1 Joe 197610 14 Feb 2 14:42 readMe.txt
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ git add *
warning: LF will be replaced by CRLF in newFile.txt.
The file will have its original line endings in your working directory
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ git commit -m "adding new file"
[master de56e3f] adding new file
1 file changed, 1 insertion(+)
create mode 100644 newFile.txt
Joe@jpc MINGW64 /c/git-local-repository-example/other-client/my-project (master)
$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes | 281.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To file:///c/git-local-repository-example/my-project.git/
6decbea..de56e3f master -> master
This time we used the repository reference name 'origin' instead of the whole url.
Let's see the logs in our central repository:
Joe@jpc MINGW64 /c/git-local-repository-example/my-project.git (BARE:master)
$ git log
commit de56e3f07beaadb5a95d0d1a32d6d17c322330e7 (HEAD -> master)
Author: Joe <joe@example.com>
Date: Sat Feb 2 15:24:09 2019 -0600
adding new file
commit 6decbea4a2b4e9fe4f54814e9821d95ba74171b7
Author: Joe <joe@example.com>
Date: Sat Feb 2 13:14:28 2019 -0600
adding my-project
Pulling the new changes
The git pull command is used to download the content from a remote repository and merge the changes to the local repository.
The pull command syntax
git pull <remote-url>
Let's go to our original client project /c/git-local-repository-example/my-project and pull the new changes from /c/git-local-repository-example/my-project.git.
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ ls
readMe.txt
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ git pull file:///c/git-local-repository-example/my-project.git/
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/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:///c/git-local-repository-example/my-project
* branch HEAD -> FETCH_HEAD
Updating 6decbea..de56e3f
Fast-forward
newFile.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 newFile.txt
Joe@jpc MINGW64 /c/git-local-repository-example/my-project (master)
$ ls
newFile.txt readMe.txt
We have successfully pulled the changes from the repository.
|