DEV Community

Peter Wan
Peter Wan

Posted on

'git'ting funky with git merge

Hello all, and welcome to my blog!

Today, I'd like to walk you through my experience using git merge in my command-line project, gimme_readme.

GitHub logo peterdanwan / 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, providing concise explanations of each file's purpose, functionality, and key components, all in a single, easy-to-read document.

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, providing concise explanations of each file's purpose, functionality, and key components, all in a single, easy-to-read document.

gimme_readme-0.1-demo-revised

See our 0.1 Release Demo!

Table of Contents

  1. Getting Started
  2. Usage
  3. Example Usage
  4. Supported Models by Providers
  5. Contributing
  6. Testing Locally
  7. Author

1. Getting Started

To get started with gimme_readme, follow these steps:

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

  2. Run the following command to install gimme_readme globally:

    npm i -g gimme_readme
    Enter fullscreen mode Exit fullscreen mode

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

  3. Generate a configuration file by running in any folder you'd like:

    gr-ai -c
    Enter fullscreen mode Exit fullscreen 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…

For context, I am a student at Seneca Polytechnic, enrolled in the Topics in Open Source Development class.

To hone our skills in open source development, each member of our class has been tasked with developing a command-line tool and using git and its various commands to maintain our projects.

This week's topic involved integrating git branch and git merge into our development workflows.

TL;DR: Working with git branch and git merge

If I had to sum up the general workflow I've adopted when using git branch and git merge (not dealing with GitHub pull requests yet), it would go like this:

  1. Avoid directly developing on the main branch of your git repository.
  2. Keep your main branch stable — it should represent the working version of your project. Create topic branches that originate from the stable main branch.
  3. Once a topic branch is stable and its feature or fix is complete, merge its changes into the main branch using git merge.

Note: A topic branch refers to a branch that is created for a specific feature or issue. It is separate from the main branch to avoid instability in your main codebase.

My Git Workflow

Now that you know my general approach—keeping the main branch stable while working on topic branches—let's dive into the specific task my colleagues and I had to complete this week. The full details of the lab can be found here, but I'll summarize it below.

We were asked to work with two GitHub issues in parallel on different branches. Here's a breakdown of the steps we followed:

  1. Start from the main branch:

    First, ensure that the main branch is stable and no new commits are made to it directly during this process (these conditions might not happen in real life, but this lab's purpose was to get our feet wet with regards to dealing with merge conflicts - more on that later). From this branch, create two new topic branches. Each branch will originate from the same point in the main branch's history (the most recent commit).

    To create a new branch, you can use either of the following commands:

    # Option 1: Basic branch creation
    git-repo(main)$: git branch <new-branch-name>
    # Example: Creating a branch for issue 11
    git-repo(main)$: git branch issue-11
    
    # Option 2: Specify a starting point (usually unnecessary if you're already on main)
    git-repo(main)$: git branch <new-branch-name> <starting-point>
    # Example: Creating a branch for issue 31
    git-repo(main)$: git branch issue-31
    
  2. Create two topic branches:

    • The first topic branch should address one GitHub issue.
    • The second topic branch should address another, separate GitHub issue.
  3. No sharing code between branches:

    Even though it might seem easier to combine fixes or share code across branches, the goal was to isolate each change on its respective topic branch.

  4. Finish development on each branch:

    Once the development on a topic branch is complete, ensure that the branch is stable and ready to be merged into the main branch.

  5. Merge the first topic branch:

    Once your first branch is complete, merge it into the main branch. This should result in a fast-forward merge, where the commits from the topic branch are simply appended to the main branch's commit history.

  6. Merge the second topic branch (dealing with merge conflicts):

    After merging the first branch, merge the second topic branch into the main branch. At this point, you may encounter a 3-way recursive merge, which will likely result in a merge conflict if there are overlapping changes between the two topic branches.

Merging my branches into main via git merge and dealing with merge conflicts

As mentioned earlier, I had to do development on 2 branches starting from main.

The branches I made were:

  1. issue-30: which involved ensuring my command-line tool doesn't send particular files that are matched by a pattern in a .gitignore where my command-line tool is executing (i.e., the current working directory or cwd). issue-30-demo

NOTE: The reason I named this branch issue-30 is because there was an issue opened on GitHub with that number.

  1. issue-11: involved ensuring that in addition to writing out a whole file's name when supplying filenames to my command-line tool, I could instead provide globbing patterns so the user won't have to type as much when they intend to send multiple files to my command-line tool issue-11-demo

NOTE: The reason I named this branch issue-11 is because there was an issue opened on GitHub with that number.

Below is a screenshot of what my branches looked like visually, before merging anything:

branches

It'll be good to refer to this graph as I explain what's happening in the merge.

Merging my first branch, issue-30 onto my main branch

After ensuring that my code worked well enough to the point that I thought it was "stable", I began merging my different branches, starting with issue-30.

git-merge-issue-30

Notice how it did a fast forward merge. This is because git knew that these commits really just come right after the main branch's commits. If you observe my earlier screenshot, it showed that my issue-30 branch had 2 commits from the base commit.
NOTE: the base commit is the commit that is the common ancestor for a particular branch. When dealing with merge conflicts the base commit is the commit that is the common ancestor of the incoming and current changes that are in conflict with each other.

Now, look at the my git branches:
main-and-30-are-the-same

With git log --all --graph, we can see that main and issue-30 are sitting on the same commit. Things look pretty good right now! But now... we're going to have some fun (spoilers: we're going to get a merge conflict).

Merging my second branch, issue-11 onto my main branch after merging issue-30 first

git-merge-issue-11-conflict

While merging the first topic branch was smooth, the second branch posed a challenge when I encountered a merge conflict.

Below, is a screenshot showing some of the conflict markers that separate my Current Change (i.e., what's on my main branch and on the left-hand side) vs. my Incoming Change (i.e., what's on my issue-11 branch on the right-hand side).

current-vs-incoming

It's important to note that both the Current and Incoming change are relative to the base commit.

Using the conflict markers for context, I resolved the merge conflict by creating a hybrid solution inspired from both my current and incoming changes.

resolving-the-issue

After testing that my solution was working, I was ready to resolve this merge conflict once and for all. I used git add to add the file with merge conflicts and used git merge --continue to continue the merge that was stopped due to the merge conflict.

git-merge-continue

When you do git merge --continue, it opens up vim, showing you the commit that you're about to make. If things look good to you, you can simply write :wq to save the commit. That's what I did.

commit-message

Now, for the final time, let's see what our graph looks like:

3-way-merge

You can see that we managed to do a 3-way merge, (NOTE: the 3 comes from the base, incoming changes, and the current changes).

Pushing my stable changes to GitHub

With my main branch finally stable, I:

  1. Pushed these changes to my GitHub repository.
  2. Closed out the GitHub issues that I resolved:

... and that concludes the details of my experience performing a fast-forward merge and a 3-way merge.

Closing Thoughts

The experience of using git branch and git merge this week really helped me understand how to work on multiple features at once without affecting the stability of the main branch. Merging is an essential part of the development process, and encountering and resolving merge conflicts is something every developer will face at some point.

If you’re working on a project that involves branching and merging, my advice is to take your time when handling merge conflicts. Don’t rush through it—use it as a learning opportunity to understand how different parts of your code interact.

Thanks for reading, and I hope you found this helpful! Stay tuned for more updates on my open-source journey.

Top comments (0)