Index: src/org/openstreetmap/josm/gui/conflict/tags/CombinePrimitiveResolverDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/conflict/tags/CombinePrimitiveResolverDialog.java	(revision 18982)
+++ src/org/openstreetmap/josm/gui/conflict/tags/CombinePrimitiveResolverDialog.java	(working copy)
@@ -3,7 +3,6 @@
 
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.tools.I18n.trn;
 
 import java.awt.BorderLayout;
 import java.awt.Component;
@@ -16,10 +15,10 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import javax.swing.AbstractAction;
 import javax.swing.Action;
@@ -26,11 +25,9 @@
 import javax.swing.JButton;
 import javax.swing.JDialog;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
 
-import org.openstreetmap.josm.actions.ExpertToggleAction;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
 import org.openstreetmap.josm.data.osm.Node;
@@ -38,7 +35,6 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.TagCollection;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
 import org.openstreetmap.josm.gui.help.HelpUtil;
@@ -45,12 +41,11 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.util.WindowGeometry;
 import org.openstreetmap.josm.gui.widgets.AutoAdjustingSplitPane;
+import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
-import org.openstreetmap.josm.tools.StreamUtils;
 import org.openstreetmap.josm.tools.UserCancelException;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
  * This dialog helps to resolve conflicts occurring when ways are combined or
@@ -471,8 +466,6 @@
      * by displaying if necessary a {@link CombinePrimitiveResolverDialog} to the user.
      * This dialog will allow the user to choose conflict resolution actions.
      *
-     * Non-expert users are informed first of the meaning of these operations, allowing them to cancel.
-     *
      * @param tagsOfPrimitives The tag collection of the primitives to be combined.
      *                         Should generally be equal to {@code TagCollection.unionOfAllPrimitives(primitives)}
      * @param primitives The primitives to be combined
@@ -496,19 +489,6 @@
         TagConflictResolutionUtil.completeTagCollectionForEditing(tagsToEdit);
 
         final Set<Relation> parentRelations = OsmPrimitive.getParentRelations(primitives);
-
-        // Show information dialogs about conflicts to non-experts
-        if (!ExpertToggleAction.isExpert()) {
-            // Tag conflicts
-            if (!completeWayTags.isApplicableToPrimitive()) {
-                informAboutTagConflicts(primitives, completeWayTags);
-            }
-            // Relation membership conflicts
-            if (!parentRelations.isEmpty()) {
-                informAboutRelationMembershipConflicts(primitives, parentRelations);
-            }
-        }
-
         final List<Command> cmds = new LinkedList<>();
 
         final TagConflictResolverModel tagModel = new TagConflictResolverModel();
@@ -516,7 +496,11 @@
 
         tagModel.populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues(), false);
         relModel.populate(parentRelations, primitives, false);
-        tagModel.prepareDefaultTagDecisions(false);
+        if (Config.getPref().getBoolean("combine-conflict-precise", true)) {
+            tagModel.prepareDefaultTagDecisions(getResolvableKeys(tagsOfPrimitives.getKeys(), primitives));
+        } else {
+            tagModel.prepareDefaultTagDecisions(false);
+        }
         relModel.prepareDefaultRelationDecisions(false);
 
         if (tagModel.isResolvedCompletely() && relModel.isResolvedCompletely()) {
@@ -566,82 +550,41 @@
     }
 
     /**
-     * Inform a non-expert user about what relation membership conflict resolution means.
-     * @param primitives The primitives to be combined
-     * @param parentRelations The parent relations of the primitives
-     * @throws UserCancelException If the user cancels the dialog.
+     * See #23305: Find those tag keys for which no conflict exists.
+     * @param keysToDecide the keys of tags which might be shown in the conflict dialog
+     * @param primitives the collection of primitives
+     * @return the keys which can be resolved using the only available value
      */
