Git (4/6)

Cloning a Repository

One of the main strengths of a distributed version control system is the possibility for each user to have their own copy of the repository they can work on. In this section of the tutorial we will show how a user can create its own copy of a repository.

In the first page of the tutorial we created a repository called "MyFirstRepository" and committed a few changes to it. Let's now make a clone of that repository.

We create a new directory called MyFirstRepositoryClone1 and use the git clone command to setup a clone of "MyFirstRepository" in this new directory. The sequence of commands is shown below.

Cloning a repository
Xavier Leclercq@PATHFINDER /c/GitRepositories
$ mkdir MyFirstRepositoryClone1

Xavier Leclercq@PATHFINDER /c/GitRepositories
$ cd MyFirstRepositoryClone1/

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1
$ git clone ../MyFirstRepository .
Cloning into '.'...
done.

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

We now have a clone of the "MyFirstRepository" repository. The clone contains the entire history of the repository just like the original. We use the git log to illustrate this fact.

Viewing the commit log
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git log
commit cc1c6530eab31c8411c7555fe75e0f850a240a2e
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Sat Nov 29 20:00:59 2014 +0000

    Update to HelloWorld.txt

commit fc7752fd9a3c2cd6985e24c9cbed4a1f1137d633
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Sat Jul 12 17:30:57 2014 +0100

    Initial commit

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

The origin Repository

A clone doesn't only contain the data about its own copy of the repository, it also keeps information about the repository it was cloned from. The name origin is given to the original repository. origin is a particular case of what is called a remote repository. We will discuss remote repositories in more details soon but let's focus on the origin repository for now.

The git remote command will display the list of remote repositories as shown below.

Remote repositories
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git remote -v
origin  c:/GitRepositories/MyFirstRepositoryClone1/../MyFirstRepository (fetch)
origin  c:/GitRepositories/MyFirstRepositoryClone1/../MyFirstRepository (push)

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

As you can see origin refers to the repository we cloned.

The git status command will include information about the origin repository (and any remote repository in general). The result of the command for our example is shown below.

Status
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

Since we didn't make any changes to the origin repository since we created the clone, git status informs us that the branch in the clone is up-to-date with the one in the origin.

Bringing the Clone up-to-date

In general after a clone has been created further changes will be committed to the original repository. Git provides a mechanism to bring clones up-to-date with their origin. We will illustrate how this is done with an example.

Let's go to the origin repository, MyFirstRepository, and commit a change. We edit the HelloWorld.txt and add a new line to it so that the file now becomes:

File: HelloWorld.txt
Hello World!
Goodbye!

We then use the commands we learned at the beginning of this tutorial to commit the updated file.

Committing the updated HelloWorld.txt to the MyFirstRepository repository
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master)
$ git add HelloWorld.txt

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master)
$ git commit -m "Another update to HelloWorld.txt"
[master 707cbbe] Another update to HelloWorld.txt
 1 file changed, 2 insertions(+), 1 deletion(-)

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master)
$

If we now go back to our clone, the MyFirstRepositoryClone1, and do git status we may not get the expected result.

git status
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

Although we have made changes to MyFirstRepository git status still says that the branch is up-to-date. This is because git status doesn't actually query the MyFirstRepository, it only queries the local copy of that repository so you need to refresh that copy first. The git fetch command does this and is shown below.

git fetch
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git fetch origin
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From c:/GitRepositories/MyFirstRepositoryClone1/../MyFirstRepository
   cc1c653..707cbbe  master     -> origin/master

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

Now that we have refreshed the local copy git status will inform us that there is one commit that was made to origin and that we have to apply to the clone.

git status
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working directory clean

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

As the output of git status suggests we can execute the git pull command to bring the clone up to date.

git pull
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git pull
Updating cc1c653..707cbbe
Fast-forward
 HelloWorld.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

Local Changes

Of course one of the main reasons for a developer to create a clone is so that he can commit his own changes to the clone.

Let's for instance create a new file called NewFile.txt and commit it to MyFirstRepositoryClone1. The steps are shown below and should be familiar by now. Note that we had to enter the default identity for the repository as we hadn't done so already (we explained this previously in this tutorial).

Adding a file to the clone
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git config user.name "Xavier Leclercq"

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git config user.email "xavier.leclercq@needfulsoftware.com"

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ touch NewFile.txt

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git add NewFile.txt

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git commit -m "Added a new file to the clone"
[master 1a3e5ad] Added a new file to the clone
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 NewFile.txt

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

It would now be interesting to see what happens if we make changes to MyFirstRepository and need to pull them into the clone after we have made local changes to it.

We go to the MyFirstRepository repository and modify HelloWorld.txt as follow:

File: HelloWorld.txt
Hello World!
Goodbye!
Ok I'll stay...

And we commit it.

More changes to HelloWorld.txt
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master)
$ git add HelloWorld.txt

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master)
$ git commit -m "More changes to HelloWorld.txt"
[master a6bc4b2] More changes to HelloWorld.txt
 1 file changed, 2 insertions(+), 1 deletion(-)

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master)
$

Now that we have new changes to pull from the cloned repository we go back to MyFirstRepositoryClone1 and do git fetch to update the local copy of the MyFirstRepository repository.

git fetch
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git fetch
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From c:/GitRepositories/MyFirstRepositoryClone1/../MyFirstRepository
   707cbbe..a6bc4b2  master     -> origin/master

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

