fork-dev / TrackerWin

Bug and issue tracker for Fork for Windows
461 stars 10 forks source link

Warn user when a conflict has multiple merge bases #1874

Open Grimeh opened 1 year ago

Grimeh commented 1 year ago

Description

When using "Merge in external merger" for a conflict that has multiple merge bases and the merge bases cannot be merged by git, the base version passed to the external merger tool will have a conflict that may cause the external merger to fail.

For an example of what I mean by a "conflicted base", please refer to this SO question: https://stackoverflow.com/questions/55949329/git-merge-how-did-i-get-a-conflict-in-base-file

I encountered this issue when attempting to merge a conflict with a LFS file using UnityYAMLMerge (the file in question is a large YAML file). The cause of multiple merge bases in this case is known to me, and I don't think this happens under "normal" git usage, but it can happen.

I believe this will also happen for non-LFS files with multiple merge bases, since Git will still produce a base file with a conflict (when they cannot be merged automatically).

At the moment tools may give confusing error messages with no information to go on, and unless you're at least somewhat familiar with the internals of git there's no way to troubleshoot the problem.

Example: UnityYAMLMerge says "Error parsing file '~Base.prefab': File is not a valid text serialized YAML file. [...]"

Solution

I'm not sure there's anything Fork can realistically do to prevent or fix this.

However it would be massively helpful to identify when this has happened and inform the user that the base version of the conflicted file has conflicts and therefore external tools may not function as expected.

To identify when this has happened Fork could check if a conflict has multiple merge bases when a conflict is detected, or examine the merge base file for any conflicts before opening the external tool.

DanPristupov commented 1 year ago

For an example of what I mean by a "conflicted base", please refer to this SO question: https://stackoverflow.com/questions/55949329/git-merge-how-did-i-get-a-conflict-in-base-file

Thank you for the link.

Detecting that is tricky.

I'm not sure there's anything Fork can realistically do to prevent or fix this.

To prevent that you must use other workflow, I think. Do you use merge a lot? Can you switch to rebase (or use 'lean branching')? Looks like that would solve the problem.

Grimeh commented 1 year ago

Ironically this was caused by a dodgy rebase I did a week ago, which is why I mentioned it probably doesn't happen under "normal" usage.

As far as I know this particular problem is not something we've run into before, I'm the only one. It's definitely more of a quality of life feature since it's a weird edge case 🙂

In response to your last point: most of the team exclusively uses merge, unfortunately in terms of workflow we are quite limited. The majority (>75%) of the team are non-technical (artists, designers, etc.) and we rely on branching a lot for various reasons. So we have different priorities when defining our workflows than perhaps your typical users do.

We're also limited to narrow windows of time between projects where we can introduce changes to workflows without disrupting the production schedule.

DanPristupov commented 1 year ago

I know, it a an off topic, but since we are here...

So we have different priorities when defining our workflows than perhaps your typical users do.

No, that's exactly what the typical users do :).

With lean branching there is just 'sync' and 'finish' which should straightforward for non-technical users:

Screenshot 2023-04-20 at 11 07 02
Grimeh commented 1 year ago

I'm afraid we are very off topic indeed. While I appreciate the suggestion, and I will evaluate Lean Branching for my team between projects, it is not a solution to this problem.

I wasn't clear enough in my reply: the issue was caused by a bad rebase, it was something I did as a one-off to solve a problem, but was far too tired at the time and was trying to be far too clever about how I did it.

It is not inherent to any particular workflow. I don't think a conflicted base can even happen with the standard "branch & merge" workflow. As far as I'm aware it's an exceedingly rare edge case, I hadn't even heard of it before running into it earlier this year.

I initially thought that perhaps searching the base file for conflict markers (<<<<<) would be an easy way to identify it, but that would likely produce false positives. The file could contain those characters intentionally, or the base file could have an existing unresolved conflict that was (erroneously) committed.

Perhaps Fork could query for the merge bases (with git merge-base --all), if there's multiple bases, attempt a merge of the two bases and test to see if it produces a conflict. Very messy, obviously not a great solution.