Learning Git Rebase

Mayank Kumar - Oct 11 - - Dev Community

This week, I worked on refactoring my project, dev-mate-cli. As with any refactor, my primary goal was to improve the codebase by making it cleaner and more modular. However, the process didn’t stop there - I also took this opportunity to practice using Git’s interactive rebase feature to tidy up my commit history.

GitHub logo mayank-Pareek / dev-mate-cli

A command line tool to quickly document your code

dev-mate-cli

A command-line tool that leverages OpenAI's Chat Completion API to document code with the assistance of AI models.

Watch this Demo video to view features.

Features

  • Source Code Documentation: Automatically generate comments and documentation for your source code.
  • Multiple File Processing: Handle one or multiple files in a single command.
  • Model Selection: Choose which AI model to use with the --model flag.
  • Custom Output: Output the results to a file with the --output flag, or display them in the console.
  • Stream Output: Stream the LLM response to command line with --stream flag.

Installation

  1. Clone the repository:

    git clone https://github.com/mayank-Pareek/dev-mate-cli.git
    cd dev-mate-cli
    Enter fullscreen mode Exit fullscreen mode
  2. Install dependencies:

    npm install
    Enter fullscreen mode Exit fullscreen mode
  3. Set up environment variables:

    Create a .env file in the project’s root directory by making a copy of .env.example file:

    cp .env.example .env
    Enter fullscreen mode Exit fullscreen mode

    Replace API_KEY and BASE_URL values with an API Key and URL generated from a Open AI's…

Refactoring Goals

Before diving into Git, I wanted to focus on improving several aspects of my code:

  • Modularity: Breaking down large functions into smaller, reusable components.
  • Error Handling: Improving how the application handled different input paths.
  • AI Response: Refactoring how the program interacted with OpenAI's API, ensuring better separation of concerns.
  • Performance: Making the file handling code more efficient by introducing recursion for processing directories.

Step-by-Step Refactor

Here’s a breakdown of the steps that I took to refactor dev-mate-cli:

  1. Move File Processing to fileHandler
    My first task was to clean up the code responsible for file processing. Previously, this logic was mixed with the part of the code that handled the setup of cli program in program.ts. To improve modularity, I moved the file processing into a dedicated fileHandler module. This separated the concerns, making the code easier to maintain and test.

  2. Make File Path Processing Recursive
    Since I was already working on the file processing, I saw an opportunity to add more robustness. The function initially handled file paths but didn’t traverse directories deeply. I enhanced it by adding recursive logic to handle directories, ensuring the program processes every file within subdirectories as well.

  3. Split AI Response Logic into Separate Functions
    One function was doing too much—handling the AI request and response in one go. To simplify this, I broke it down into two functions: one for generating the response and another for handling what happens afterward. This separation of concerns not only made the code cleaner but also easier to extend in the future.

  4. Fix Token Usage Output When Streaming Response
    While streaming AI responses to the command line, I discovered that the token usage report wasn’t working as expected. This was due to incorrect handling of response chunks when streaming. I fixed the logic so that token usage would now be correctly displayed, even when data is streamed to the command line.

  5. Add Interface and Fallback for Program Options
    To ensure that the program handled missing options gracefully, I added fallback values for the model and temperature. I also created an interface to define the options type, improving type safety and making the code more predictable.

Git Rebase: Interactive Squashing

Once all the changes were made, I turned my attention to the commit history. I had made 5 separate commits, each representing a logical change. To keep the Git history clean, I decided to squash these commits into one using Git’s interactive rebase feature.

  1. Ran git rebase main -i to start an interactive rebase with main branch.
  2. Squashed the 5 commits into one.
  3. Amended the commit message to summarize all the changes in a clear and concise manner using git commit --amend command.
  4. Merged the topic branch into main branch using fast-forward merge.
  5. Pushed the new commit to origin using git push origin main.

The interactive rebase was smooth, and I found it to be an invaluable tool for maintaining a clean project history. I also learned how important it is to commit often but keep the history readable for maintainers and collaborators.

The final commit can be checked here - https://github.com/mayank-Pareek/dev-mate-cli/commit/16fe682e17cd0983d793298adfee504b16d71537

. . . . . . . . . . . .