-    protected static void informAboutRelationMembershipConflicts(
-            final Collection<? extends OsmPrimitive> primitives,
-            final Set<Relation> parentRelations) throws UserCancelException {
-        /* I18n: object count < 2 is not possible */
-        String msg = trn("You are about to combine {1} object, "
-                + "which is part of {0} relation:<br/>{2}"
-                + "Combining these objects may break this relation. If you are unsure, please cancel this operation.<br/>"
-                + "If you want to continue, you are shown a dialog to decide how to adapt the relation.<br/><br/>"
-                + "Do you want to continue?",
-                "You are about to combine {1} objects, "
-                + "which are part of {0} relations:<br/>{2}"
-                + "Combining these objects may break these relations. If you are unsure, please cancel this operation.<br/>"
-                + "If you want to continue, you are shown a dialog to decide how to adapt the relations.<br/><br/>"
-                + "Do you want to continue?",
-                parentRelations.size(), parentRelations.size(), primitives.size(),
-                DefaultNameFormatter.getInstance().formatAsHtmlUnorderedList(parentRelations, 20));
-
-        if (!ConditionalOptionPaneUtil.showConfirmationDialog(
-                "combine_tags",
-                MainApplication.getMainFrame(),
-                "<html>" + msg + "</html>",
-                tr("Combine confirmation"),
-                JOptionPane.YES_NO_OPTION,
-                JOptionPane.QUESTION_MESSAGE,
-                JOptionPane.YES_OPTION)) {
-            throw new UserCancelException();
+    private static Set<String> getResolvableKeys(Set<String> keysToDecide, Collection<? extends OsmPrimitive> primitives) {
+        Set<String> easyKeys = new HashSet<>();
+        // determine the number of objects which have any of the tags which require a decision
+        int countTagged = 0;
+        for (OsmPrimitive p : primitives) {
+            for (String key : keysToDecide) {
+                if (p.hasTag(key)) {
+                    ++countTagged;
+                    break;
+                }
+            }
         }
-    }
-
-    /**
-     * Inform a non-expert user about what tag conflict resolution means.
-     * @param primitives The primitives to be combined
-     * @param normalizedTags The normalized tag collection of the primitives to be combined
-     * @throws UserCancelException If the user cancels the dialog.
-     */
-    protected static void informAboutTagConflicts(
-            final Collection<? extends OsmPrimitive> primitives,
-            final TagCollection normalizedTags) throws UserCancelException {
-        String conflicts = normalizedTags.getKeysWithMultipleValues().stream().map(
-                key -> getKeyDescription(key, normalizedTags)).collect(StreamUtils.toHtmlList());
-        String msg = /* for correct i18n of plural forms - see #9110 */ trn("You are about to combine {0} objects, "
-                + "but the following tags are used conflictingly:<br/>{1}"
-                + "If these objects are combined, the resulting object may have unwanted tags.<br/>"
-                + "If you want to continue, you are shown a dialog to fix the conflicting tags.<br/><br/>"
-                + "Do you want to continue?", "You are about to combine {0} objects, "
-                + "but the following tags are used conflictingly:<br/>{1}"
-                + "If these objects are combined, the resulting object may have unwanted tags.<br/>"
-                + "If you want to continue, you are shown a dialog to fix the conflicting tags.<br/><br/>"
-                + "Do you want to continue?",
-                primitives.size(), primitives.size(), conflicts);
-
-        if (!ConditionalOptionPaneUtil.showConfirmationDialog(
-                "combine_tags",
-                MainApplication.getMainFrame(),
-                "<html>" + msg + "</html>",
-                tr("Combine confirmation"),
-                JOptionPane.YES_NO_OPTION,
-                JOptionPane.QUESTION_MESSAGE,
-                JOptionPane.YES_OPTION)) {
-            throw new UserCancelException();
+        for (String key : keysToDecide) {
+            Set<String> values = new HashSet<>();
+            int num = 0;
+            for (OsmPrimitive p : primitives) {
+                String val = p.get(key);
+                if (val != null) {
+                    num++;
+                    values.add(val);
+                }
+            }
+            if (values.size() == 1 && num == countTagged) {
+                // there is only one value and all tagged objects have that value -> easy to solve
+                easyKeys.add(key);
+            }
         }
+        return easyKeys;
     }
 
-    private static String getKeyDescription(String key, TagCollection normalizedTags) {
-        String values = normalizedTags.getValues(key)
-                .stream()
-                .map(x -> Utils.isEmpty(x) ? tr("<i>missing</i>") : x)
-                .collect(Collectors.joining(tr(", ")));
-        return tr("{0} ({1})", key, values);
-    }
-
     @Override
     public void dispose() {
         setTargetPrimitive(null, false);
Index: src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java
===================================================================
--- src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java	(revision 18982)
+++ src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java	(working copy)
@@ -275,7 +275,7 @@
     /**
      * Prepare the default decisions for the current model
      * @param fireEvent {@code true} to call {@code fireTableDataChanged} (can be a slow operation)
-     * @since 11626
+     * @since 11627
      */
     void prepareDefaultTagDecisions(boolean fireEvent) {
         for (MultiValueResolutionDecision decision: decisions.values()) {
@@ -292,6 +292,23 @@
     }
 
     /**
+     * Prepare the default decisions for the current model.
+     * @param decidedKeys set of tag keys for which the first value should be used
+     * @since xxx
+     */
+    public void prepareDefaultTagDecisions(Set<String> decidedKeys) {
+        for (MultiValueResolutionDecision decision : decisions.values()) {
+            if (!decidedKeys.contains(decision.getKey()))
+                continue;
+            List<String> values = decision.getValues();
+            if (!values.isEmpty()) {
+                decision.keepOne(values.iterator().next());
+            }
+        }
+        rebuild(false);
+    }
+
+    /**
      * Returns the set of keys in conflict.
      * @return the set of keys in conflict.
      * @since 6616
