KINTO Tech Blog
Development

Pull Request Options on GitHub and Pitfalls

Cover Image for Pull Request Options on GitHub and Pitfalls

This article is the entry for day 13 in the KINTO Technologies Advent Calendar 2024 🎅🎄

Introduction

Hello. I am ITOYU, a front-end developer in the New Car Subscription Development Group of the KINTO ONE Development Division.

Engineers, are you using GitHub? At KINTO Technologies we do too! We rely on GitHub's Pull Request feature to review and merge code.

When merging, you have several options to choose from—did you know that? In this article, I'll explain the differences between these options and share some pitfalls I've encountered along the way.

option_select

Topics Covered

  • GitHub Pull Request merge options:
    • Create a merge commit
    • Squash and merge
    • Rebase and merge
  • Common Pitfalls:
    • Rebase and merge is not the same as git rebase.
    • Your last selected merge option becomes the default for the next merge.

Prerequisites

  • A develop branch and a feature branch exist.
  • You create a feature branch by branching off from develop, make changes, and then submit a Pull Request to merge it back into develop.
  • The commit histories for the develop and feature branches are as follows:

Commit history of the develop branch develop_history

Commit history of the feature branch feature_history

The Pull Request Merge Options on GitHub.

Create a merge commit

The Create a merge commit option merges the commits from the feature branch into the develop branch while preserving their hash values. It also generates a new merge commit. After merging, the commit history will appear as follows:

Commit history of the develop branch after the merge
create_merge_commit

You can see that the hash values of the original commits are preserved and that a new merge commit is created, maintaining a clear record of the merge.

Features

  • The hash value of the commit history from the merge source is retained.
  • A merge commit is created, preserving a record of the merge in the commit history.

Use cases

  • When you want to keep multiple commits as is
  • When you want to keep a clear merge history

Squash and merge

The Squash and merge option combines all all commits from the feature branch into a single commit before merging it into the develop branch. After merging, the commit history will appear as follows:

Commit history of develop branch after merge
squash_and_merge

Although multiple commits existed in the feature branch, they are consolidated into a single commit in the develop branch.

Features

  • Combines all commits from the merge source into a single commit.

Use cases

  • When you want to keep the commit history simple.
  • When you need to consolidate multiple small changes into one commit.

Rebase and merge

The Rebase and merge option moves the commits from the feature branch right after the latest commit in the develop branch, and merges them into the develop branch. Unlike squash, the commit history remains intact.

Commit history of develop branch after merge
rebase_and_merge

As you can see, no merge commit is created.

Features

  • Preserves the commit history from the feature branch without modifications.
  • No merge commit is created, keeping the history clean.
  • Unlike the original commit hash values, new commits are created during the rebase.

Use cases

  • When you want to keep the commit history intact without creating a merge commit.
  • When you prefer a structured commit history by rebasing.

Common Pitfalls:

I've explained each option above, but now I'll highlight some pitfalls I've encounteres along the way.

Rebase and merge and git rebase are not the same

In a medium-sized project, our team was collaborating on a development branch, and the develop branch of the source branch had been updated. I considered using git rebase to clean up the commit history of our project's branches. However, this approach would require a force push, which I wanted to avoid on the branches we were all working on.

Instead, I thought the Rebase and merge option in GitHub’s Pull Request feature might be a safer alternative. I believed this method would keep the commit history clean without requiring additional local work. After merging the Pull Request from the feature branch into the develop branch using the Rebase and merge option, I checked for any differences or deltas. after_rebase

There were a lot of differences.

At first glance, the commit histories of both the develop and feature branches seemed identical, but the hash values were different. rebase_compare

This occurs because Rebase and merge generates a new commit hash rather than preserving the hash value from the source branch.

I realized that Rebase and merge and git rebase behave differently, and I shouldn’t expect them to produce the same results.

The option you selected last time will be set as the default for the next merge.

This one is more of a careless mistake than a pitfall, but it’s important to highlight. My team typically uses Squash and merge to keep a clean commit history in the working branch.

After my previous unsuccessful attempt with Rebase and merge, I returned to my usual workflow. Once the Pull Request I submitted was approved, I merged it as usual.

However, something was off. For some reason, Rebase and merge was executed instead of Squash and merge

It turns out that the Pull Request merge options you select last are automatically set as the default for the next merge. This might seem obvious after you think about it, but I didn’t realize it at first. I learned to be more cautious when changing merge options, as the selected option will carry over to the next Pull Request, potentially affecting your workflow if you’re not paying attention.

Conclusion

When merging a GitHub Pull Request, selecting the appropriate option is crucial based on the characteristics of the merge and your specific needs. Here’s how I differentiate the options:

  • Create a merge commit: I use this option when I want to retain the commit hash from the feature branch and maintain a clear record of the merge history. This makes it easier to trace which branches were merged and when.
  • Squash and merge: I prefer this option when I want to combine my working commits into a single commit and maintain a clean, simple commit history. This helps combine smaller commits into one, making the commit history more concise and easier to read.
  • Rebase and merge: I choose this when I want to keep my commit history linear without creating merge commits. This makes it easier to follow the flow of changes and keeps the history clean.

Additionally, always double-check the currently selected merge option before merging a Pull Request to avoid any unexpected issues.

Facebook

関連記事 | Related Posts

We are hiring!

【フロントエンドエンジニア】プロジェクト推進G/東京

配属グループについて▶新サービス開発部 プロジェクト推進グループ 中古車サブスク開発チームTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 中古車 』のWebサイトの開発、運用を中心に、その他サービスの開発、運用も行っています。

【フロントエンドエンジニア(コンテンツ開発)】新車サブスク開発G/東京

新車サブスク開発グループについてTOYOTAのクルマのサブスクリプションサービスである『 KINTO ONE 』のWebサイトの開発、運用をしています。​業務内容トヨタグループの金融、モビリティサービスの内製開発組織である同社にて、自社サービスである、クルマのサブスクリプションサービス『KINTO ONE』のWebサイトコンテンツの開発・運用業務を担っていただきます。

イベント情報

P3NFEST Bug Bounty 2025 Winter 【KINTOテクノロジーズ協賛】