#1578 - Add opt-in "Merge contributors by name" preference to prevent duplicate album-artist browse entries when MusicBrainz IDs differ across the same display name.
diff --git a/HTML/EN/settings/server/behavior.html b/HTML/EN/settings/server/behavior.html
index cac772a1f98..9b67dd65098 100644
--- a/HTML/EN/settings/server/behavior.html
+++ b/HTML/EN/settings/server/behavior.html
@@ -105,6 +105,11 @@
[% END %]
+ [% WRAPPER settingGroup title="SETUP_MERGECONTRIBUTORSBYNAME" desc="SETUP_MERGECONTRIBUTORSBYNAME_DESC" %]
+
+
+ [% END %]
+
[% WRAPPER settingGroup title="SETUP_MYCLASSICALGENRES" desc="SETUP_MYCLASSICALGENRES_DESC" %]
[% END %]
diff --git a/Slim/Schema/Contributor.pm b/Slim/Schema/Contributor.pm
index 778b2603dab..2d1fa88969d 100644
--- a/Slim/Schema/Contributor.pm
+++ b/Slim/Schema/Contributor.pm
@@ -258,8 +258,19 @@ sub add {
my $mbid = $brainzIDList[$i];
my ($id, $oldExtId, $oldMbid, $sth);
- # check Musicbrainz ID first
- if ($mbid) {
+ my $preferNameMatch = $prefs->get('mergeContributorsByName');
+
+ # Default behaviour: check Musicbrainz ID first, name fallback
+ # only against rows whose musicbrainz_id is NULL.
+ #
+ # When mergeContributorsByName is enabled: look up by name first
+ # regardless of MBID, tie-breaking by preferring rows with a
+ # non-null musicbrainz_id (richer data) then by id ascending
+ # (oldest first) for determinism. MBID lookup is the fallback.
+ # This is opt-in because some libraries legitimately rely on
+ # MBIDs to distinguish two artists who share a display name
+ # (e.g. John Williams the composer vs. the guitarist).
+ if ($mbid && !$preferNameMatch) {
$sth = $dbh->prepare_cached( 'SELECT id, extid, musicbrainz_id FROM contributors WHERE musicbrainz_id = ?' );
$sth->execute($mbid);
($id, $oldExtId, $oldMbid) = $sth->fetchrow_array;
@@ -273,6 +284,24 @@ sub add {
$sth->finish;
}
}
+ elsif ($preferNameMatch && $name) {
+ $sth = $dbh->prepare_cached(
+ 'SELECT id, extid, musicbrainz_id FROM contributors WHERE name = ? '
+ . 'ORDER BY (musicbrainz_id IS NULL), id LIMIT 1'
+ );
+ $sth->execute($name);
+ ($id, $oldExtId, $oldMbid) = $sth->fetchrow_array;
+ $sth->finish;
+
+ # If no name match, fall back to MBID lookup so a brand-new
+ # contributor doesn't get split off from an existing MBID-only row.
+ if ( !$id && $mbid ) {
+ $sth = $dbh->prepare_cached( 'SELECT id, extid, musicbrainz_id FROM contributors WHERE musicbrainz_id = ?' );
+ $sth->execute($mbid);
+ ($id, $oldExtId, $oldMbid) = $sth->fetchrow_array;
+ $sth->finish;
+ }
+ }
else {
$sth = $dbh->prepare_cached( 'SELECT id, extid, musicbrainz_id FROM contributors WHERE name = ? LIMIT 1' );
$sth->execute($name);
diff --git a/Slim/Utils/Prefs.pm b/Slim/Utils/Prefs.pm
index 489e6e8db3c..ea038e93c23 100644
--- a/Slim/Utils/Prefs.pm
+++ b/Slim/Utils/Prefs.pm
@@ -189,6 +189,7 @@ sub init {
'variousArtistAutoIdentification' => 1,
'useUnifiedArtistsList' => 0,
'useTPE2AsAlbumArtist' => 1,
+ 'mergeContributorsByName' => 0,
'variousArtistsString' => undef,
'releaseTypesToIgnore' => [],
'ignoreReleaseTypes' => 0,
@@ -403,7 +404,7 @@ sub init {
$prefs->setChange(
sub { Slim::Control::Request::executeRequest(undef, ['wipecache', $prefs->get('dontTriggerScanOnPrefChange') ? 'queue' : undef]) },
- qw(splitList groupdiscs useTPE2AsAlbumArtist cleanupReleaseTypes worksScan)
+ qw(splitList groupdiscs useTPE2AsAlbumArtist mergeContributorsByName cleanupReleaseTypes worksScan)
);
$prefs->setChange( sub {
diff --git a/Slim/Web/Settings/Server/Behavior.pm b/Slim/Web/Settings/Server/Behavior.pm
index fd50cd3928a..151b820b49d 100644
--- a/Slim/Web/Settings/Server/Behavior.pm
+++ b/Slim/Web/Settings/Server/Behavior.pm
@@ -31,7 +31,7 @@ sub prefs {
ignoreReleaseTypes cleanupReleaseTypes groupArtistAlbumsByReleaseType
useTPE2AsAlbumArtist variousArtistsString ratingImplementation useUnifiedArtistsList
skipsentinel showComposerReleasesbyAlbum myClassicalGenres onlyAlbumYears
- worksScan)
+ worksScan mergeContributorsByName)
);
}
diff --git a/strings.txt b/strings.txt
index a35a095b7f1..3193119e41b 100644
--- a/strings.txt
+++ b/strings.txt
@@ -20219,6 +20219,15 @@ SETUP_USETPE2ASALBUMARTIST_0
RU Поле TPE2 тега MP3 содержит группу
SV Behandla mp3-taggen TPE2 som band
+SETUP_MERGECONTRIBUTORSBYNAME
+ EN Merge contributors by name
+
+SETUP_MERGECONTRIBUTORSBYNAME_DESC
+ EN When two tracks share the same album artist display name but carry different MusicBrainz Album Artist IDs (e.g. a band credit on MusicBrainz that uses the solo artist's name string), LMS normally creates separate contributor rows — causing duplicate browse entries for the same apparent artist. Enable this option to match contributors by display name first, ignoring MBID differences, so those tracks are grouped under a single entry. Leave disabled if your library contains genuinely distinct artists who share a name and you rely on MusicBrainz IDs to keep them apart. Changing this setting will trigger a rescan.
+
+SETUP_MERGECONTRIBUTORSBYNAME_LABEL
+ EN Merge album artist contributors with the same name, even when MusicBrainz IDs differ
+
LYRICS
CS Texty písní
DA Tekster