<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DJ Unicode</title>
    <description>The latest articles on DEV Community by DJ Unicode (@dj-unicode).</description>
    <link>https://dev.to/dj-unicode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F4649%2Fd79ecbb6-8ef8-4472-9ffb-c6d77213002d.png</url>
      <title>DEV Community: DJ Unicode</title>
      <link>https://dev.to/dj-unicode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dj-unicode"/>
    <language>en</language>
    <item>
      <title>How to squash commits in a PR</title>
      <dc:creator>YJDoc2</dc:creator>
      <pubDate>Fri, 27 Aug 2021 11:01:10 +0000</pubDate>
      <link>https://dev.to/dj-unicode/how-to-squash-commits-in-a-pr-e8i</link>
      <guid>https://dev.to/dj-unicode/how-to-squash-commits-in-a-pr-e8i</guid>
      <description>&lt;p&gt;Helped by &lt;a href="https://github.com/palkadhirawani" rel="noopener noreferrer"&gt;Palka&lt;/a&gt; , &lt;a href="https://github.com/dedsec29" rel="noopener noreferrer"&gt;Parth&lt;/a&gt;, and &lt;a href="https://github.com/YatharthVyas" rel="noopener noreferrer"&gt;Yatharth&lt;/a&gt;.&lt;br&gt;
Header image created by &lt;a href="https://github.com/saloni3121" rel="noopener noreferrer"&gt;Saloni&lt;/a&gt;. Git illustration in text created by &lt;a href="https://github.com/panchalmilan" rel="noopener noreferrer"&gt;Milan&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Hello everyone !&lt;br&gt;
As you might be aware, hacktoberfest is approaching, and in about a month many of you will be helping out on open source projects. Of course, working on projects is a side effect, you know why we really do it...😏😏 To plant a tree, obviously 🌳🌲🌳🌲 (Seriously, we should do that seeing the amount of wildfires this year)&lt;/p&gt;

&lt;p&gt;Anyway, while making PRs, you might be asked to squash formatting or spelling error commits, and to save you a Google search, I am writing this post to show you why, when and how to squash commits in your PR.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why would you ever want to squash something???
&lt;/h2&gt;

&lt;p&gt;So imagine this, you have written your beautiful code, written comments in a well known format, the code is compiling and working, and you satisfyingly make a commit with the perfect commit message.... Only to realize later that you have made a spelling error 🥲🤦 Now you can use a soft reset, fix the error, and re-commit, leaving no one any wiser, but what if you had already pushed the commit in PR?&lt;/p&gt;

&lt;p&gt;More realistically, imagine you're working on a PR, and as you're pushing the commits, and they're getting reviewed you accidentally mess up formatting and commit. Or along an ongoing discussion in a PR, you have made some patch commits and now before merging the PR you want to combine them, as old patches don't really make sense . This is where squashing the commits would come handy.&lt;/p&gt;

&lt;p&gt;Squashing allows to combine or 'squash' the commits together, leaving a nice git history behind. That way you can combine all your patch commits into a single commit, or squash formatting and spelling error commits into other commits, leaving behind a git history of only necessary commits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0on6d33b4pk9zuylmzg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0on6d33b4pk9zuylmzg.jpeg" alt="Git squash example" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  When should the squashing be done?
&lt;/h2&gt;

&lt;p&gt;Now on an important note, you should not squash commits if they're pushed to the main branch of the repository. Squashing changes git history, which means that history of all forks of that branch will be inconsistent with your repository, giving everyone a lot of merge conflicts, and you know how &lt;em&gt;you&lt;/em&gt; were when you got conflicts, right 😉 😉&lt;/p&gt;

&lt;p&gt;However if you're working on a branch which is not main for an issue, and you intend to make a PR to the main branch, it is totally fine to squash the commits. As most of the times you alone are working on that specific branch, even if the history changes it will not affect anyone else. Then once everything is done, you can merge the PR without any history conflicts.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to squash commits
&lt;/h2&gt;

&lt;p&gt;Let us see with an example. Consider a project on which you're working, that already has some commits on its main branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# run git log --pretty=oneline&lt;/span&gt;
7dc92d4...&lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to grow some trees 🌲🌳 you decide to work on this project and help in solving issue-1. So you fork and clone the project, make a branch named issue-1 like a good contributor and start working on the issue.&lt;/p&gt;