The output of git status now shows that there is one change that has been made to MyFirstRepository and not to the clone. But it also shows that there is one change made to the clone and not integrated back into MyFirstRepository.

git status
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commit each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working directory clean

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

For this first example we have made sure to apply the changes to two different files so there is no risk of these changes conflicting with eachother. We can simply run git pull as before to integrate the changes made to the origin repository into the clone.

git pull
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git pull
Merge made by the 'recursive' strategy.
 HelloWorld.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$

There is a big difference with the previous case where no changes had been made locally to the clone. Because the branches have diverged (as reported by the git status command we ran before the pull), Git needs to merge them together again and that creates a new commit.

If we use git log we can see how two entries where added to the log:

git log
Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$ git log
commit e58912aacc7d40efb7ff99d24beebc7120edfc46
Merge: 1a3e5ad a6bc4b2
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Tue Dec 2 09:33:28 2014 +0000

    Merge branch 'master' of c:/GitRepositories/MyFirstRepositoryClone1/../MyFi

commit a6bc4b2056313881b65186f99132199346212de3
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Tue Dec 2 09:32:31 2014 +0000

    More changes to HelloWorld.txt

commit 1a3e5ad8cd8a82fea23c34ee337470bd4d48bc33
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Mon Dec 1 21:46:03 2014 +0000

    Added a new file to the clone

commit 707cbbef2d96f67d419226bb6559fd463b3e663d
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Sun Nov 30 14:18:29 2014 +0000

    Another update to HelloWorld.txt

commit cc1c6530eab31c8411c7555fe75e0f850a240a2e
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Sat Nov 29 20:00:59 2014 +0000

    Update to HelloWorld.txt

commit fc7752fd9a3c2cd6985e24c9cbed4a1f1137d633
Author: Xavier Leclercq <xavier.leclercq@needfulsoftware.com>
Date:   Sat Jul 12 17:30:57 2014 +0100

    Initial commit

Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master)
$
Xavier Leclercq@PATHFINDER /c/GitRepositories $ cd MyFirstRepository Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master) $ notepad HelloWorld.txt Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master) $ svn add HelloWorld.txt svn: E155007: 'C:\GitRepositories\MyFirstRepository' is not a working copy Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master) $ git add HelloWorld.txt Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master) $ git commit -m "Yet more changes to HelloWorld.txt" [master 29971af] Yet more changes to HelloWorld.txt 1 file changed, 2 insertions(+), 1 deletion(-) Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepository (master) $ cd .. Xavier Leclercq@PATHFINDER /c/GitRepositories $ cd MyFirstRepositoryClone1/ Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $ git fecth git: 'fecth' is not a git command. See 'git --help'. Did you mean this? fetch Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $ git fetch remote: Counting objects: 6, done. remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From c:/GitRepositories/MyFirstRepositoryClone1/../MyFirstRepository a6bc4b2..29971af master -> origin/master Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $ git status On branch master Your branch and 'origin/master' have diverged, and have 2 and 1 different commit each, respectively. (use "git pull" to merge the remote branch into yours) nothing to commit, working directory clean Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $ git pull Merge made by the 'recursive' strategy. HelloWorld.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $ git status On branch master Your branch is ahead of 'origin/master' by 3 commits. (use "git push" to publish your local commits) nothing to commit, working directory clean Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $ git log commit f5ad5165622b5df5a6dc1805fcce6e38790d724b Merge: e58912a 29971af Author: Xavier Leclercq Date: Tue Dec 2 21:15:57 2014 +0000 Merge branch 'master' of c:/GitRepositories/MyFirstRepositoryClone1/../MyFir commit 29971af74124412c42ec0a06e5049c559251c194 Author: Xavier Leclercq Date: Tue Dec 2 21:15:22 2014 +0000 Yet more changes to HelloWorld.txt commit e58912aacc7d40efb7ff99d24beebc7120edfc46 Merge: 1a3e5ad a6bc4b2 Author: Xavier Leclercq Date: Tue Dec 2 09:33:28 2014 +0000 Merge branch 'master' of c:/GitRepositories/MyFirstRepositoryClone1/../MyFir commit a6bc4b2056313881b65186f99132199346212de3 Author: Xavier Leclercq Date: Tue Dec 2 09:32:31 2014 +0000 More changes to HelloWorld.txt commit 1a3e5ad8cd8a82fea23c34ee337470bd4d48bc33 Author: Xavier Leclercq Date: Mon Dec 1 21:46:03 2014 +0000 Added a new file to the clone commit 707cbbef2d96f67d419226bb6559fd463b3e663d Author: Xavier Leclercq Date: Sun Nov 30 14:18:29 2014 +0000 Another update to HelloWorld.txt commit cc1c6530eab31c8411c7555fe75e0f850a240a2e Author: Xavier Leclercq Date: Sat Nov 29 20:00:59 2014 +0000 Update to HelloWorld.txt commit fc7752fd9a3c2cd6985e24c9cbed4a1f1137d633 Author: Xavier Leclercq Date: Sat Jul 12 17:30:57 2014 +0100 Initial commit Xavier Leclercq@PATHFINDER /c/GitRepositories/MyFirstRepositoryClone1 (master) $

blog comments powered by Disqus

Copyright(c) 2006-2017 Xavier Leclercq | Privacy policy

Home
Contact Us
Search