close
close

Refactor, revision, rebase – DEV Community

This week in my Open Source Development class, my classmates and I were given a task to think about three ways Unpleasant refactor the code we wrote for our command-line tools.

Below is my GitHub repository for my command line tool gimme_readme:

gimme_readme is a command-line tool, powered by AI, that generates a comprehensive README.md file for your project. It analyzes multiple source code files at once and provides concise explanations of each file’s purpose, functionality, and key components, all in one easy-to-read document.

gimme_readme is a command-line tool, powered by AI, that generates a comprehensive overview README.md file for your project. It analyzes multiple source code files at once and provides concise explanations of each file’s purpose, functionality, and key components, all in one easy-to-read document.

gimme_readme-0.1-demo-revised

Check out our 0.1 release demo!

Table of contents

  1. Get started
  2. Usage
  3. Example usage
  4. Supported models by providers
  5. Contributions
  6. Test locally
  7. Author

1. Getting started

To start with gimme_readmeFollow these steps:

  1. Install the latest version of Node.js for your operating system.

  2. Run the following command to install gimme_readme worldwide:

    npm i -g gimme_readme
    Go to full screen mode

    Exit full screen mode

    NOTE: MAC/LINUX users may need to run this program sudo npm i -g gimme_readme

  3. Generate a configuration file by entering each desired folder:

    gr-ai -c
    Go to full screen mode

    Exit full screen mode

    This command creates a .gimme_readme_config file in your home directory. Do not move this file from this location.

  4. Open the .gimme_readme_config file and add your API…

Before we get into it What I have reprocessed it, I think it is best to clarify it What refactoring is. Refactoring is the process of improving the internal structure of your code without changing the current functionality. For comparison: revising has the connotation of making changes that can change the current behavior of your program (hopefully for the better).

Now that the definitions are out of the way, let’s take a look at what I modified.

For me, the most obvious thing I could do to refactor my code was to facilitate better file organization within my repository.

I want to organize my repository in such a way that the story of the project is told. By placing files in logically named folders, everyone should be able to navigate through them easily and know where each file belongs.

This is what my repository’s file structure looked like prior on my changes:

for

This is what the file structure of my repository looks like now:

after

The hope with this refactoring of my project’s file structure is that contributors, as well as myself, can quickly reason: “if I want to work on the ai-related logic of this program, I should probably look into my ai folder”.

But wow – this was one lot of the work to be carried out.

By trying to move my ai_config folder and ai_models folder in the ai folder, I also had to use the abundance from other files that depended on it on the files in these folders.

Look how many files I had to change simply because I wanted to rename my folders:

renaming-influences-a lot

Take a look at this end result:

ai-map

The end result, in my opinion, is a lot nicer: the right files are now where they should be.

As an aside, you’ll notice that when I ran:

git status -s
Go to full screen mode

Exit full screen mode

You could see files with the extension R next to it – this is to indicate that these files were located renamed and that git is aware of this.

git is aware of this renaming because I was executed git mv commands like this:

git mv tests/unit/ai_models/groqModels.test.js tests/unit/ai/models/groqModels.test.js
Go to full screen mode

Exit full screen mode

Now – why should you care?

Well, if you were in a situation where you wanted to rename your existing files in a git repository, and you it didn’t usage git mv If you want to rename your files, you may encounter several problems:

  1. Loss of file history: If you manually rename a file (for example, using your operating system’s file explorer or a command like mv), git will interpret this as two separate actions: deleting the old file and creating a new one. This means you’ll lose the history of the file in git, making it harder to track changes over time.
  2. Confusion in diffs: When you view changes or create pull requests, the diff will show a file deletion and a new file creation instead of a simple rename. This can make code reviews more challenging and time-consuming.
  3. Merge conflicts: Renaming files without git mv can lead to more merge conflicts, especially if other team members are working on the same files.
  4. Incomplete tracking:git will not automatically track the relationship between the old and new filenames, which can complicate operations such as reverting changes or inheriting commits.