&lt;p&gt;You add feature 1 and feature 2 in their own commits and make a PR. After discussing with the reviewers, you find that there was a bug in your commits and you make a commit to fix it.&lt;/p&gt;

&lt;p&gt;Now, your git history looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git log --pretty=oneline&lt;/span&gt;
b2f4c83... &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; issue-1&lt;span class="o"&gt;)&lt;/span&gt; Bug Fix
32e414f... Add Feature 2
7654633... Add Feature 1
7dc92d4... &lt;span class="o"&gt;(&lt;/span&gt;Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have your main branch's head on &lt;code&gt;Add Readme&lt;/code&gt; commit, and issue-1's head on &lt;code&gt;Bug Fix&lt;/code&gt; commit. &lt;/p&gt;

&lt;p&gt;Now as you're about to start with feature 3 , when someone comments on your PR, noticing a formatting and spelling error😭😢&lt;br&gt;
Ah well.... You fix those, make a commit and start working on the feature 3. After finally making if work, your commit history now looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git log --pretty=oneline&lt;/span&gt;
f592171... &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; issue-1&lt;span class="o"&gt;)&lt;/span&gt; Add Feature 3
574b345... Fix Formatting
b2f4c83... Bug Fix
32e414f... Add Feature 2
7654633... Add Feature 1
7dc92d4... &lt;span class="o"&gt;(&lt;/span&gt;Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you push these to your repository, and wait eagerly to get it merged, someone asks you to squash the formatting commit, so the main repository history would look nice.&lt;/p&gt;

&lt;p&gt;Now to squash the commits, you need to run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-i&lt;/code&gt; option make the rebase interactive, and &lt;code&gt;HEAD~4&lt;/code&gt; considers last 4 commits from current Head position for the rebase. If your formatting commit was 5 commits before current, you would replace 4 with 6 or some numbers greater than 5, to get all commits till there.&lt;/p&gt;

&lt;p&gt;After running this, you will see a message like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick 32e414f Add Feature 2
pick b2f4c83 Bug Fix
pick 574b345 Fix Formatting
pick f592171 Add Feature 3

&lt;span class="c"&gt;# Rebase 7654633..f592171 onto f592171 (4 commands)&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Commands:&lt;/span&gt;
&lt;span class="c"&gt;# p, pick &amp;lt;commit&amp;gt; = use commit&lt;/span&gt;
&lt;span class="c"&gt;# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message&lt;/span&gt;
&lt;span class="c"&gt;# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending&lt;/span&gt;
&lt;span class="c"&gt;# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit&lt;/span&gt;
&lt;span class="c"&gt;# f, fixup &amp;lt;commit&amp;gt; = like "squash", but discard this commit's log message&lt;/span&gt;
&lt;span class="c"&gt;# x, exec &amp;lt;command&amp;gt; = run command (the rest of the line) using shell&lt;/span&gt;
&lt;span class="c"&gt;# b, break = stop here (continue rebase later with 'git rebase --continue')&lt;/span&gt;
&lt;span class="c"&gt;# d, drop &amp;lt;commit&amp;gt; = remove commit&lt;/span&gt;
&lt;span class="c"&gt;# l, label &amp;lt;label&amp;gt; = label current HEAD with a name&lt;/span&gt;
&lt;span class="c"&gt;# t, reset &amp;lt;label&amp;gt; = reset HEAD to a label&lt;/span&gt;
&lt;span class="c"&gt;# m, merge [-C &amp;lt;commit&amp;gt; | -c &amp;lt;commit&amp;gt;] &amp;lt;label&amp;gt; [# &amp;lt;oneline&amp;gt;]&lt;/span&gt;
&lt;span class="c"&gt;# .       create a merge commit using the original merge commit's&lt;/span&gt;
&lt;span class="c"&gt;# .       message (or the oneline, if no original merge commit was&lt;/span&gt;
&lt;span class="c"&gt;# .       specified). Use -c &amp;lt;commit&amp;gt; to reword the commit message.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# These lines can be re-ordered; they are executed from top to bottom.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# If you remove a line here THAT COMMIT WILL BE LOST.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# However, if you remove everything, the rebase will be aborted.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Note that empty commits are commented out&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows first, the commits : from oldest to latest, and then available options, such as squash, edit, fixup... Git can be really powerful once you get to know it... But I don't know much of it other than handful of commands, so let us get on with squashing the formatting commit.&lt;/p&gt;

&lt;p&gt;To perform an action on a commit, you change the word 'pick' before that commit to that action, as described in comments. To squash the formatting commit, you change it as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pick 32e414f Add Feature 2
pick b2f4c83 Bug Fix
squash 574b345 Fix Formatting
pick f592171 Add Feature 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After saving this you will get another commit message, showing commit message before the squashed commit, and the squash commit message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is a combination of 2 commits.&lt;/span&gt;
&lt;span class="c"&gt;# This is the 1st commit message:&lt;/span&gt;

Bug Fix

&lt;span class="c"&gt;# This is the commit message #2:&lt;/span&gt;

Fix Formatting

&lt;span class="c"&gt;# Please enter the commit message for your changes. Lines starting&lt;/span&gt;
&lt;span class="c"&gt;# with '#' will be ignored, and an empty message aborts the commit.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Date:      Thu Aug 19 19:03:51 2021 +0530&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# interactive rebase in progress; onto 7654633&lt;/span&gt;
&lt;span class="c"&gt;# Last commands done (3 commands done):&lt;/span&gt;
&lt;span class="c"&gt;#    pick b2f4c83 Bug Fix&lt;/span&gt;
&lt;span class="c"&gt;#    squash 574b345 Fix Formatting&lt;/span&gt;
&lt;span class="c"&gt;# Next command to do (1 remaining command):&lt;/span&gt;
&lt;span class="c"&gt;#    pick f592171 Add Feature 3&lt;/span&gt;
&lt;span class="c"&gt;# You are currently rebasing branch 'issue-1' on '7654633'.&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# Changes to be committed:&lt;/span&gt;
&lt;span class="c"&gt;#       modified:   readme.md&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case the commit was something like a patch in series where you want to keep the message, this will allow you to do that. Otherwise if you just want to forego the message, you can also use the &lt;code&gt;fixup&lt;/code&gt; instead of &lt;code&gt;squash&lt;/code&gt;. Here you can comment the second commit message, and save, like usual git commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is a combination of 2 commits.&lt;/span&gt;
&lt;span class="c"&gt;# This is the 1st commit message:&lt;/span&gt;

Bug Fix

&lt;span class="c"&gt;# This is the commit message #2:&lt;/span&gt;

&lt;span class="c"&gt;# Fix Formatting&lt;/span&gt;

&lt;span class="c"&gt;# Please enter the commit message for your changes. Lines starting&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# git log --pretty=oneline&lt;/span&gt;
29768cb... &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; issue-1&lt;span class="o"&gt;)&lt;/span&gt; Add Feature 3
10c38d8... Bug Fix
32e414f... Add Feature 2
7654633... Add Feature 1
7dc92d4... &lt;span class="o"&gt;(&lt;/span&gt;Main&lt;span class="o"&gt;)&lt;/span&gt; Add ReadMe
d3395b0... Initial Commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah, now you have a clean git history, alas, if you try to push this to your repository branch, you will get error saying cannot push because histories are different. Your repository has the formatting commit whereas your local has no such thing in its history. To fix this you'll have to force push :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-f&lt;/span&gt; origin issue-1:issue-1
&lt;span class="c"&gt;# as you're on issue-1 branch, you can leave the last part, but I like the extra confirmation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this your PR will be updated, hopefully merged, and you'll be one step closer to planting that plant 🌱&lt;/p&gt;




&lt;p&gt;Hope you found this useful, and may your PRs be clean :)&lt;/p&gt;

&lt;p&gt;Since I started this post talking about hacktoberfest, let me end with the same. Do you have any repository that you plan to open up for contributing to this hacktoberfest? Sometimes it is hard to make your repository visible in all repos open for contributing, so this is kind of an early call... If you have any interesting repo you would like to open for contribution, post them in the comments. Let's start planting the trees. 🌱🌱🌱&lt;/p&gt;

</description>
      <category>git</category>
      <category>opensource</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
