mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 14:01:37 +00:00
Enhance git metadata handling and improve change detection logic
- Introduced a new function `getGitMetadata` in `ApiContext` to fetch current git metadata, including new file IDs. - Updated the `PatchTree.build` function to handle new file IDs, allowing for better differentiation between tracked and untracked files during patch processing. - Modified the `git_changed_files` function to return both tracked and untracked files, improving accuracy in change detection. - Enhanced the `App` component to debounce git metadata refreshes, ensuring the UI reflects the latest changes without unnecessary calls. These changes aim to improve the integration with git and enhance the accuracy of change detection in the application.
This commit is contained in:
parent
b8bd92d665
commit
640b2d3d97
7 changed files with 128 additions and 30 deletions
|
|
@ -271,6 +271,12 @@ function ApiContext:write(patch, stageIds)
|
|||
end)
|
||||
end
|
||||
|
||||
function ApiContext:getGitMetadata()
|
||||
local url = ("%s/api/git-metadata"):format(self.__baseUrl)
|
||||
|
||||
return Http.get(url):andThen(rejectFailedRequests):andThen(Http.Response.msgpack)
|
||||
end
|
||||
|
||||
function ApiContext:connectWebSocket(packetHandlers)
|
||||
local url = ("%s/api/socket/%s"):format(self.__baseUrl, self.__messageCursor)
|
||||
-- Convert HTTP/HTTPS URL to WS/WSS
|
||||
|
|
|
|||
|
|
@ -1000,6 +1000,9 @@ function App:startSession()
|
|||
return result
|
||||
end)
|
||||
|
||||
local pendingGitRefreshThread = nil
|
||||
local GIT_METADATA_DEBOUNCE = 0.5
|
||||
|
||||
serveSession:setPatchUpdateCallback(function(instanceMap, patch, changedIds)
|
||||
-- If all changes have been reverted, auto-accept the empty patch
|
||||
if PatchSet.isEmpty(patch) then
|
||||
|
|
@ -1009,14 +1012,40 @@ function App:startSession()
|
|||
return
|
||||
end
|
||||
|
||||
-- Update the patchTree when new changes arrive during confirmation
|
||||
-- The changedIds parameter contains IDs of items that were modified
|
||||
-- so their selections can be reset (user must re-review)
|
||||
-- Immediately rebuild with stale metadata so the UI reflects new items
|
||||
local gitMetadata = cachedServerInfo and cachedServerInfo.gitMetadata
|
||||
self:setState({
|
||||
patchTree = PatchTree.build(patch, instanceMap, { "Property", "Current", "Incoming" }, gitMetadata),
|
||||
changedIds = changedIds, -- Pass to UI so it can unselect changed items
|
||||
changedIds = changedIds,
|
||||
})
|
||||
|
||||
-- Debounce: schedule a fresh git metadata fetch after rapid patches settle
|
||||
if pendingGitRefreshThread then
|
||||
task.cancel(pendingGitRefreshThread)
|
||||
end
|
||||
pendingGitRefreshThread = task.delay(GIT_METADATA_DEBOUNCE, function()
|
||||
pendingGitRefreshThread = nil
|
||||
apiContext
|
||||
:getGitMetadata()
|
||||
:andThen(function(freshMetadata)
|
||||
if cachedServerInfo then
|
||||
cachedServerInfo.gitMetadata = freshMetadata
|
||||
end
|
||||
if self.state.appStatus == AppStatus.Confirming then
|
||||
self:setState({
|
||||
patchTree = PatchTree.build(
|
||||
patch,
|
||||
instanceMap,
|
||||
{ "Property", "Current", "Incoming" },
|
||||
freshMetadata
|
||||
),
|
||||
})
|
||||
end
|
||||
end)
|
||||
:catch(function(err)
|
||||
Log.warn("Failed to refresh git metadata: {}", tostring(err))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
-- One-shot sync: disconnect after initial sync is fully complete (including any writes)
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ local PatchTree = {}
|
|||
|
||||
-- Builds a new tree from a patch and instanceMap
|
||||
-- uses changeListHeaders in node.changeList
|
||||
-- gitMetadata is optional: { changedIds: {string}, scriptCommittedHashes: {[string]: {string}} }
|
||||
-- gitMetadata is optional: { changedIds: {string}, scriptCommittedHashes: {[string]: {string}}, newFileIds: {string}? }
|
||||
function PatchTree.build(patch, instanceMap, changeListHeaders, gitMetadata)
|
||||
Timer.start("PatchTree.build")
|
||||
local clock = os.clock()
|
||||
|
|
@ -267,6 +267,14 @@ function PatchTree.build(patch, instanceMap, changeListHeaders, gitMetadata)
|
|||
end
|
||||
end
|
||||
|
||||
local newFileIdSet = nil
|
||||
if gitMetadata and gitMetadata.newFileIds then
|
||||
newFileIdSet = {}
|
||||
for _, id in gitMetadata.newFileIds do
|
||||
newFileIdSet[id] = true
|
||||
end
|
||||
end
|
||||
|
||||
Timer.start("patch.updated")
|
||||
for _, change in patch.updated do
|
||||
clock = yieldIfNeeded(clock)
|
||||
|
|
@ -518,8 +526,14 @@ function PatchTree.build(patch, instanceMap, changeListHeaders, gitMetadata)
|
|||
table.insert(changeList, 1, changeListHeaders)
|
||||
end
|
||||
|
||||
-- Add this node to tree
|
||||
-- Default to nil (unselected) - user must explicitly choose Push/Pull/Skip
|
||||
-- Truly new files (untracked in git) default to "push" (Atlas).
|
||||
-- Tracked files appearing as additions are ambiguous (Studio may have
|
||||
-- deleted them), so they remain nil for user review.
|
||||
local defaultSelection = nil
|
||||
if newFileIdSet and newFileIdSet[id] then
|
||||
defaultSelection = "push"
|
||||
end
|
||||
|
||||
tree:addNode(change.Parent, {
|
||||
id = change.Id,
|
||||
patchType = "Add",
|
||||
|
|
@ -528,7 +542,7 @@ function PatchTree.build(patch, instanceMap, changeListHeaders, gitMetadata)
|
|||
changeInfo = changeInfo,
|
||||
changeList = changeList,
|
||||
instance = instanceMap.fromIds[id],
|
||||
defaultSelection = nil,
|
||||
defaultSelection = defaultSelection,
|
||||
})
|
||||
end
|
||||
Timer.stop()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue