From cd78f5c02c876d74a8e94945b906a5f07cac2738 Mon Sep 17 00:00:00 2001 From: boatbomber Date: Tue, 14 Oct 2025 12:13:59 -0700 Subject: [PATCH] Fix postcommit callbacks being skipped (#1132) --- CHANGELOG.md | 6 +++++ plugin/src/App/init.lua | 52 ++++++++++++++----------------------- plugin/src/ServeSession.lua | 27 +++++++------------ 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4422d9be..eb83f987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Rojo Changelog +## Unreleased + +* Fixed a bug where the last sync timestamp was not updating correctly in the plugin ([#1132]) + +[#1132]: https://github.com/rojo-rbx/rojo/pull/1132 + ## 7.6.0 - October 10th, 2025 * Added flag to `rojo init` to skip initializing a git repository ([#1122]) * Added fallback method for when an Instance can't be synced through normal means ([#1030]) diff --git a/plugin/src/App/init.lua b/plugin/src/App/init.lua index ae03a6f1..f38596dd 100644 --- a/plugin/src/App/init.lua +++ b/plugin/src/App/init.lua @@ -602,46 +602,32 @@ function App:startSession() }) end) self.cleanupPostcommit = serveSession:hookPostcommit(function(patch, instanceMap, unappliedPatch) - -- Update tree with unapplied metadata + local now = DateTime.now().UnixTimestamp self:setState(function(prevState) + local oldPatchData = prevState.patchData + local newPatchData = { + patch = patch, + unapplied = unappliedPatch, + timestamp = now, + } + + if PatchSet.isEmpty(patch) then + -- Keep existing patch info, but use new timestamp + newPatchData.patch = oldPatchData.patch + newPatchData.unapplied = oldPatchData.unapplied + elseif now - oldPatchData.timestamp < 2 then + -- Patches that apply in the same second are combined for human clarity + newPatchData.patch = PatchSet.assign(PatchSet.newEmpty(), oldPatchData.patch, patch) + newPatchData.unapplied = PatchSet.assign(PatchSet.newEmpty(), oldPatchData.unapplied, unappliedPatch) + end + return { patchTree = PatchTree.updateMetadata(prevState.patchTree, patch, instanceMap, unappliedPatch), + patchData = newPatchData, } end) end) - serveSession:hookPostcommit(function(patch, _instanceMap, unapplied) - local now = DateTime.now().UnixTimestamp - local old = self.state.patchData - - if PatchSet.isEmpty(patch) then - -- Ignore empty patch, but update timestamp - self:setState({ - patchData = { - patch = old.patch, - unapplied = old.unapplied, - timestamp = now, - }, - }) - return - end - - if now - old.timestamp < 2 then - -- Patches that apply in the same second are - -- considered to be part of the same change for human clarity - patch = PatchSet.assign(PatchSet.newEmpty(), old.patch, patch) - unapplied = PatchSet.assign(PatchSet.newEmpty(), old.unapplied, unapplied) - end - - self:setState({ - patchData = { - patch = patch, - unapplied = unapplied, - timestamp = now, - }, - }) - end) - serveSession:onStatusChanged(function(status, details) if status == ServeSession.Status.Connecting then if self.dismissSyncReminder then diff --git a/plugin/src/ServeSession.lua b/plugin/src/ServeSession.lua index 9994be10..38971379 100644 --- a/plugin/src/ServeSession.lua +++ b/plugin/src/ServeSession.lua @@ -349,18 +349,11 @@ function ServeSession:__applyPatch(patch) error(unappliedPatch) end - if PatchSet.isEmpty(unappliedPatch) then - if historyRecording then - ChangeHistoryService:FinishRecording(historyRecording, Enum.FinishRecordingOperation.Commit) - end - return - end + if Settings:get("enableSyncFallback") and not PatchSet.isEmpty(unappliedPatch) then + -- Some changes did not apply, let's try replacing them instead + local addedIdList = PatchSet.addedIdList(unappliedPatch) + local updatedIdList = PatchSet.updatedIdList(unappliedPatch) - local addedIdList = PatchSet.addedIdList(unappliedPatch) - local updatedIdList = PatchSet.updatedIdList(unappliedPatch) - - local actualUnappliedPatches = PatchSet.newEmpty() - if Settings:get("enableSyncFallback") then Log.debug("ServeSession:__replaceInstances(unappliedPatch.added)") Timer.start("ServeSession:__replaceInstances(unappliedPatch.added)") local addSuccess, unappliedAddedRefs = self:__replaceInstances(addedIdList) @@ -371,20 +364,18 @@ function ServeSession:__applyPatch(patch) local updateSuccess, unappliedUpdateRefs = self:__replaceInstances(updatedIdList) Timer.stop() + -- Update the unapplied patch to reflect which Instances were replaced successfully if addSuccess then table.clear(unappliedPatch.added) - PatchSet.assign(actualUnappliedPatches, unappliedAddedRefs) + PatchSet.assign(unappliedPatch, unappliedAddedRefs) end if updateSuccess then table.clear(unappliedPatch.updated) - PatchSet.assign(actualUnappliedPatches, unappliedUpdateRefs) + PatchSet.assign(unappliedPatch, unappliedUpdateRefs) end - else - Log.debug("Skipping ServeSession:__replaceInstances because of setting") end - PatchSet.assign(actualUnappliedPatches, unappliedPatch) - if not PatchSet.isEmpty(actualUnappliedPatches) then + if not PatchSet.isEmpty(unappliedPatch) then Log.debug( "Could not apply all changes requested by the Rojo server:\n{}", PatchSet.humanSummary(self.__instanceMap, unappliedPatch) @@ -396,7 +387,7 @@ function ServeSession:__applyPatch(patch) -- guaranteed to be called after the commit for _, callback in self.__postcommitCallbacks do task.spawn(function() - local success, err = pcall(callback, patch, self.__instanceMap, actualUnappliedPatches) + local success, err = pcall(callback, patch, self.__instanceMap, unappliedPatch) if not success then Log.warn("Postcommit hook errored: {}", err) end