Tdd Apps Blog

Git Workflow

Jun 24, 2015 6 minute read

I worked in a place with a horrible Git1 repository. This repo was so slow that git status usually took more than two seconds. Deprived of a fast GUI tool, the command line became the tool of choice. These are my most frequently used commands.

How is the working copy doing

git status

Displays the current branch and the list of modified files in the working copy. Once it displays nothing to commit, working directory clean you’re good to start working.

Cleanup everything

git checkout -- . && git clean -f && git status
  1. git checkout -- . discards all the pending changes in the working copy. It makes no effect on untracked files.
  2. git clean -f deletes all untracked files from the working copy.
  3. git status at this point should say that everything is clean. Failures need to be resolved on a per case basis.

Create a new branch

git checkout master && git pull && git branch my_new_branch && git checkout my_new_branch
  1. git checkout master switches to the master branch.
  2. git pull gets master’s latest version.
  3. git branch my_new_branch creates a new branch named my_new_branch off the latest version of master. 2
  4. git checkout my_new_branch starts using the newly created branch. Upcoming changes will go into my_new_branch.

Inspect pending changes

git diff

Displays the changes detail in a diff format, except for staged changes and untracked files. Although it is very fast, git diff becomes almost useless for large changesets. On the other hand, the majority of GUI tools come preloaded with excellent diff capabilities. 3

Commit everything

A commit is a unique changeset. 4

git add -A && git commit -m "committing all the files" && git push origin my_new_branch
  1. git add -A stages all the modified and new files. The Staging Area is a snapshot of what will get committed. Staged changes will not be affected by working directory changes.
  2. git commit -m "committing all the files" creates a new commit with the staged files. This new commit has the message committing all the files.
  3. git push origin my_new_branch pushes my_new_branch to the remote tracking branch origin/my_new_branch in the remote repository. While it is not required to push every commit right away, doing so protects against losing work in case of hardware failure.

Commit only the Javascript changes

git add *.js

Sometimes it is necessary to commit only certain files. In those scenarios the git add command can be used with wildcards or specific filenames. Then the previous example becomes:

git add *.js && git commit -m "committing only javascript changes" && git push origin my_new_branch

Display the history

The commits history can be displayed from the command line. 5 However, GUI tools truly excel for this task.

Merge from the latest master

It is a good practice to sync branches frequently [citation needed].

git fetch && git merge origin/master
  1. git fetch downloads the commits from remote branches but it doesn’t merge them.
  2. git merge origin/master merges the remote master into the current branch. 6

Sometimes Git will complain in the middle of the operation and you’ll be left with a big mess. The following command is equivalent, more resilient, and definitely slower.

git checkout master && git pull && git checkout my_new_branch && git merge master

Rebase from master

git pull --rebase origin master

Rebasing is an alternative to merging. It keeps the history cleaner. However, since rebase rewrites the commits history, it is not recommended for pushed commits. 7

Solve the conflicts

git mergetool

Launches the configured merge tool once per conflicted file. 8

Leave what you’re doing to do something else

git stash -u && git status
  1. git stash -u creates a stash with all the pending changes, including untracked files. 9
  2. git status at this point should say that everything is clean. Failures need to be resolved on a per case basis.

Afterwards, it is safe to do any other operation.

Return to the previous state

git stash pop

Stashes behave as a stack. git stash pop will pop the latest stash into the working copy. In a similar way git stash apply will peek the latest stash into the working copy without changing the stack. At this point the working copy should be in the same state as it was before.

Rewrite the history

Avoid history modification when possible. 10

Something is wrong with the last commit

git reset --soft HEAD~1 && git reset
  1. git reset --soft HEAD~1 removes the last commit from the history. Its changes are put back into the staging area.
  2. git reset unstages the staged changes and puts them back into the working copy.

Afterwards, make the necessary edits and commit again. Editing pushed commits can cause serious issues. It is safer to create a new commit to correct the problem.

What broke the project

When things break out of magic, use git bisect to pinpoint the exact commit where the issue started. git bisect is such a useful tool that merits a blogpost just for itself. In the meantime, read this to learn more about it.

  1. This guide is far from being a Git reference. The avid reader will enjoy Git Succintly. It is a hundred pages book with the basic concepts of Git. 

  2. If branches feel like a drag, look for Branchless development 

  3. Git Extensions for Windows and SourceTree for Mac. 

  4. There are no clearly defined rules for commit sizes. I prefer commits to be very small. 

  5. Git Basics - Viewing the Commit History 

  6. Some developers prefer to pull directly from origin/master. I’ve encountered a fair number of issues doing this in the past not to do it again. 

  7. Visit this and this to learn more about rebase. 

  8. After some research on mergetools I settled for SourceGear Diffmerge. Nowadays, I’m more inclined to use Beyond Compare. Both are very good tools. Configuring the mergetool is beyond the scope of this guide. Mainly, because it is different depending on your setup. Here’s how to do it in SourceTree for Windows. You can also do it in the Git Extensions settings. Google is your best friend. 

  9. For more information on Git Stashes follow this link

  10. Go to this Atlassian tutorial to learn more about rewriting history.