By using git mv you ensure that:

  1. File history is preserved:git maintains the entire history of the file, just under a new name.
  2. Clean diffs: When you view the changes, it is clear that a file has been renamed rather than deleted and recreated.
  3. Smoother merges: git can handle merges more intelligently if it knows a file has been renamed.
  4. Proper tracking:git correctly maintains the relationship between the old and new filenames, allowing operations such as to wind back changes easier.
  5. Efficiency: git mv is a single action that both moves the file and updates Git’s index, eliminating the need to run separate mv and git add/rm commands.

In short, you should use git mv to guarantee that git can track the changes to your files even if they have been renamed.

Now – all that git mv / company renaming was mine First repetition of the changes I wanted to make.

The next change I made was actually quite minor in comparison.

All I did with my next change was extract a functionbased on the guidelines of this website here: https://refactoring.com/catalog/extractFunction.html.

This is what I had for I extracted my function:

before extraction

This is what I had after I extracted my function:

extract function

Regarding this particular one refactoring of my code I was actually reluctant to do it because in my eyes the original logic was actually clearer to me than the refactored version. Not that I think extracting functions inherently wrong, but even more so because that was not the case in this particular case reusability factor in that.

To give you a clearer idea of ​​what I mean reusabilitylet me show you an example of what I saw in the Visual Studio Code warehouse.
It says in one of their files src/vs/base/common/arrays.tsthey define the function, sortedDiff that defines a subfunction therein.

I think this would be a better example of when extracting a function as described in https://refactoring.com/catalog/extractFunction.html would be appropriate.

Check out the code below:

extract-a-function-vscode

In this example, the subfunction (pushSplice) not only serves as a way to document certain steps, but also serves as logic repeated within the outer function (sortedDiff).

This is when I think it would be more appropriate to extract a feature – but others may think differently! For others, a feature is worth more than comments explaining the code – I can agree with that point of view too.

But without delving further into that topic, let me show you the third change I made, where I took some common logic between two similar files and placed it in another file. Below is the extracted logic, placed in a new file:

extracted logic

Below you can see how my existing files benefited from this new file (there is now much less code in both files)!

example-1

example-2

With that I refactored my code in 3 different ways!

But wait: that’s not the end of the lab.

Every change I made to my repository for the purpose of refactoring, I did so formalized those changes with git commits.

commit-history-before-rebase

However, there are times when you need to know how to do that squash multiple commits in one so you don’t blow up your git repository history.

Let’s demonstrate how to use the git rebase -i command (de i stands for interactive) Unpleasant squash our obligations.

Run git rebase main -i will open one text editorso you can see it git how to handle your commit history – this opens by default vim.

interactive-rebase-for-squashing

Let’s actually edit the file so we can see it git we want to merge our commits into one commit.

interactive-rebase-after-squashing

REMARK:

  1. to close vim And to rescue your changes:
    1. Busy ESC
    2. Than :wq
    3. Busy ENTER
  2. to close vim without save changes:
    1. Busy ESC
    2. Busy :q!
    3. press ENTER

For me, I saved my changes and was greeted with this other interactive screen, which shows you which commits you are squashing:

confirmation

You will need that too save and also exit this screen.

After you do this, you will be greeted with something like this:

after

Let’s run git log --all --graphto visually see our changes.

git-log-all-graph

You’ll notice that the commit message from the squashed commit doesn’t look very nice.

Let’s have one amended commitvia git commit --amend. Below you can see that I have edited the commit message a bit.

edit-commit message

Let’s save up and get out vim.

After making adjustments to our commit history, we end up with something like this:

rebased-commit message

Now let’s switch to our local headquarters and make the changes from our refactor branch by running:

git checkout main
# We should be able to do a simple fast-forward merge
git merge --ff-only refactor
Go to full screen mode

Exit full screen mode

fast forward-merge

Now let me push my changes to my main branch on GitHub (normally I wouldn’t do this, but this is for demonstration purposes!).

github

That pushed my commit to GitHub!

So to summarize, this week was a lot of fun, working on making at least 3 changes (where each change involved refactoring our code) and using git rebase --i main to destroy our obligations.

I hope the pictures and story helped!

Cheers!