Tuesday, January 7, 2014

A Basic GIT Workflow

I'm using GIT more and more. It's different enough from other source control systems that I ended up cobbling together a basic approach to interacting with GIT during development. This works best with development of small bits of code that are committed frequently. Oh, and I never (except by mistake) edit in the MASTER branch. I always work in a development branch that I try to name after the changes I'm making. There's a basic git philosophy about creating a lot of little (often local) branches to do your work and then merge stuff together once it's really done.

So, here is my "Typical Developer Git Workflow":

1. Create a local feature or bug fix branch

/project.dir(master)> git checkout -b new_feature

2. Make your changes and commits to the branch

/project.dir(new_feature)> git commit -am "adding awesome features"
/project.dir(new_feature)> ...
/project.dir(new_feature)> git commit -am "finally done"

3. Bring things up to date with the "master" branch

/project.dir(new_feature)> git checkout master
/project.dir(master)> git pull  # bring master up to date
/project.dir(master)> git checkout new_feature
/project.dir(new_feature)> git rebase master

Note: the last command rewinds all the changes you made, then applies all the changes that have been made on master, and then replays your changes on an "up to date" version of the code.  Here is where you'll get information about any potential conflicts to fix / edit accordingly

4. Merge your branch into master and push your changes

/project.dir(new_feature)> git checkout master
/project.dir(master)> git merge new_feature
/project.dir(master)> git push origin master

That's it - the basic development workflow - it helps people isolate their changes in a separate branch and merge things in when they're done.  They can also create separate branches - for bug fixes and multiple features they may be working on at the same time.

Some other useful commands
1. Bug fixes and release branches

When you're doing bug fixes across branches (master and a release branch that is in production) you'll use the "cherrypick" command to pull changes from one branch to another.  Let's say we have a bug fix that was committed with id 12b10f5f

/project.dir(master)> git log
commit 12b10f5fc49faedb0a9d8008ad0100a67a6cbca7
Author ...

/project.dir(master)> git checkout release-1.2  #a branch out there for release 1.2
/project.dir(release-1.2)> git cherrypick 12b10f5f
/project.dir(release-1.2)> git push  #now the change has been applied to that release too

2. Generally getting around

git log  # show me a list of recent commits
git show 12b10f5f  # show me a diff for this commit
git blame database.yml  # who wrote this code
git diff  # show me a diff of my local changes (not committed)
git status  # show me the files that are new, changed, deleted, etc.
git mv  # move a file from one name / directory to another

Tools that can help

1. Putting the current branch name in the command prompt


2. Update your ~/.gitconfig with shortcuts and colorized diffs, etc.

name = Your Name
email = your email
diff = auto
status = auto
branch = auto
interactive = auto
st = status
co = checkout
ci = commit
ca = commit -a
br = branch