Friday, August 30, 2013

Getting Started with Git...Introduction to the basic work flow

This is a very fluid and informal guide to some of the git commands you would come across with a relatively moderate level of frequency as you work with Git. It covers the basics of the git work flow.

And by the way, this is not a true life story...

So yes! First day at work! Congrats! You managed to pass through the technical assessments and various stages of interviews (you did a swell job selling yourself and how awesome you are innit?) Phew! Now it’s the time to come in and start doing all those stuffs you profess you can do! Yes!

After the round of introduction to other folks in the company and your co-developers, you are "introduced" to your work station: All set up nicely; with the right number of monitors just as you like it. Your favourite IDE is already installed too! Cool!

Your new company uses version control to manage collaborative development. Well if they don't am sure you won't be there wanting to work for them...right? Yes, right.

Done with all the introduction and already taken your seat. Your team-lead tells you to get comfortable and that you would be receiving instructions in your email in a couple of minutes regarding getting started, things to configure, account credentials blah blah, etc. etc.

And true to his words, in a couple of minutes your Github username and password arrives in your inbox accompanied by the repository URL you would be working with. Also with those came some additional jargon about common practices, style guides, team practices, schedules etc.

You take about 30 minutes to get acquainted with the new materials you have just received...

...done, cool stuffs in general but now It’s time to set up the project you would be working on!

Even though no one says it is, you feel this innocuous task of setting up your working machine, is somewhat of a test. And you can literally feel eyes behind your back watching to see how you would proceed. But before starting to hyper venting you do yourself a huge favour -- tell yourself  “c'mon, don’t be that paranoid”.

You take a deep breathe and quickly proceeded to doing what needs to be done.



So you log into your new Github account! Confirm the credentials work, change your password and then you got down to business.

Installing Git 

