Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I squash _other peoples_ git commits in a submitted PR?

I have received a PR and wish to squash the commits so it's nice.

I'm not sure if I can do it or the respective authors have to do it? Of course, I wish to keep the author's name referencing their squash commit.

NOTE: this question is not about me squashing my own commits.

Here's what the PR looks like in Git:

enter image description here

or via the cli:

c:\Projects\Foo>git log --pretty=oneline
7fab9ae1031c13414909668f342582bdc8081f5a <Author - Red>
a02270b2014fd3995456773cd7badc7df0c72cf6 <Author - Blue>
6ae3d6c8b5a8b037c0e4dc88d24ec5598ff1933e <Author - Blue>
100f6513aacbe431b56f3082597749cddca284c8 <Author - Blue>
d263a5c8924053678f455b5ee8515bbb16aacf49 <Author - Blue>
c3cc5dbc13ac77e0a552a2d3132d255df3c7a6e4 <Author - Blue>
71f89b3f3dd583cd97d4a0806a973a4d1af64fe9 <Author - Red>
f14ef616a852f3a7311f4f7b9e05d460e0574422 <Author - Red>
015f30b3828828404b5549ee8a7df2aefdfa9424 <Author - Red>
9b22a4d2ded54cb754883d9d6418a39eb34df7cf <Author - Red>
33a10e9828d04cf82439a6c60b8cf4c0c2f122a3 <Author - Red>
4615c7747c4546809b29e063986c697c7c64cbc4 Added Specific naming rules, section.
b8ee154e38338022649caef40945c6f0297a59ce Added method parameters, section.
bc860c7609cc80caf41fc5944c1b39201019a80e Added Input and View Models, section.
ad6b3e4bee1cb9d8afcf9cd1fa8815769d80133b Fixed bad markdown formatting.
5929d5b38aad8bb7cc3da4976dd81883eab0f999 Added more testing info.
18b64dfc3769766ac2bb841e6346b555d00751f1 Create README.md
d7761e57a5bbd7de587b766c83d2a3134c0bc58b Added xUnit and Shouldly NuGet packages.
7f2ea8cdd97958d347df8079ef2eebb6b7f1647c We need unit tests....
ee31bbfe0572e0e49872edcf1a6fc2c426ed0d15 :money_with_wings: We are alive!

the commits that have the messages there, those are mine and not part of this PR.

Is there anything that I can do? Or do I need to the other author's to do?

like image 527
Pure.Krome Avatar asked Nov 11 '15 01:11

Pure.Krome


1 Answers

Comments ended up turning into an answer so I'll summarize them here:

I'm not sure if I can do it or the respective authors have to do it? Of course, I wish to keep the author's name referencing their squash commit.

If you squash any commits, you will only end up with one commit, and a commit can only have one author. They may still be referenced in the commit message (Git does by default) but you will lose individuality on the literal commit author.

So can't I squash the blue commits (into one) and then the red commits (into one) ? so there's two in the PR?

Yeah you could totally do that, and squashing should be something that you suggest in pull requests so that you only carry over one commit for each one. If you squash all blue commits into one and all red commits into one you achieve what I think you want which is to clean up your git log while still maintaining the author history.

Great! .. any suggestions how this can be done?

Sure. You can interactively rebase to squash multiple commits together. Your problems will come when you have a red commit on either side of blue commits, which limits your squash-ability.

For the blue commits you can squash them into the first commit in the list when you do a git rebase -i HEAD~11 (which loads in the last 11 commits for interactive rebasing).

I mocked up some dummy commits to use as an example:

$ git log --oneline
7e8be9c Red
b740f97 Blue
325b375 Blue
553d733 Red
bb5599b Red

In your console, choose "p" or "pick" for the first Blue commit in the list (bd63d63) and for all the others, give it "f" or "fixup" to discard their commit messages, or "s" or "squash" if you want to keep the commit messages for them:

$ git rebase -i HEAD~5
pick bb5599b Red
pick 553d733 Red
pick 325b375 Blue
fixup b740f97 Blue
pick 7e8be9c Red

When rebasing is finished your blue commits will all be squashed together:

$ git log --oneline
a341d97 Red
488c19e Blue
553d733 Red
bb5599b Red

This is where it may get complicated depending on whether Red and Blue have touched the same files or not.

If they haven't then your best bet is to cherry-pick the Blue commit into a separate branch (without either Red or Blue) or rebase it out, rebase the original and squash the Red commits while discarding the Blue commit, then merge the temporary branch back in, e.g.:

$ git checkout -b tempbranch
$ git reset --hard XXXXXXX # this is the commit BEFORE any red or blues
$ git cherry-pick 488c19e

Git log will now tell you that you have the single squashed Blue commit.

Switch back to your main branch and rebase again, this time skipping the Blue commit and squashing the red ones together:

$ git rebase -i HEAD~4
pick bb5599b Red
fixup 553d733 Red
drop 488c19e Blue
fixup a341d97 Red

Git log will now show you that you only have one single Red commit. Now you cherry-pick the Blue one back in again:

$ git cherry-pick 488c19e
$ git log --oneline
fc96b04 Blue
0280ef9 Red

You will come into problems if those commits all touch the same files. In this case, you may just need to keep the separation of Red around Blue.

Important

I'd highly suggest that you advise all contributors to your Github project to squash all their commits into one as part of the pull request process, then you won't have to deal with these problems yourself.

HTH.

like image 121
scrowler Avatar answered Oct 13 '22 14:10

scrowler