When introducing code changes across an existing code base, it can be difficult to detect which new change broke the camel’s (or the app’s!) back. Git is an excellent tool to avoid getting caught in Command+Z hell. My git workflow is based on the convention of making small commits of changes that you know work properly.
In this overview of my workflow, I’ll cover the following:
- Adding and committing in patches
- Checking out files to discard changes
- Resetting to a previous commit
- Fearlessly force pushing
Let’s say a new function is introduced:
And a test for it is added immediately after, like always, right?
The test passes, so both the function and the test are added and committed. Later on, the return text needs to be altered.
Because this is a small change and that undoubtedly won’t break anything (famous last words…), the output is printed to eyeball it as a quick test and I decide to commit this seemingly non-breaking change:
git add -pin order to keep only the changes we want to commit. If given the
soption to split the changes, we can choose
n, or no, to not include the print statement, and
yfor yes to include the functional code change. Note: If you cannot split the hunk, use the
eoption to manually edit the hunk. This will drop you into the vim editor allowing you to delete the print statement.
- Check your git status; you will see one staged change and one unstaged change. Commit the staged change.
- Use git checkout to discard the print statement.
Using git add or git checkout with the patch flag is better practice than deleting code by hand. With the latter, you can easily introduce unnecessary new lines or spaces or delete ones that were there before, leading to a less clean diff in your pull request.
When running tests later, the change previously made to
say_hi would cause the associated unit test to fail.
In this case, a space will be added after the comma in the
say_hi function, and the test will pass. I would then squash this commit with the commit introducing the function. However, for a more complex change that you’d like to start from scratch to solve, you can reset back to your previous commit:
git reset — hard <commit SHA>.
If you have already pushed changes up to that point to origin, you can git push with the — force flag to overwrite your remote changes (Note: This should only be done once you’re sure of the changes you are making, lest your hard work disappear forever!).
Git can be an extremely useful tool in software development by keeping track of all changes you make to a code base, and there are a myriad of options to customize your workflow to ensure clean pull requests and a useful log history.