Week 6Day 3 - "Is this clone for real?"
Not entirely as expected
We now have a clone of the repository and we can start to look at how we can play with branches and see how the two are different.
In the trenches...
"Klaus, this doesn't make sense though. I cloned my repo, but my branches have vanished," started Rob, rather worriedly.
"I'm sure they haven't gone anywhere," shouted John.
Rob's reply was quick and certain, "They have! Run a git branch on your clone and see for yourself"
"Oh!"
Rob smiled the smug smile of a man who is pleased he was right.
* * *
"Rob?" asked John tentatively, aware of his previous state of anguish.
His reply indicated a less than stressed demeanour, "Sup, dude?".
John was pleasantly surprised, "Did you sort out the branch issue?"
Rob began walking over to John, "Yeh, try running git branch with the r parameter."
You may be thinking that we now have a detached copy of the other branches in our repository.
That's not exactly accurate.
Let us run the command that Rob suggested and see what is happening.
john@satsuki:~/coderepo-cl$ git branch
* master
john@satsuki:~/coderepo-cl$ git branch -r
origin/HEAD -> origin/master
origin/master
origin/wonderful
origin/zaney
john@satsuki:~/coderepo-cl$
Whilst we have all the objects in our repository, we do not yet have our branches set up locally.
They are available, but they have not yet been set up locally.
To explain this we need to introduce the concept of remote tracking branches.
We are familiar with local branches.
Local branches allowed us to make commits locally in a safe and separated environment.
Remote tracking branches are links to remote branches which allow us to track the development of that branch and bring it in to a local one if we so desire.
Let us take a look at what we can do with these remote tracking branches.
Notice in the output above, we have the word origin in front of the branch names.
When we clone a repository, Git automatically sets up what is called a remote.
We can view this by using the git remote tool.
john@satsuki:~/coderepo-cl$ git remote
origin
john@satsuki:~/coderepo-cl$ git remote -v
origin /home/john/coderepo (fetch)
origin /home/john/coderepo (push)
john@satsuki:~/coderepo-cl$
As you can see from the output above, the origin remote definition points to the original folder that our repository came from.
So now we know that when referring to origin/master , we are really talking about the master branch which is located at the remote location origin.
We are going to spend a little while now learning about remote branches and how they differ to local branches.
Let us spend a few minutes trying some of our normal operations against a remote branch.
The first operation we are going to try is a diff.
We are going to run a diff between our current master branch and the wonderful branch as it stands in the original repository, so we should be diffing between master and origin/wonderful .
For brevity, we are also going to limit the changes shown to those which affect newfile1 only, by appending -- <filename> to the command.
john@satsuki:~/coderepo-cl$ git diff master origin/wonderful -- newfile1
diff --git a/newfile1 b/newfile1
index f32a0e6..ef20984 100644
--- a/newfile1
+++ b/newfile1
@@ -1,3 +1,2 @@
A new file
-and some more awesome changes
-Some mega important changes
+and some more changes
john@satsuki:~/coderepo-cl$
So we can see that our diff command completed successfully.
Note that this command requires no connection to our origin repository, as all of the data has been cloned locally, more on this later.
Let us run another command now and learn a little more about what the remote reference origin really means.
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 branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
john@satsuki:~/coderepo-cl$
Though this command introduces some terms that we are not yet familiar with yet, like push, pull and fetch, we can see that the origin remote has been set up to track three branches called, master, wonderful and zaney.
So although these branches are not yet usable in the way a local branch would be, it is comforting to know that Git does know about them.
Let us continue playing with the remote branch and run a git log command against it.
john@satsuki:~/coderepo-cl$ git log origin/master -- newfile1
commit 9cb2af2a00fd2253060e6bf8cc6c377b3d55ecea
Author: John Haskins <john.haskins@tamagoyakiinc.koala>
Date: Tue Apr 19 16:43:59 2011 +0100
Important Update
commit d50ffb2fa536d869f2c4e89e8d6a48e0a29c5cc1
Merge: ed2301b 7cc32db
Author: John Haskins <john.haskins@tamagoyakiinc.koala>
Date: Fri Apr 1 07:42:04 2011 +0100
Merged in zaney
...
...
...
Again, this requires no connection to the origin repository at all and works as expected.
Let us try something really funky now, let us try checking out a remote branch so that we can view the file system.
We are now going to try checking out the remote branch called wonderful.
john@satsuki:~/coderepo-cl$ git checkout origin/wonderful
Note: checking out 'origin/wonderful'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at cfbecab... Fantastic new feature
john@satsuki:~/coderepo-cl$
Interesting.
This is not what we are used to seeing.
When we have checked out branches before, we have always been presented with a Switched to branch 'xxxxxx' message.
Now we are seeing a funny message about having a detached HEAD.
This is because we are not actually on a branch.
We can make changes as we are advised, we can even make commits, but these will not actually become integrated into any branches.
In essence these commits would be left dangling and after time, because no branch points to them, they would get deleted by garbage collection routines.
Running the git branch command below confirms our suspicions.
john@satsuki:~/coderepo-cl$ git branch -v
* (no branch) cfbecab Fantastic new feature
master 37950f8 Continued Development
john@satsuki:~/coderepo-cl$
So we really need to figure out how to make these branches exist locally so that we can commit to them and retain those commits.
To do this we use the git branch tool again, but we use it in a slightly different manner.
john@satsuki:~/coderepo-cl$ git checkout -b wonderful origin/wonderful
Branch wonderful set up to track remote branch wonderful from origin.
Switched to a new branch 'wonderful'
john@satsuki:~/coderepo-cl$
We are now on a local instance of the wonderful branch.
Let us take a minute to understand what that means.
As Git is a distributed environment, our local wonderful branch, is not going to be synchronised with the remote end automatically.
It would require effort on our part.
What this does mean though, is that we are able to begin committing to this branch and experimenting with it.
|