# Git Workflow
Jun 24, 2015 7 minute readI 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 statusDisplays 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 statusgit checkout -- .discards all the pending changes in the working copy. It makes no effect on untracked files.git clean -fdeletes all untracked files from the working copy.git statusat 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_branchgit checkout masterswitches to the master branch.git pullgets master’s latest version.git branch my_new_branchcreates a new branch namedmy_new_branchoff the latest version of master. 2git checkout my_new_branchstarts using the newly created branch. Upcoming changes will go intomy_new_branch.
Inspect pending changes
git diffDisplays 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_branchgit add -Astages 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.git commit -m "committing all the files"creates a new commit with the staged files. This new commit has the messagecommitting all the files.git push origin my_new_branchpushesmy_new_branchto the remote tracking branchorigin/my_new_branchin 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 *.jsSometimes 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_branchDisplay 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/mastergit fetchdownloads the commits from remote branches but it doesn’t merge them.git merge origin/mastermerges 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 masterRebase from master
git pull --rebase origin masterRebasing 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 mergetoolLaunches the configured merge tool once per conflicted file. 8
Leave what you’re doing to do something else
git stash -u && git statusgit stash -ucreates a stash with all the pending changes, including untracked files. 9git statusat 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 popStashes 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 resetgit reset --soft HEAD~1removes the last commit from the history. Its changes are put back into the staging area.git resetunstages 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.
-
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. ↩
-
If branches feel like a drag, look for Branchless development ↩
-
Git Extensions for Windows and SourceTree for Mac. ↩
-
There are no clearly defined rules for commit sizes. I prefer commits to be very small. ↩
-
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. ↩ -
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. ↩
-
Go to this Atlassian tutorial to learn more about rewriting history. ↩