Week 6

"Tug of war"

Taking the push with the pull

We have spoken at fairly great length about how remote repositories work. We have seen how the git remote tool is used to create the various references to remote repositories, but we have no real understanding about what this means in terms of Git's internals. Just in the same way a branch is a single file that contains a pointer to a reference, a remote repository has to be handled within Git somehow.

As it happens, Git again uses a reasonably simplistic design when creating remote references. To take a look at this in detail, we need to once again delve into the .git directory. Seeing as our original repository does not contain any remotes for now, we are going to use our coderepo-cl folder as an example. Hopefully, if you have been following the text, you have not deleted this directory yet. If you have, do not worry, just follow the operations we completed in Week 6, or read on and use the text in the book.

If you remember, we created two clones of our original repository. One of these was a simple clone called coderepo-cl and the other was a bare repository called coderepo-bk. The coderepo-cl and the coderepo-bk repositories were both cloned from coderepo, but it was coderepo-cl that was configured to pull from one and push to the other. Running a simple git remote -v command, confirms this configuration.
john@satsuki:~/coderepo-cl$ git remote -v
backup /home/john/coderepo-bk (fetch)
backup /home/john/coderepo-bk (push)
origin /home/john/coderepo (fetch)
origin /home/john/coderepo (push)
john@satsuki:~/coderepo-cl$

We can get even more information by running the git remote show tool with the remote name as a parameter.
john@satsuki:~/coderepo-cl$ git remote show origin
* remote origin
Fetch URL: /home/john/coderepo
Push URL: /home/john/coderepo
HEAD branch: master
Remote branches:
master tracked
wonderful tracked
zaney tracked
Local branches configured for 'git pull':
master merges with remote master
wonderful merges with remote wonderful
Local refs configured for 'git push':
master pushes to master (up to date)
wonderful pushes to wonderful (up to date)
john@satsuki:~/coderepo-cl$

How though, is this data set up and configured from within Git itself? Looking at the .git/config file, we can see a glimpse of this.
john@satsuki:~/coderepo-cl$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = /home/john/coderepo
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "wonderful"]
remote = origin
merge = refs/heads/wonderful
[remote "backup"]
url = /home/john/coderepo-bk
fetch = +refs/heads/*:refs/remotes/backup/*
john@satsuki:~/coderepo-cl$

As you can see there are two relevant sections, these are the remote and branch stanzas. The remote stanzas are there to define certain elements of the remote repository, whilst the branch stanzas describe elements and settings for the branches that we are tracking. Let us look at the relevant elements that we have set out in config file for each type of stanza.

We will start by looking at the remote stanza. We have two settings here in our configuration. The first is url and the second is fetch. The url setting tells Git the location of the remote repository defined by the name outlined within the quotation marks. In our example, the remote we first encounter is called origin and has a url of /home/john/coderepo.

You will notice that there is also a second setting called fetch. This setting tells Git which branches, or HEADs we are interested in. In the default configuration, we ask Git to fetch all branch HEADs. This also has an effect on which objects are downloaded. Git will look at all of the branch HEADs and work backwards to find out which commit objects need to be downloaded.

In the refs/ folder there are two other folders by default called tags and remotes. With the default configuration as above, these references will not be fetched, and commits that are only pointed to by these references will not be downloaded either.

Looking at the branch settings, we can see that there are a few more settings here that describe how Git responds to certain commands when inside a certain branch. In both the cases above, Git will automatically use remote of origin as the remote to use when performing operations. This means that when we run a git pull, we do not have to specify a remote to pull from. Obviously if we wanted to, we could change this and have wonderful, for example, update from a different remote repository.

The last setting in this file that we will concern ourselves with is the merge setting. When we are in the named branch, this setting defines the upstream version of the named branch and is used for merging and can affect pulling and rebasing too.

We can set these settings and any of the others in the config file manually, using the git config tool, which we used in a previous chapter.

Previous Day

Next Day

 
   
home | download | read now | source | feedback | legal stuff