Since your machine is a windows box just like mine, and your favourite Git client is also Msysgit, you headed to the site (http://msysgit.github.io/) to get it downloaded.

Getting a copy of the repository (via HTTPS)

Now you have a Git client on your machine, the next thing to do is to get a copy of the code base from Github. From the email you received, the URL for the repository is https://github.com/blogpost/chacha.git.

So you create a directory "project" where your repository would be and used the necessary command to get things started. That is:

cd chacha

git clone https://github.com/blogpost/chacha.git

to fetch the repository.

This creates the "chacha" directory and clones the remote project into it.

You switch to it cd chaha

…easy does it.

Getting a copy of the repository (via SSH)

You noticed that the URL to the repository you just used is HTTPS. Well if it were an SSH link, you would have easily gotten a copy of the codebase just as you did with HTTPS. It won’t have fazed you.  You would have just had to generate a private/public key, have the public key on Github and keep the private key on your machine. You might have done this by getting http://www.openssh.org/. Have it installed, then use the ssh-keygen command to generate your keys. These would have then created two keys/files for you.  An id_rsa file that would have been saved in your .ssh directory in your home directory.  And an id_rsa.pub file which would have contained the public key. The content of the public key would have been what you update your Github account setting with just as stated here: https://help.github.com/articles/generating-ssh-keys

Dealing with Branches

Now that you have cloned the project, you head to the Github page of the repository to actually see what’ sup. You see on Github that the repository actually have couple of branches. master, develop and some other feature and bug branches. You switched back to your git Client to see what’sup from that end also.

Local branches
So you run

git branch

to check out your local branches to see if it matches what you have in the remote. You see only master listed...hmmm

Remote branches
To be sure what’s going on, you decided to check the remote branches again. This time around, doing so from your Git client. So you run the command:

git branch -r.

And not surprisingly, you see all the branches you know are there.

Seeing remote and local branches
To see both your remote and local branch in one go you used:

git branch –a


which basically showed you what you already know. Your local branch consist of only the master while the remote branch is up to date.

Checking out Branches and Tracking

So all is well and good. You just need to be able to have the develop branch as a local branch, not just the master branch. Since the develop branch is already in your remote and you can see it via git branch –r. You simple do:

git checkout develop.

This automatically creates your local develop branch checks it out from develop in remote and tracks it.

Fetching Branches

So far so good, everything is going fine. So you tell the team-lead that your work station is set up. And you already checkout the develop branch. Cool he said, but to get you started he said he created another branch, which he would be pushing in a couple of minutes. This new branch is supposed to get you started by exploring the code base to fix some little sample bugs.

After about a minute he told you that the branch has been pushed and it is called gettingstarted: Now you need to get your hands on this new branch.

So you run:
git fetch origin gettingstarted.

But you could have left out the gettingstarted part. As running just git fetch origin would fetch you all new branches and update existing ones.

Creating Local Branches, Committing, Rebasing, Merging and Pushing

You now have the gettingstarted branch. You switch to it (checkout) by running:

git checkout gettingstarted.

But as a personal practice you usually do not work in the feature branch itself. You create another branch off it, work on this, then merge back to original branch and then push changes. So to do this, you need to create a new branch.

Create new Local branch

You create a new local branch via:

git branch –b gettingstarted-local

Committing changes

You then proceed to identify the first bug and fix it. After your first fix, you now need to commit. This you do by running:

git commit –am "my very first commit fix"

Undoing changes not committed yet

First commit down. You continue working. Editing, saving changes. Coding, more edits and more files saved. Then you realize that the changes you have made thus far, since the last commit, needs to be done in a different way!

You need to reset your files to how it was after the commit.

But pressing "ctr+z" on all the files you edited does not seem to be the most effective way to go about this. But you know there are commands you can use to add, remove, reset local changes. To find out the specific commands you remember they are listed if you ask Git for the current state of your local repository. So you run:

git status

to find out. And just as you expected you could see information about the state of your project and the necessary commands you need to run in other to add, remove or resets things. Isn't that just nice?

Undoing commit

15 minutes down the line you make another commit, but only to quickly realize that the changes you just committed is not necessary. Well you could actually fix this by making another commit that removes/resets the edits in the previous commit, but since you thought that might not be the cleanest way to go about it, you decide to, all together, undo the previous commit you made. So you achieved this by running:

git reset –soft HEAD^


Pulling.

So now you done with the fix you have made in gettingstarted-local. Now its time to put those changes back in your local copy of gettingstarted branch and then push it to remote. So the first thing you do is to switch back to gettingstarted branch using git checkout gettingstarted. Since you are not the only one working on the code base, you need to be sure that, since you started working on it, none of your teammates have pushed new changes gettingstarted. And if so, then you need to update your copy. So you run:

git pull origin gettingstarted


you might as well have ran git pull. Since your gettingstarted branch is already set up to track the remote one.

Rebasing

After pulling to gettingstarted you checkout gettingstarted-local.

Now is the time to rebase. So you run:

git rebase gettingstarted

realizing that what this does is to take the updated version of gettingstarted (that might have or not have new changes) and make it the base of the changes you have made in gettingstarted-local, meaning that we might as well say you effectively made your changes on top of the latest gettingstarted.

Merging

Now gettingstarted-local has your changes and its based on the latest copy of gettingstarted. Now you switch back to gettingstarted and do a git merge. That is, you run:

git merge gettingstarted-local

meaning you merged the changes you have in gettingstarted-local to gettingstarted.

Pushing

Now you have your gettingstarted up to date with your fixes from gettingstarted-local. All you now need to do is push. So you run:

git push origin gettingstarted,

knowing fully well that just git push would do as well since the branch is being tracked.

Caching Username and Password

Since you cloned the project using the HTTPS link, before you can push, the git client prompted you for your username and password. Well this would quickly become annoying and inconvenient if you have to do this every time you need to push. So instead would rather have git cache your password. So you check out how to do this https://help.github.com/articles/set-up-git#password-caching

But maybe it seems like a long process. And you would rather just switch to the SSH url instead, since with SSH, your private/public key takes care of authentication.

Updating Remote URL

Since you cloned the project using the HTTPS link this is automatically configured as the remote URL for the repository. But you know, this is not fatal and it can be changed. In other to switch to the SSH link you need to update your remote URL, and this you do by running:

git remote set-url-ssh origin


Creating Aliases

Before you continue with your work, you take a moment to set up shortcuts (aka aliases) for the git commands you use often. Well who does not like shortcuts! To do this you made use of the format
git config --global alias.<aliases> <git command>

so you quickly typed all these

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
git config --global alias.hist 'log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short'
git config --global alias.type 'cat-file -t'
git config --global alias.dump 'cat-file -p'
git config --global alias.go 'git checkout'

while you are at it, you realized that having a short cut for undoing commits might also be useful. So you went ahead and added
git config --global alias.undo-commit 'reset --soft HEAD^'
Nice!

Deleting branches

Now you have pushed gettingstarted, it is time to delete gettingstarted-local. You run:

git branch –d gettingstarted-local

to do just that.

Tracking Remote Branches

You realized that you got your develop branch and gettingstarted created and tracked by fetching the branches and checking out. Sometimes you may need to achieve the same objective, that is, having a local branch track a remote branch. So you took note of the options available to get this done.

git checkout --track origin/mybranch

which will create a local branch named mybranch, tracking the remote branch origin/mybranch

or


git checkout -b mybranch origin/mybranch


And if you already created a local branch (let say foo) and is currently checked out and you later decide to have it track a remote branch. You know that this command:

git branch -u origin/foo

gets the job done as it lets your local foo track the remote. In case foo is not currently checked out you do

git branch -u origin/foo foo instead.


Pushing and deleting branches

Just after lunch you happen to come up with a really cool idea that is easily implementable and scores a high point in the "it solves a problem for our users" rating. You told the team-lead about it. He likes it. So right away you start working on it. But as you know, new features don’t (shouldn’t) start in the develop branch, you create a local feature branch for the cool feature you want to implement: Say you call it reallycoolfeature.

But to implement reallycoolfeature, other developers would have to contribute code too. So you have to push this new branch to the remote. Easy does it, you just issue the command:

git push origin reallycoolfeature


and the reallycoolfeature branch is available for others to work on.

3 hours down the line, the feature is finished, tested and merged back to develop. It is now time to delete the reallycoolfeature branch. Doing this is easy.

git push origin :reallycoolfeature


takes care of that!

And just like me you have a collection of useful git resources you keep bookmarked. So while you are at it you decided to update your list:

No comments: