Reputation: 1205
When I use meld as git mergetool
for solving conflict while merging, meld shows me the differences between local/output and remote/output files (in blue or green) that git automatically solves, and not only the actual conflicts (that are red highlighted). And when I click on the down arrow, it goes to the next (blue/green) difference, and not to the next conflict (red). In this topic, a picture illustrates this.
How could I
Upvotes: 16
Views: 7381
Reputation: 1323045
In addition to meld-specific parameters, you now have new Git options:
With Git 2.31 (Q1 2021), "git mergetool
"(man) feeds three versions (base, local, and remote) of a conflicted path unmodified.
The command learned optionally to prepare these files with unconflicted parts already resolved. OP could enable this behaviour for their meld
mergetool with:
git config --global mergetool.meld.hideResolved true
See commit 9d9cf23, commit de8dafb, commit 98ea309 (09 Feb 2021) by Seth House (whiteinge
).
(Merged by Junio C Hamano -- gitster
-- in commit 78a26cb, 17 Feb 2021)
mergetool
: addhideResolved
configurationOriginal-implementation-by: Felipe Contreras
Signed-off-by: Seth House
The purpose of a mergetool is to help the user resolve any conflicts that Git cannot automatically resolve.
If there is a conflict that must be resolved manually Git will write a file named MERGED which contains everything Git was able to resolve by itself and also everything that it was not able to resolve wrapped in conflict markers.One way to think of
MERGED
is as a two- or three-way diff.
If each "side" of the conflict markers is separately extracted an external tool can represent those conflicts as a side-by-side diff.However many mergetools instead diff
LOCAL
andREMOTE
both of which contain versions of the file from before the merge.
Since the conflicts Git resolved automatically are not present it forces the user to manually re-resolve those conflicts.
Some mergetools also showMERGED
but often only for reference and not as the focal point to resolve the conflicts.This adds a
mergetool.hideResolved
flag that will overwriteLOCAL
andREMOTE
with each corresponding "side" of a conflicted file and thus hide all conflicts that Git was able to resolve itself.
Overwriting these files will immediately benefit any mergetool that uses them without requiring any changes to the tool.No adverse effects were noted in a small survey of popular mergetools
so this behavior defaults to.true
However it can be globally disabled by settingmergetool.hideResolved
tofalse
.
See "Mergetools: Stop doing three-way merges!"
git config
now includes in its man page:
mergetool.hideResolved
During a merge Git will automatically resolve as many conflicts as possible and write the 'MERGED' file containing conflict markers around any conflicts that it cannot resolve; 'LOCAL' and 'REMOTE' normally represent the versions of the file from before Git's conflict resolution.
This flag causes 'LOCAL' and 'REMOTE' to be overwriten so that only the unresolved conflicts are presented to the merge tool.
Can be configured per-tool via the
mergetool.<tool>.hideResolved
configuration variable. Defaults totrue
.
In the OP's case:
git config --global mergetool.meld.hideResolved true
This is described in:
mergetool
: add per-tool support and overrides for the hideResolved flagHelped-by: Johannes Sixt
Helped-by: Junio C Hamano
Signed-off-by: Seth House
Add a per-tool override flag so that users may enable the flag for one tool and disable it for another by setting
mergetool.<tool>.hideResolved
tofalse
.In addition, the author or maintainer of a mergetool may optionally override the default
hideResolved
value for that mergetool.
If themergetools/<tool>
shell script contains ahide_resolved_enabled
function it will be called when the mergetool is invoked and the return value will be used as the default for thehideResolved
flag.hide_resolved_enabled () { return 1 }
Disabling may be desirable if the mergetool wants or needs access to the original, unmodified 'LOCAL' and 'REMOTE' versions of the conflicted file.
For example:
- A tool may use a custom conflict resolution algorithm and prefer to ignore the results of Git's conflict resolution.
- A tool may want to visually compare/constrast the version of the file from before the merge (saved to 'LOCAL', 'REMOTE', and 'BASE') with Git's conflict resolution results (saved to 'MERGED').
git config
now includes in its man page:
mergetool.<tool>.hideResolved
Allows the user to override the global
mergetool.hideResolved
value for a specific tool.
Note that mergetool.hideResolved
actually default to false:
With Git 2.31 (Q1 2021), rc2, disable the recent mergetool's hideresolved
feature by default for backward compatibility and safety.
See commit 5320406, commit b2a51c1 (13 Mar 2021) by Jonathan Nieder (artagnon
).
(Merged by Junio C Hamano -- gitster
-- in commit 8775279, 14 Mar 2021)
mergetool
: do not enable hideResolved by defaultReported-by: Dana Dahlstrom
Helped-by: Seth House
Signed-off-by: Jonathan Nieder
When 98ea309 ("
mergetool
: add hideResolved configuration", 2021-02-09, Git v2.31.0-rc0 -- merge listed in batch #9) introduced themergetool.hideResolved
setting to reduce the clutter in viewing non-conflicted sections of files in a mergetool, it enabled it by default, explaining:No adverse effects were noted in a small survey of popular mergetools. so this behavior defaults to `true`.
In practice, alas, adverse effects do appear.
A few issues:
No indication is shown in the UI that the base, local, and remote versions shown have been modified by additional resolution. This is inherent in the design: the idea of mergetool.hideResolved is to convince a mergetool that expects pristine local, base, and remote files to show partially resolved verisons of those files instead; there is no additional source of information accessible to the mergetool to see where the resolution has happened.
(By contrast, a mergetool generating the partial resolution from conflict markers for itself would be able to hilight the resolved sections with a different color.)
A user accustomed to seeing the files without partial resolution gets no indication that this behavior has changed when they upgrade Git.
If the computed merge did not line up the files correctly (for example due to repeated sections in the file), the partially resolved files can be misleading and do not have enough information to reconstruct what happened and compute the correct merge result.
Resolving a conflict can involve information beyond the textual conflict.
For example, if the local and remote versions added overlapping functionality in different ways, seeing the full unresolved versions of each alongside the base gives information about each side's intent that makes it possible to come up with a resolution that combines those two intents.
By contrast, when starting with partially resolved versions of those files, one can produce a subtly wrong resolution that includes redundant extra code added by one side that is not needed in the approach taken on the other.All that said, a user wanting to focus on textual conflicts with reduced clutter can still benefit from mergetool.hideResolved=true as a way to deemphasize sections of the code that resolve cleanly without requiring any changes to the invoked mergetool.
The caveats described above are reduced when the user has explicitly turned this on, because then the user is aware of them.Flip the default to 'false'.
git config
now includes in its man page:
configuration variable. Defaults to
false
.
Note: With Git 2.48 (Q1 2025), batch 15, end-user experience of "git mergetool
"(man) when the command errors out has been improved.
See commit dbaece3, commit acca46d, commit bba503d, commit 0053676, commit fe99a52 (22 Nov 2024) by Philippe Blain (phil-blain
).
(Merged by Junio C Hamano -- gitster
-- in commit 9cd1e2e, 10 Dec 2024)
git-mergetool--lib.sh
: add error message if 'setup_user_tool
' failsSigned-off-by: Philippe Blain
In
git-mergetool--lib.sh::setup_tool
, we check if the given tool is a known builtin tool, a known variant, or a user-defined tool by callingsetup_user_tool,
and we return with the exit code fromsetup_user_tool
if it was called.
setup_user_tool
checks if{diff,merge}tool.$tool.cmd
is set and quietly returns with an error if not.This leads to the following invocation quietly failing:
git mergetool --tool=unknown
which is not very user-friendly.
Adjustsetup_tool
to output an error message before returning ifsetup_user_tool
returned with an error.Note that we do not check the result of the second call to
setup_user_tool
insetup_tool,
as this call is only meant to allow users to redefine 'cmd' for a builtin tool; it is not an error if they have not done so.Note that this behaviour of quietly failing is a regression dating back to de8dafb ("
mergetool
: breaksetup_tool
out into separate initialization function", 2021-02-09, Git v2.31.0-rc0 -- merge listed in batch #9), as before this commit an unknown mergetool would be diagnosed inget_merge_tool_path
when called fromrun_merge_tool
.
We now have the error message:
error: ${TOOL_MODE}tool.$tool.cmd not set for tool '$tool'
And:
error: unknown tool variant '$tool'
Upvotes: 9
Reputation: 527
If you use cmd+D in your mac it will got to the next conflict, no matter how many changes it is showing. Or in the menu go to Find -> Go Next -> Conflict
Upvotes: 0
Reputation: 10393
Add the following to your .gitconfig
:
[mergetool "meld"]
cmd = meld --auto-merge "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
This is the same command Git runs by default with --auto-merge
specified so that Meld automatically resolves what it can.
Upvotes: 11
Reputation: 733
In meld, you can click Changes > Merge All, which will merge most changes except for the conflicts.
Upvotes: 7