diff --git a/src/modules/api/submodules/p2p.ts b/src/modules/api/submodules/p2p.ts
index cf35286..47bba39 100644
--- a/src/modules/api/submodules/p2p.ts
+++ b/src/modules/api/submodules/p2p.ts
@@ -70,6 +70,10 @@ interface RemotePeerInfo {
     scriptRevision?: string
     qminingPageRevision?: string
     dataEditorRevision?: string
+    serverLastCommitDate?: number
+    scriptLastCommitDate?: number
+    qminingPageLastCommitDate?: number
+    dataEditorLastCommitDate?: number
     serverBuildTime?: number
     qminingPageBuildTime?: number
     dataEditorBuildTime?: number
@@ -476,16 +480,25 @@ function setup(data: SubmoduleData): Submodule {
         }
 
         if (includeVerboseInfo) {
-            result.serverRevision = utils.getGitRevision(__dirname)
-            result.scriptRevision = utils.getGitRevision(
+            const serverRevision = utils.getGitInfo(__dirname)
+            result.serverRevision = serverRevision.revision
+            result.serverLastCommitDate = serverRevision.lastCommitDate
+
+            const scriptRevision = utils.getGitInfo(
                 paths.moodleTestUserscriptDir
             )
-            result.qminingPageRevision = utils.getGitRevision(
-                paths.qminingPageDir
-            )
-            result.dataEditorRevision = utils.getGitRevision(
-                paths.dataEditorPageDir
-            )
+            result.scriptRevision = scriptRevision.revision
+            result.scriptLastCommitDate = scriptRevision.lastCommitDate
+
+            const qminingPageRevision = utils.getGitInfo(paths.qminingPageDir)
+            result.qminingPageRevision = qminingPageRevision.revision
+            result.qminingPageLastCommitDate =
+                qminingPageRevision.lastCommitDate
+
+            const dataEditorRevision = utils.getGitInfo(paths.dataEditorPageDir)
+            result.dataEditorRevision = dataEditorRevision.revision
+            result.dataEditorLastCommitDate = dataEditorRevision.lastCommitDate
+
             result.qminingPageBuildTime = utils
                 .statFile(paths.qminingIndexPath)
                 ?.mtime.getTime()
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 63fee56..aa43dc6 100755
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -37,7 +37,7 @@ export default {
     renameFile: renameFile,
     deleteDir: deleteDir,
     formatBytes: formatBytes,
-    getGitRevision: getGitRevision,
+    getGitInfo: getGitInfo,
     getScriptVersion: getScriptVersion,
 }
 
@@ -314,17 +314,26 @@ function formatBytes(number: number, unit: 'MB' | 'GB' = 'MB'): string {
     return `${number} byte`
 }
 
-function getGitRevision(dir: string): string {
+function getGitInfo(dir: string): { lastCommitDate: number; revision: string } {
     try {
-        return child_process
+        const revision = child_process
             .execSync('git rev-parse HEAD', {
                 cwd: dir,
                 stdio: [0, 'pipe', null],
             })
             .toString()
             .trim()
+        const lastCommitDate = child_process
+            .execSync(`git show -s --format=%ct ${revision}`, {
+                cwd: dir,
+                stdio: [0, 'pipe', null],
+            })
+            .toString()
+            .trim()
+
+        return { lastCommitDate: +lastCommitDate, revision: revision }
     } catch (e) {
-        return 'Failed to get revision'
+        return { lastCommitDate: 0, revision: 'Failed to get revision' }
     }
 }
 
diff --git a/submodules/qmining-data-editor b/submodules/qmining-data-editor
index fa8d245..983695d 160000
--- a/submodules/qmining-data-editor
+++ b/submodules/qmining-data-editor
@@ -1 +1 @@
-Subproject commit fa8d2459a3f7d2c27a28dbc287525921876a3af1
+Subproject commit 983695db46afb0fc70d8f7534da71b23b6d769fb
diff --git a/submodules/qmining-page b/submodules/qmining-page
index c0a36fc..8267534 160000
--- a/submodules/qmining-page
+++ b/submodules/qmining-page
@@ -1 +1 @@
-Subproject commit c0a36fccadcf3c2b7fcb130057da7225ad0f845c
+Subproject commit 8267534a3f4279169c9ed11d0bef019b12cac2a2