Tyr1on
Tyr1on

Reputation: 2339

How to squash commits which have merge-commit in between?

I am working on a feature branch.

  1. Made several commits. Squashed commits.
  2. Pushed changes to remote branch. Got conflicts.
  3. Merged changes from master, resolved conflicts on feature branch.
    • git fetch origin master
    • git merge FETCH_HEAD
    • Resolved conflicts manually.
    • git commit
    • git push
  4. I made one more commit.

So, current commit history looks like this. From current to old:

  1. commit 3
  2. commit M yyy (Merged)
  3. commit 2

How do I squash above 3 commits into 1 before I merge my feature branch to master?

Upvotes: 198

Views: 167437

Answers (8)

haridsv
haridsv

Reputation: 9683

I had to squash multiple feature commits that are interspersed with multiple merge-from-master operations and some of them with conflicts so re-resolving conflicts is going to be very tedious and error prone, so I worked out a solution in my case that I believe will work in all or most other scenarios. I am working on an open source repo (Apache Phoenix), so I can use the exact scenario for depiction below.

To start with, the current history of the feature branch is like this:

* e395780e9 TheN.. PHOENIX-7015 Implementing CDCGlobalIndexRegionScanner (#1813)
* 87a2ea101 Hari.. PHOENIX-7008: Fix for parser gap and fix for failing test (#1812)
* f07898f1f Hari.. PHOENIX-7008: Addressing Jira spec and review feedback changes (#1802)
* 93d586efb Kadi.. Add an extra delete mutation during rebuild for CDC index
* da6ddad04 Kadi.. Add an extra delete mutation for CDC
* 7420443d8 Hari.. PHOENIX-7014: Query compiler/optimizer changes along with some PHOENIX-7015 changes (#1766)
*   21bf5a181 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\
| * b24125230 Jing.. PHOENIX-7101 Explain plan to output local index name if it is used (#1737)
| * da53e659f Istv.. PHOENIX-7121 Do not exclude commons-beanutils from Omid dependencies
| * 1a2f09ced Aron.. PHOENIX-7109 Incorrect query results when using OFFSET
* | 5d3fd4033 TheN.. PHOENIX-7074 DROP CDC Implementation (#1713)
* | 3ebf0bbf6 Vira.. addendum for merge conflict
* | 4e8fa931a Vira.. addendum - SYSTEM.CATALOG upsert syntax changes
* | f7a4feecc Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 5128ad0e7 Divn.. PHOENIX-7076 : MetaDataRegionObserver#postOpen hook improvements (#1735)
| * b64a9736b Istv.. PHOENIX-7095 Implement Statement.closeOnCompletion() and fix related close() bugs
| * 62ccb3b81 Vira.. PHOENIX-7067 View indexes should be created only on non overlapping updatable views (#1709)
| * 20529a62b Istv.. PHOENIX-7102 phoenix-connectors doesn't compile with core HEAD
| * 2feb70fc2 kadi.. PHOENIX-7032 Partial Global Secondary Indexes (#1701)
| * 5d5aaca21 Mona.. PHOENIX-7038 : Implement Connection Query Service Metrics (#1682)
* | e3ca00431 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 17fac6a4d Istv.. PHOENIX-7097 Allow specifying full JDBC URL string in psql/PhoenixRuntime and sqllline.py
| * 97915cd09 Istv.. PHOENIX-6523 Support for HBase Registry Implementations through Phoenix connection URL (addendum:use hbase.client.bootstrap.servers for RPCRe
gistry)
| * 09d229970 Istv.. PHOENIX-6523 Support for HBase Registry Implementations through Phoenix connection URL
* | af1177f78 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 31acf16f5 chai.. PHOENIX-7090 Hash join throw NullPointerException when subquery return null
| * f97c19bda Mona.. TableMetricsManager#getSizeHistogramsForAllTables() is returning empty map (#1727)
* | c15269cb7 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 0a3941f2a Divn.. PHOENIX-7070 : Child View of ReadOnly View is marked as updatable View (#1723)
| * 4463f34d0 Divn.. PHOENIX-5980 : MUTATION_BATCH_FAILED_SIZE metric is incorrectly updated for failing delete mutations (#1717)
| * 36b5a17be Istv.. PHOENIX-7082 Upgrade Jetty to 9.4.53.v20231009
| * 23607a369 Istv.. PHOENIX-7060 Compilation fails on 5.1 with Hbase 2.1 or 2.2
| * c6539dca4 Istv.. PHOENIX-7066 Specify -Xms for tests
| * f40921ce3 Loke.. PHOENIX-7063 Track and account garbage collected phoenix connections (#1706)
| * a9fd540fe Hari.. PHOENIX-7055 Small improvements and bug fixes to sqlline
* | 66bd5db02 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 14c1717af Vira.. PHOENIX-7046 Query results return different values when PKs of view have DESC order (#1689)
* | e2ef88603 Hari.. PHOENIX-7008 Tweaks, fixes and additional test coverage for CREATE CDC (#1703)
* | 20e9a66bd Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 986b79b67 Vira.. PHOENIX-7035 Index on data table with only pk columns result in invalid state (#1675)
| * 4b468bad2 Istv.. PHOENIX-7062 Stabilize testDeletingStatsShouldNotFailWithADEWhenTableDropped
| * 68696f376 Aron.. PHOENIX-7034 Disallow mapped view creation when the schema does not exists
| * 163d11afb Istv.. PHOENIX-7057 Potential bug in MetadataEndpointImpl#updateIndexState.
* | a0501c4e6 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * f5a425e3e Vira.. PHOENIX-7039 Snapshot scanner should skip replay WAL and update seqid while opening region (#1677)
* | 581e61365 Hari.. PHOENIX-7008 Implementation for CREATE CDC  (#1681)
* | 3adc4d019 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 909c25454 Vira.. PHOENIX-7028 Annotate client initiated Scan with metadata attributes (#1661)
* | a7a70f5cb Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 6125f0244 Divn.. PHOENIX-7003 Harden hbase region inconsistencies check in CQSI#getAllTableRegions method (#1686)
| * 3e7b9e944 Istv.. PHOENIX-7052 phoenix-pherf ITs fail because they do not use the miniCluster ZK quorum
| * e4c701843 Istv.. PHOENIX-7051 Remove direct dependency on Google Guice from phoenix-core
| * 57daedce3 Istv.. PHOENIX-7045 AlterTableWithViewsIT.testCreateViewWithPropsMaintainsOwnProps failing on 5.1
* | e5220e01e TheN..  PHOENIX-7054 Shallow grammar support for DROP CDC and ALTER CDC  (#1694)
* | ff5ec799f Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * d6278a0f7 sdav.. PHOENIX-6900 Enable paging feature when the phoenix query is made on a table snapshot. (#1673)
| * 8a59bad25 Istv.. PHOENIX-7042 Update Jetty to 9.4.52.v20230823
| * fd485ab4f Istv.. PHOENIX-7027 Add compatibility module for Hbase 2.5.4 and upgrade Hbase version to 2.5.5
* | 683aeda80 Vira.. Merge branch 'master' into PHOENIX-7001-feature
|\|
| * 48d712ca4 Istv.. PHOENIX-7036 Copy the Java version specific profiles for JVM options from HBase
| * 193b3c544 Tama.. PHOENIX-6973 Add option to CREATE TABLE to skip verification of HBase table
| * a14551ff7 Divn.. PHOENIX-7002 : Added log line for Stale Region Boundary Cache Exception (#1674)
| * c3c317452 tkhu.. PHOENIX-6909 Paged rows counter metric (#1671)
| * 7f6cc3f26 Vira.. PHOENIX-6960 Scan range is incorrect when query desc columns (#1663)
| * 00d0f3878 Aron.. PHOENIX-6920 PhoenixResultSetMetaData doesn't distinguish between label and column_name
| * 3c777aa77 tkhu.. PHOENIX-7024 Fix issues in Server Paging (#1659)
* | 4c9827a43 Hari.. PHOENIX-7008 Shallow grammar support for CREATE CDC (#1662)
|/
* bb8e9daf7 Divn.. PHOENIX-6864 - create view throwing NPE when referring back to itself (#1669)

What I need is a squash of the below feature commits:

* e395780e9 TheN.. PHOENIX-7015 Implementing CDCGlobalIndexRegionScanner (#1813)
* 87a2ea101 Hari.. PHOENIX-7008: Fix for parser gap and fix for failing test (#1812)
* f07898f1f Hari.. PHOENIX-7008: Addressing Jira spec and review feedback changes (#1802)
* 93d586efb Kadi.. Add an extra delete mutation during rebuild for CDC index
* da6ddad04 Kadi.. Add an extra delete mutation for CDC
* 7420443d8 Hari.. PHOENIX-7014: Query compiler/optimizer changes along with some PHOENIX-7015 changes (#1766)
* | 5d3fd4033 TheN.. PHOENIX-7074 DROP CDC Implementation (#1713)
* | e2ef88603 Hari.. PHOENIX-7008 Tweaks, fixes and additional test coverage for CREATE CDC (#1703)
* | 581e61365 Hari.. PHOENIX-7008 Implementation for CREATE CDC  (#1681)
* | e5220e01e TheN..  PHOENIX-7054 Shallow grammar support for DROP CDC and ALTER CDC  (#1694)
* | 4c9827a43 Hari.. PHOENIX-7008 Shallow grammar support for CREATE CDC (#1662)

If you follow the approach suggested by @Kristján, you will end up with the below conflicts:

$ git rebase -i b24125230
...
Auto-merging phoenix-core/src/main/protobuf/PTable.proto
CONFLICT (content): Merge conflict in phoenix-core/src/main/protobuf/PTable.proto
...
error: could not apply 581e61365... PHOENIX-7008 Implementation for CREATE CDC  (#1681)
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 581e61365... PHOENIX-7008 Implementation for CREATE CDC  (#1681)

The solution came into my mind when I realized that the last merge commit (21bf5a181) has all the feature changes as well as the master changes, so if I can squash that, I can cherry-pick and squash the rest on top it with no conflicts, so this is what I did:

  1. Squash all the changes prior to the last merge commit
git checkout -b PHOENIX-7001-feature-squash 21bf5a181
git reset --soft b24125230
git commit -m 'Squashing changes from the PRs #1662, #1694, #1681, #1703 and #1713

* 4c9827a43 Hari.. PHOENIX-7008 Shallow grammar support for CREATE CDC (#1662)
* e5220e01e TheN..  PHOENIX-7054 Shallow grammar support for DROP CDC and ALTER CDC  (#1694)
* 581e61365 Hari.. PHOENIX-7008 Implementation for CREATE CDC  (#1681)
* e2ef88603 Hari.. PHOENIX-7008 Tweaks, fixes and additional test coverage for CREATE CDC (#1703)
* 5d3fd4033 TheN.. PHOENIX-7074 DROP CDC Implementation (#1713)'
  1. Cherry-pick all the newer commits that came after the last merge:
git cherry-pick 7420443d8 da6ddad04 93d586efb f07898f1f 87a2ea101 e395780e
  1. Now squash again to the same base, which will capture both previous squashed commit that includes older as well as the newer commits compared to the merge-base.
git reset --soft b24125230 # Jing.. PHOENIX-7101 Explain plan to output local index name if it is used (#1737)
git commit -m 'Squashing changes from the PRs #1662, #1694, #1681, #1703, #1713, #1766, #1802, #1812 and #1813

* 4c9827a43 Hari.. PHOENIX-7008 Shallow grammar support for CREATE CDC (#1662)
* e5220e01e TheN..  PHOENIX-7054 Shallow grammar support for DROP CDC and ALTER CDC  (#1694)
* 581e61365 Hari.. PHOENIX-7008 Implementation for CREATE CDC  (#1681)
* e2ef88603 Hari.. PHOENIX-7008 Tweaks, fixes and additional test coverage for CREATE CDC (#1703)
* 5d3fd4033 TheN.. PHOENIX-7074 DROP CDC Implementation (#1713)
* 7420443d8 Hari.. PHOENIX-7014: Query compiler/optimizer changes along with some PHOENIX-7015 changes (#1766)
* da6ddad04 Kadi.. Add an extra delete mutation for CDC
* 93d586efb Kadi.. Add an extra delete mutation during rebuild for CDC index
* f07898f1f Hari.. PHOENIX-7008: Addressing Jira spec and review feedback changes (#1802)
* 87a2ea101 Hari.. PHOENIX-7008: Fix for parser gap and fix for failing test (#1812)
* e395780e9 TheN.. PHOENIX-7015 Implementing CDCGlobalIndexRegionScanner (#1813)'

Upvotes: 0

Cesar Celis
Cesar Celis

Reputation: 306

enter image description here

  1. Get the PR locally:
gh pr checkout 1938
  1. Add upstream to tell from where you are going to obtain the changes
git remote add upstream [email protected]:minio/console.git
  1. fetch from upstream to get all new changes
git fetch upstream
  1. rebase in a special way, look:
git rebase -i upstream/master

You will see

pick 18eea859 add csr under tenant details

# Rebase 3bfdbb5e..01964c30 onto 3bfdbb5e (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
  1. Just don't change the pick let it be, if you select squash or reword for this particular case, it won't work. All you really want is to rebase your change and remove the merge commit from your PR, so just save the file as is and get below:
$ git rebase -i upstream/master
Successfully rebased and updated refs/heads/add-csr-under-tenant-details.
  1. Now you can push it:
git push -f
  1. Squashed, or actually rebased, no more merged commit in between:

enter image description here

Upvotes: 3

Assuming the feature branch is called feature and the main branch main:

Create a temporary branch from main:

git checkout -b temp main

Squash the feature branch in:

git merge --squash feature

Commit the changes (the commit message contains all squashed commit messages):

git commit

Go back to the feature branch and point it to the temp branch:

git checkout feature
git reset --hard temp

Delete the temporary branch:

git branch -d temp

Upvotes: 264

Saurav Sahu
Saurav Sahu

Reputation: 13924

I came across this issue when I committed a code change using Github UI, and then committed a change locally(without updating the local clone), and then tried to push the local commit to origin. A merge-commit was created as a result.

master
       \ 
         remote-branch --- commit #1 ---------------MergeCommit
                                                    ^
             |                                      |    
           local-branch -------------- commit #2 --- 

Checkout a new branch from the same origin branch, cherry-pick all commits except merge-commit, and then push the branch

master
       \ 
         new-branch --------------------------------------- Squash-commits
                                   ^                     ^
             |                     |   < Cherry-pick >   |                      
         previous-branch -----commit #1 --------- commit #2 

Note that the origin-branch from which we are forking is the same i.e. master.

The process of cherry-picking is straightforward for IntelliJ users. The new-branch will not have the merge-commit as a result.

Upvotes: 2

Gabriel Schulhof
Gabriel Schulhof

Reputation: 111

The only way I have found to not have to re-resolve conflicts is this:

Given branch main and branch work, perform the following steps:

git checkout -b work-squashed `git merge-base main work`

This creates a new branch from the last main commit you merged into the work branch.

git diff work-squashed...work | patch -p1

This grabs and applies to the working directory all the changes between the last commit on main that was merged into work and the tip of the work branch. In other words, all the work, including the resolved conflicts.

At this point you need to take care of files added/removed on the work branch, because patch is not git. It doesn't know what files are being tracked by git. So, you need to git add/git rm until all the files are accounted for. Then, you simply commit the changes as a single commit.

Upvotes: 6

sheerun
sheerun

Reputation: 1794

You can use the tool I've created specifically for this task:

https://github.com/sheerun/git-squash

It's only necessary to merge master branch, and then run squashing command:

git merge master
git squash master

Upvotes: 21

user6096790
user6096790

Reputation: 430

In my case, I started working with a branch that had several commits, then a merge with the main/source branch, then more commits and I wanted to squash all commits, but kept running into an error because of the merge commit:

error: commit is a merge but no -m option was given.

->C1->C2->M(merge with source branch)->C3->C4

There's probably a better way (and I look forward to learning), but what I ended up doing after much reading and trial and error was creating a copy branch for reference, then reverting the current branch to C1,

reset --hard (C1 hash)

then cherry-picking C2, C3, C4, then squashing, then rebasing ... resulting in:

M->C

(just one commit that has been rebased with source!)

I hope this helps someone else with the same problem.

Upvotes: 4

Kristj&#225;n
Kristj&#225;n

Reputation: 18803

You can rebase -i starting with commit 2's parent (that is, the commit on master that you branched from. You'll likely have to re-resolve conflicts when you get to the merge commit.

So if your history looks like

  * D commit 3 (HEAD)
  * M merge
 /|
| * C commit 2
* | B commit on master
|/
* A (master)

Start with git rebase -i A. You'll see a list of commits including both master and your_branch, but not the merge commit. pick the first one (B or C, depending on timing) and squash the rest.

Upvotes: 60

Related Questions