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

Git and DropBox - An Approach for Small Projects and Small, Distributed Teams

I work on any number of software development projects and over the years have worked my way through any number of source control systems: RCS, CVS, SVN, until now (finally) I've landed on GIT.

Although GIT can be used with only a local repository, I always set it up on a remote repository, basically for two reasons: to have a backup in the event something happens to my computer, and to share the code with other developers, or even with another computer of my own. For some projects, we've created a GIT repository on one of our servers. For others, we've used GitHub, which is fantastic, IMO.

Creating a project repository in GitHub is perfect for projects that are being developed for public access and use, but to create a private GitHub project requires a paid-for account. And while the cost is not huge (~$8/mo at this writing), it would be nice to have an alternative, cost-free option. Enter DropBox.

I use DropBox all the time for transferring files between people and even between multiple computers of my own. It's just too easy. And on most projects in which I'm involved, the whole team uses DropBox to share files. So wouldn't it be cool if I could simply create a GIT remote repository in DropBox and share that with the development team? Yeah. So what we'll do here is set up a "bare" GIT remote repository under DropBox and then use that to capture a project's code. Importantly, this is a bare repo - it's not meant for any developer to commit to directly. Instead, developers should clone from this repo, commit locally, and push back to it.

So here's what I did:

  1. Download and install GIT (http://git-scm.com/downloads).
    While this includes some GUIs, I use the command from a terminal. So after installing, open a terminal or a command window and...
  2. Create a directory in DropBox for the repository. I used git_repos. Then cd into that.
  3. Initialize a git repository:
    git init --bare myproject.git
    You should see a message something  like this:
    Initialized empty Git repository in .../Dropbox/git_repos/myproject.git
    And you should see a DropBox notification of this as well.
And that's it. The bare GIT repository is created. if you look in the myproject.git directory, you'll see all the GIT folders and files.

Now, we can create or add a project to this repo using normal GIT commands:
git init
git add .
git commit -m "initial GIT commit"
git remote add origin 
git push -u origin master
The URL is important. It needs to point at that new DropBox repository, something like this:
This value will get written into the .git/config file in the project directory and will be used as the location for the "origin" or remote GIT repository.

Other developers on my team can now clone from this:
git clone d:/DropBox/.../git_repos/myproject.git myproject
and so on.