Before you read much farther here, I just want to let you know that this post is mostly for my own personal use as a consolidation of scattered Git notes I’ve been keeping around… It’s my Git crib sheet describing some how-to’s and the why’s behind them. I’ll probably be updating this post on occasion as I find or figure out new Git goodies. Hopefully C4SC readers can find a gem or two in here.

 

Create a New Local Branch

The following command creates a new local branch in your Git repository. The workflow first switches to the local master branch and pulls all of the latest remote changes. The --rebase argument tells Git not to merge the remote master branch into your local master branch, but to replay all of the most recent individual remote commits on local master instead. Git will replay all of the commits in succession since your local master’s HEAD commit rather than forcing you to perform a single commit for the whole merge. The checkout -b command tells Git to create a new local branch and then check it out.

git checkout master
git pull --rebase
git checkout -b <new-branch-name>

Pull Remote Changes Locally

Most of the commands here look very similar to the example above, but we’re assuming an existing child branch here (off master) rather than needing to create one. The additional step here is that after updating master, we update the child branch as well. After switching to the child branch, calling git rebase master replays all of the commits to master (since your child branch’s HEAD commit) onto your child branch. Just as in the example before, the rebase command forces Git to avoid a single merge commit in favor of replaying all of the individual commits in master onto the child branch.

git checkout master
git pull --rebase
git checkout <child-branch>
git rebase master

 

Merge Child Branch Into Master (and Push It to Origin Master)

Before merging a child branch into master, you’ll want to repeat all 4 commands in “Pull Remote Changes Locally” prior to the merge to ensure you have the latest remote changes before merging any code. If you don’t do this, Git will force you to do it anyway… One more reminder – after getting all the remote changes and performing your merge, run your unit test suite locally to make sure nothing is broken. If you don’t do this, you deserve whatever hazing you get if you break the build.

A quick note here (because this is different than the last two steps)… When merging a child branch into master, since you updated your child branch by rebasing from master in the previous step “Pull Remote Changes Locally”, your child branch changes are fast-forwarded onto the master branch HEAD commit. This ensures that only the changes you performed on the child branch are committed to master just as if they had been done on master rather than the child branch. This keeps all of your local branch information from showing up in your remote repository (git push origin master). Why? I may have performed LOTS of commits and applied LOTS of refactorings to my child branch to get it ready to merge – I may have even used several local branches to accomplish the task. I don’t want to sei all of the local branch information in the remote repository. This is beneficial for the overall upkeep of the project because other developers may have local branches named the same as yours causing serious conflicts if all the local branch information appeared in the remote repository. This makes everyone’s job easier to integrate local changes when pulling remote changes.

git checkout master
git merge <child-branch>
git push origin master

 

Undelete a Deleted [Staged] File and Roll It Back

As far as Git is concerned, this is one of the easiest operations to perform. However, if you’re used to a nice right-click context menu option in Visual Studio or some other IDE, it might be one of the hardest to remember… In your head you’re saying “Undo Changes” or “Revert File”, but Git requires a two-step approach. The workflow here is to unstage the deleted file and then get the latest repository version by checking it out.

git reset HEAD /some-directory/file.txt
git checkout /some-directory/file.txt

 

Rename / Move a File

The following command is a shortcut. If you chose not to do it this way, you’ll end up with a few more calls. This prevents you from having to add the new file (along with tracking it) and remove the old file in separate commands. If you haven’t yet begun tracking the file you want to move, just remove the git mv command in favor of just mv since Git doesn’t know about it yet.

git mv <file-name> /new-directory/new-file-name

 

Resources

Pro Git -- Scott Chacon (ProGit.org)

Git for Subversion Users – Derrick Bailey (Code-Magazine)