I recently decided to switch from using a traditional Intel based laptop to a Macbook (I know Macbooks also use Intel chips now, but you know what I mean).
Rather than simply make a tarball of all my code projects that I would ship across my network to the new system, I decided to try and be a bit more professional and give git a try.
All things being equal, a single developer working on a code project probably doesn’t need source control, but I figured it was probably wise to learn this, in case some situation arose in future where I was required to collaborate, and where it was important I didn’t look like a complete novice.
I have had some experience with git before, but this was pretty pedestrian, and it didn’t touch on the main challenge with git, which is working from multiple sources with remote repositories.
For the uninitiated, git is a source control system, but not like a traditional source control system.
In a traditional system, the history of changes to a particular code project are stored centrally. In the git system, each participant in the project retains a local history, which they can work on locally, or merge back to the central repository. This logic is somewhat convoluted when you are used to working with a centrally stored repository, which means git can take a bit of getting used to. This isn’t really helped by the syntax of the commands used in git, which are anything but self-explanatory.
I won’t go into git any more than this, because its way more complex than can be explained in a single post. Instead, I’ll focus on the task described by the post title; if you want to learn more about git that this provides for, you’ll have to read a bit more elsewhere, and do quite a bit of trial and error.
OK, so the basic components of the task are:
1. An Internet hosted git repository (repo)
2. Computer 1 with the git client installed
3. Computer 2 with the git client installed
There are several options available for creating an Internet hosted git repo, many of which offer a free basic level of service. I choose Bitbucket. I registered, signed in and create a repo. In completing this task, Bitbucket signalled the commands and URL I would need to work with the repo. Thank you Bitbucket for making life with git a little easier. For the purposes of this post, lets say I’m creating a repo to manage the code for this blog, so I’ve called it “nbfblog”
Next to Computer 1. The installation of git is very straightforward, so I won’t cover it here. Just Google it for your particular OS.
Once installed, you now need to create your local repo. Change to the directory in which your code is stored, and issue the following commands:
git add .
git commit -am "initial checkin"
These commands will create your local repo.
The next task is to create what is referred to as a remote of this repo. When we were on Bitbucket, we basically created an empty repo called nbfblog. We are now going to populate that repo by creating a remote of our local repository. The terminology isn’t great here, which is kind of an issue throughout git.
To create your remote, issue the following command:
git remote add origin https://email@example.com/garrethmcdaid/nbfblog.git
This creates a remote called origin, in the Bitbucket account that is identified by the username garrethmcdaid, in the repo nbfblog. Depending on how git is set up on Computer 1, you may or may not be asked for your Bitbucket password when you issue this command.
At this point, all you have done is create a remote. No code as been moved between Computer 1 and the central repository. To do this, issue the following command:
git push -u origin --all
If you’re used to using the command line, you’ll probably presume that the -u argument here means user. Again, its no harm to remind yourself that the git command syntax is misleading; it this instance, -u means upstream, and signifies the name of the remote you want to push your code to, and has nothing to do with usernames. The –all switch means push everything. You specify this as git provides functionality to push only parts of a local repo to remote, which is beyond what we are dealing with here.
At this point, a copy of your code should exist in Bitbucket, which you can check via the web interface. You will see that the code has been created under a branch called master. What’s a branch you ask? A good question, and there are as many answers as there are developers. We are only going to be working with the master branch, so its probably better if we leave the topic of branching for another day.
For now, lets just use an analogy: think of your code as a recipe for sourdough bread. One day, you wake up and decide you want to make sourdough bread with black olives. Rather than throw your original recipe (your master branch) in the bin, you make a photocopy of it (your black olive branch), and then make changes to the photocopy, leaving the original in your recipe folder. When you’re happy with your new recipe, you merge the annotations into the original and throw away the photocopy. You have now merged the blackolive branch into the master branch.
Like I say, we only going to deal with the master branch here (think of it has having 2 recipe folders in 2 different houses, and you want to make sure the recipe for sourdough bread is identical in each of the folders). The only other thing to say is that branches exist in your repo regardless of where it is stored, locally or centrally.
So enough about bread and back to git. To be sure we’re on the same page here, you should probably test making further changes to your local code case, and push them to the central repo. Try this:
Edit a file
git commit -am "Computer 1 update" (should report re. your edit)
git push origin master (should ship all your files, with edits, off to your remote).
Again, check the Bitbucket interface to make sure your changes (commits) have been passed in the central repo.
Now, having created a remote repo, a local repo, and mastered the process of moving code changes from the local repo to the remote repo, lets see if we can introduce Computer 2.
Simple stuff first, make sure the git client is installed.
Now, in this case, we must remember that we have already got a git repo, so we are not going to init another one. Instead, we are going to clone the existing git repo from the remote repository. Change to the parent directory where you want to locate the code base on Computer 2. We will allow git to create a new directory at this location to store the code.
sudo git clone https://firstname.lastname@example.org/garrethmcdaid/nbfblog.git httpdocs
Hopefully, this command is self-explanatory. We are cloning the nbfblog repo, and its branches, that exists on Bitbucket under the account identifier garrethmcdaid in the new directory httpdocs.
If this command has worked (again, your Bitbucket password may be required), you should be able to change into the httpdocs directory and view you code.
Now, the real test. Make some changes to the code on Computer 2. The objective here is to make sure those changes are replicated back to Computer 1 via the central repo.
Remember, git is based on local history rather than central history, so when you make a change to code, the first place to commit that is to the local repo. Lets do that now:
git commit -am "Computer 2 update"
That change now exists in the local repo on Computer 2. To get that change into the central repo, lets push it:
git push origin master
That is, push my local history to the master branch in the “origin” remote repo, which git knows is a remote, as the origin repo was cloned from a remote source. To be more precise, you are merging the code in your local master branch to the master branch in the origin remote.
Once again, to verify that this has worked, go back to the Bitbucket web interface and view your source. The changes you made to your code on Computer 2 should now be visible in that source.
Presuming that they are, well done. You have now mastered the core functionality of git, which is actually the hardest part of git to master. To really push the envelope, lets now make sure that when we go back to Computer 1, our code base has the changes we made on Computer 2.
Change back into the directory in which your code was stored on Computer 1. Now, we want to pull the current history of the master branch in the central repo into the master branch of our local repo.
git pull origin master
git knows that origin refers to a remote, because we created remotely, and we’re telling git that we want the history of the master branch, which again is the only branch we are dealing with. Once this command has processed, check your local code case and make sure the changes made on Computer 2 are there.
If they are, well done again. Now, all you have to do is remember the sequence:
Change a file
Push to remote
Pull from remote
Change a file
Push to remote
Pull to remote