Index: /trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java	(revision 19397)
+++ /trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java	(revision 19398)
@@ -323,6 +323,6 @@
 
     /**
-     * Returns the list of conflicts involving nodes.
-     * @return The list of conflicts involving nodes.
+     * Returns the list of conflicts involving ways.
+     * @return The list of conflicts involving ways.
      * @since 6555
      */
@@ -332,6 +332,6 @@
 
     /**
-     * Returns the list of conflicts involving nodes.
-     * @return The list of conflicts involving nodes.
+     * Returns the list of conflicts involving relations.
+     * @return The list of conflicts involving relations.
      * @since 6555
      */
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 19397)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 19398)
@@ -65,4 +65,5 @@
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.MainMenu;
+import org.openstreetmap.josm.gui.Notification;
 import org.openstreetmap.josm.gui.ScrollViewport;
 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
@@ -1062,9 +1063,26 @@
     public void commandChanged(int queueSize, int redoSize) {
         Relation r = getRelation();
-        if (r != null && r.getDataSet() == null) {
-            // see #19915
-            setRelation(null);
-            applyAction.updateEnabledState();
-        }
+        if (r != null) {
+            if (r.getDataSet() == null) {
+                // see #19915
+                setRelation(null);
+                applyAction.updateEnabledState();
+            } else if (isDirtyRelation()) {
+                if (!isDirtyEditor()) {
+                    reloadDataFromRelation();
+                } else {
+                    new Notification(tr("Relation modified outside of relation editor with pending changes. Conflict resolution required."))
+                    .setIcon(JOptionPane.WARNING_MESSAGE).show();
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean isDirtyEditor() {
+        Relation snapshot = getRelationSnapshot();
+        Relation relation = getRelation();
+        return (snapshot != null && !memberTableModel.hasSameMembersAs(snapshot)) ||
+                tagEditorPanel.getModel().isDirty() || relation == null || relation.getDataSet() == null;
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/IRelationEditor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/IRelationEditor.java	(revision 19397)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/IRelationEditor.java	(revision 19398)
@@ -40,5 +40,29 @@
      * @return true if the currently edited relation has been changed elsewhere.
      */
-    boolean isDirtyRelation();
+    default boolean isDirtyRelation() {
+        return isDirtyRelation(false);
+    }
+
+    /**
+     * Replies true if the currently edited relation has been changed elsewhere.
+     *
+     * In this case a relation editor can't apply updates to the relation directly. Rather,
+     * it has to create a conflict.
+     *
+     * @param ignoreUninterestingTags whether to ignore uninteresting tag changes
+     * @return true if the currently edited relation has been changed elsewhere.
+     * @since xxx
+     */
+    boolean isDirtyRelation(boolean ignoreUninterestingTags);
+
+    /**
+     * Replies true if the relation has been changed in the editor (but not yet applied).
+     *
+     * Reloading data from the relation would cause the pending changes to be lost.
+     *
+     * @return true if the currently edited relation has been changed in the editor.
+     * @since xxx
+     */
+    boolean isDirtyEditor();
 
     /**
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java	(revision 19397)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java	(revision 19398)
@@ -148,5 +148,15 @@
     @Override
     public final boolean isDirtyRelation() {
-        return !relation.hasEqualSemanticAttributes(relationSnapshot);
+        return isDirtyRelation(false);
+    }
+
+    @Override
+    public final boolean isDirtyRelation(boolean ignoreUninterestingTags) {
+        if (relation != null && relation.getDataSet() == null &&
+            relationSnapshot != null && relationSnapshot.getDataSet() == null) {
+            return false;
+        }
+
+        return !relation.hasEqualSemanticAttributes(relationSnapshot, ignoreUninterestingTags);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java	(revision 19397)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/RefreshAction.java	(revision 19398)
@@ -68,15 +68,5 @@
     @Override
     public void updateEnabledState() {
-        Relation snapshot = getEditor().getRelationSnapshot();
-        Relation relation = getEditor().getRelation();
-        if (relation != null && relation.getDataSet() == null)
-            relation = null; // see #19915
-        if (relation != null && snapshot != null && snapshot.getDataSet() == null) {
-            // relation was changed outside of the editor
-            // either it was modified or deleted or changed by an undo
-            setEnabled(!snapshot.hasEqualSemanticAttributes(relation, false /* don't ignore uninteresting keys */));
-            return;
-        }
-        setEnabled(false);
+        setEnabled(getEditor().isDirtyRelation());
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java	(revision 19397)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java	(revision 19398)
@@ -193,7 +193,5 @@
 
     protected boolean isEditorDirty() {
-        Relation snapshot = editorAccess.getEditor().getRelationSnapshot();
-        return (snapshot != null && !getMemberTableModel().hasSameMembersAs(snapshot)) || getTagModel().isDirty()
-                || getEditor().getRelation() == null || getEditor().getRelation().getDataSet() == null;
+        return editorAccess.getEditor().isDirtyEditor();
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditorTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditorTest.java	(revision 19397)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditorTest.java	(revision 19398)
@@ -91,4 +91,14 @@
             @Override
             public boolean isDirtyRelation() {
+                return false;
+            }
+
+            @Override
+            public boolean isDirtyRelation(boolean ignoreUninterestingTags) {
+                return false;
+            }
+
+            @Override
+            public boolean isDirtyEditor() {
                 return false;
             }
