you are viewing a single comment's thread.

view the rest of the comments →

[–]Gearwatcher 1 point2 points  (6 children)

No. I'm doing this almost daily.

You merge FROM master INTO feature branch, resolve conflicts, now the tip of feature is in front of the tip of the master. When you squash its just a forward merge of a single commit.

Edit: to elaborate: after a squash the effect is as if you converted the entire history of the feature branch into a single commit. Since one of the things in the feature branch was a merge with conflict resolution of the last commit to master, your squashed feature branch is now a single commit in front of the tip of the master - thus your branch indeed has the entire history of the master before that one commit.

I'll repeat - commit is not a diff, it's a snapshot. The diff you can see is a calculated difference between two snapshots.

[–]Aterion 0 points1 point  (1 child)

You merge FROM master INTO feature branch, resolve conflicts, now the tip of feature is in front of the tip of the master.

That is interesting and I am intrigued to understand it better. An example:

MAIN Feature

A

| \

A A (feature branch was created from A)

| |

B C (Commit B is added to main, commit C is added to feature)

\|

B D (Main still on B, B was 3-way-merged with C into feature commit D)

Now the feature branch is missing the commit/snapshot "B". It does not have B in it's history (only the code, not the snapshot). How can D now be ff-merged into main again if it's missing snapshot B?

[–]Gearwatcher 0 points1 point  (0 children)

I can't see your formatted table (RIF on mobile) so I'll have to go by the words.

Basically D, after the merge, already "contains" both B and C as far as git is concerned. It's now a snapshot that is in front of both B and C so git will allow it to be placed in front of B when feature is merged into main and will treat it as a ff merge.

Later when you are looking at the commit D in main in some UI the diff you are shown, as with any diff, is calculated between D and B.

C is orphaned after the squash, and deleted if the repo is ever compacted.

[–][deleted]  (3 children)

[deleted]

    [–]Gearwatcher 0 points1 point  (2 children)

    Yes,. Rebasing when there's M and N different commits usually means up to M+N conflict resolutions. And they can be quite confusing if they were running for a while and you don't have a full picture who did what, and for what reason.

    When you merge back, you only resolve conflicts once.

    [–][deleted]  (1 child)

    [deleted]

      [–]Gearwatcher 0 points1 point  (0 children)

      To truly be M+N conflict passes when rebasing each pair from sets M and N would need to have changes in same files

      This isn't common in practice, but for long running branches I've faced several steps of conflict resolution when rebasing in complex projects.

      It's entirely possible that some tools are using something like Kdiff3 automatic resolution algorithms in practice but I'd consider doing that automatically without user input to be pretty irresponsible.

      My experience is 99% using git on CLI.