Repository: ynput/OpenPype
Issue: Publisher: newly created instances and changed data

 ## Problem

Newly created instance has all data flagged as changed in call to `update_instances()` so it tried to write them again just after they were created,


[cuID:2tfezff]

Changed files:
openpype/pipeline/create/context.py, openpype/hosts/traypublisher/api/plugin.py

diff --git a/openpype/hosts/traypublisher/api/plugin.py b/openpype/hosts/traypublisher/api/plugin.py
index a3eead51c8..bdad5a0f44 100644
--- a/openpype/hosts/traypublisher/api/plugin.py
+++ b/openpype/hosts/traypublisher/api/plugin.py
@@ -104,6 +104,8 @@ class TrayPublishCreator(Creator):
 
         # Host implementation of storing metadata about instance
         HostContext.add_instance(new_instance.data_to_store())
+        new_instance.mark_as_stored()
+
         # Add instance to current context
         self._add_instance_to_context(new_instance)
 
diff --git a/openpype/pipeline/create/context.py b/openpype/pipeline/create/context.py
index eaaed39357..669358c456 100644
--- a/openpype/pipeline/create/context.py
+++ b/openpype/pipeline/create/context.py
@@ -167,7 +167,10 @@ class AttributeValues:
         return self._data.pop(key, default)
 
     def reset_values(self):
-        self._data = []
+        self._data = {}
+
+    def mark_as_stored(self):
+        self._origin_data = copy.deepcopy(self._data)
 
     @property
     def attr_defs(self):
@@ -304,6 +307,9 @@ class PublishAttributes:
         for name in self._plugin_names_order:
             yield name
 
+    def mark_as_stored(self):
+        self._origin_data = copy.deepcopy(self._data)
+
     def data_to_store(self):
         """Convert attribute values to "data to store"."""
 
@@ -623,6 +629,25 @@ class CreatedInstance:
                 changes[key] = (old_value, None)
         return changes
 
+    def mark_as_stored(self):
+        """Should be called when instance data are stored.
+
+        Origin data are replaced by current data so changes are cleared.
+        """
+
+        orig_keys = set(self._orig_data.keys())
+        for key, value in self._data.items():
+            orig_keys.discard(key)
+            if key in ("creator_attributes", "publish_attributes"):
+                continue
+            self._orig_data[key] = copy.deepcopy(value)
+
+        for key in orig_keys:
+            self._orig_data.pop(key)
+
+        self.creator_attributes.mark_as_stored()
+        self.publish_attributes.mark_as_stored()
+
     @property
     def creator_attributes(self):
         return self._data["creator_attributes"]
@@ -636,6 +661,18 @@ class CreatedInstance:
         return self._data["publish_attributes"]
 
     def data_to_store(self):
+        """Collect data that contain json parsable types.
+
+        It is possible to recreate the instance using these data.
+
+        Todo:
+            We probably don't need OrderedDict. When data are loaded they
+                are not ordered anymore.
+
+        Returns:
+            OrderedDict: Ordered dictionary with instance data.
+        """
+
         output = collections.OrderedDict()
         for key, value in self._data.items():
             if key in ("creator_attributes", "publish_attributes"):