In this blog post, I want to go over the steps I took to clean up the code for my CLI tool - addcom, and share how I used Git Rebase to rewrite my project's history.
If you have just stumbled upon my OSD600 series of blog posts, it has been created to document and share my learnings as I progress through my Open Source Development college course.
Enhancing the code
I've been trying to keep my code clean and modular from the start, so, luckily, I didn't have to do a lot of adjustments.
Big thanks to my friend and classmate Aryan for helping me come up with ideas for refactoring the project!
1. Making the comments more consistent
First thing that caught my eye was the the inconsistency in the commenting style across the file operation functions and the absence of comments in the main add_comments()
function. Therefore, my first change was to make commenting style consistent throughout the project.
2. Improving error handling
My second area of improvement focused on enhancing error handling within the code: I centralized the error handling by adding the try-except
block to the main add_comments()
function and modified the helper functions to throw exceptions instead of logging and abruptly exiting sys.exit(1)
. In addition to this, I wrapped all file read and write operations in try-except
blocks to ensure they perform safely.
# Check if API key was successfully set
if not api_key:
raise RuntimeError(f"Error: API key must be provided to generate comments")
vs.
# Check if API key was successfully set
if not api_key:
print("Error: API key must be provided either as an argument or through the environment.", file=sys.stderr)
sys.exit(1)
3. Enhancing the logging
Although I was printing error messages to standard error, it was difficult to differentiate warning and error logs from standard output. To address this, I added colour coding using rich.console
. Now, all warnings are displayed in yellow, while errors are printed in red.
Rewriting the project history
I made all of the improvements mentioned above on a separate refactoring
branch, and once I was satisfied with the result, I could start merging it into main
.
However, before doing so, I had to combine (squash
) all commits I've made during the refactoring into a single commit (mainly for the sake of practice, but also because all of the changes could be viewed as one refactoring commit).
To do so, I started an interactive git rebase:
git rebase main -i
This command opens the text editor, where you can specify what to do with each commit.
I used (picked
) the first commit and squashed
the second and third into it.
Tip: associate a text editor of choice with git, it will help you perform more complex Git operations
After saving and closing the file, git creates the commit that combines all the changes in a single commit.
The result of the rebase can be seen using git log
.
The log message consists of the messages from all of the combined commits, but I ended up providing a better commit message using git --amend
.
After the rebase was done, I simply merged the changes into main, using the following commands:
git checkout main
git merge --ff-only refactoring
git push origin main
Outcomes
Refactoring the code didn't cause any difficulties since I didn't need to alter the core logic. My focus was mainly on doing small enhancements and ensuring the formatting consistency.
On the other hand, rewriting the history using Git Rebase was a bit confusing at first, mainly because I had never used a text editor with Git before. However, once I integrated Git with VS Code, the process became much smoother.
I learnt how to rewrite Git History and tweak the last commit using git --amend
, so the overall experience was a success!