gitxelectron 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/main/index.js +177 -10
- package/out/preload/index.js +1 -0
- package/out/renderer/assets/index-C1EI1txt.css +1365 -0
- package/out/renderer/assets/{index-BPsK_u-e.js → index-Ctq_B0UN.js} +69 -12
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/out/renderer/assets/index-Cl2V4XSJ.css +0 -1365
package/out/main/index.js
CHANGED
|
@@ -577,7 +577,12 @@ function initGit(sessionId, baseDir) {
|
|
|
577
577
|
baseDir,
|
|
578
578
|
binary: "git",
|
|
579
579
|
maxConcurrentProcesses: 6,
|
|
580
|
-
unsafe: {
|
|
580
|
+
unsafe: {
|
|
581
|
+
allowUnsafeEditor: true,
|
|
582
|
+
allowUnsafeAskPass: true,
|
|
583
|
+
allowUnsafeCredentialHelper: true,
|
|
584
|
+
allowUnsafeFilter: true
|
|
585
|
+
},
|
|
581
586
|
progress: ({ method, stage, progress }) => {
|
|
582
587
|
try {
|
|
583
588
|
const wc = electron.webContents.fromId(sessionId);
|
|
@@ -598,7 +603,12 @@ function createSafeGit(baseDir, sessionId) {
|
|
|
598
603
|
const options = {
|
|
599
604
|
binary: "git",
|
|
600
605
|
maxConcurrentProcesses: 6,
|
|
601
|
-
unsafe: {
|
|
606
|
+
unsafe: {
|
|
607
|
+
allowUnsafeEditor: true,
|
|
608
|
+
allowUnsafeAskPass: true,
|
|
609
|
+
allowUnsafeCredentialHelper: true,
|
|
610
|
+
allowUnsafeFilter: true
|
|
611
|
+
},
|
|
602
612
|
progress: ({ method, stage, progress }) => {
|
|
603
613
|
if (!sessionId) return;
|
|
604
614
|
try {
|
|
@@ -1017,15 +1027,148 @@ async function pushToRemote(sessionId, remote, branch) {
|
|
|
1017
1027
|
}
|
|
1018
1028
|
}
|
|
1019
1029
|
async function pullFromRemote(sessionId, remote, branch) {
|
|
1020
|
-
const { git } = getGitSession(sessionId);
|
|
1030
|
+
const { git, repoPath } = getGitSession(sessionId);
|
|
1021
1031
|
const remotes = await getRemotes(sessionId);
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1032
|
+
if (!remotes || remotes.length === 0) {
|
|
1033
|
+
throw new Error("No remote repository configured to pull from.");
|
|
1034
|
+
}
|
|
1035
|
+
const remoteObj = (remote ? remotes.find((r) => r.name === remote) : null) || remotes[0];
|
|
1036
|
+
const targetRemote = remoteObj.name;
|
|
1037
|
+
let targetBranch = branch;
|
|
1038
|
+
if (!targetBranch) {
|
|
1039
|
+
const status = await git.status();
|
|
1040
|
+
targetBranch = status.current || "main";
|
|
1041
|
+
}
|
|
1042
|
+
const authUrl = remoteObj.refs?.fetch ? injectAuthToken(sessionId, remoteObj.refs.fetch) : targetRemote;
|
|
1043
|
+
let didStash = false;
|
|
1044
|
+
try {
|
|
1045
|
+
const status = await git.status();
|
|
1046
|
+
if (!status.isClean()) {
|
|
1047
|
+
await git.raw(["stash", "push", "-u", "-m", "gitquickpush-autostash-before-pull"]);
|
|
1048
|
+
didStash = true;
|
|
1049
|
+
}
|
|
1050
|
+
} catch (err) {
|
|
1051
|
+
console.warn("Stash check before pull warning:", err);
|
|
1052
|
+
}
|
|
1053
|
+
try {
|
|
1054
|
+
const pullArgs = [
|
|
1055
|
+
"-c",
|
|
1056
|
+
"credential.helper=",
|
|
1057
|
+
"-c",
|
|
1058
|
+
"core.longpaths=true",
|
|
1059
|
+
"-c",
|
|
1060
|
+
"filter.lfs.required=false",
|
|
1061
|
+
"-c",
|
|
1062
|
+
"filter.lfs.smudge=",
|
|
1063
|
+
"-c",
|
|
1064
|
+
"http.postBuffer=524288000",
|
|
1065
|
+
"pull",
|
|
1066
|
+
"--no-rebase",
|
|
1067
|
+
"--allow-unrelated-histories",
|
|
1068
|
+
authUrl,
|
|
1069
|
+
targetBranch
|
|
1070
|
+
];
|
|
1071
|
+
const pullOutput = await new Promise((resolve, reject) => {
|
|
1072
|
+
const child = child_process.spawn("git", pullArgs, {
|
|
1073
|
+
cwd: repoPath,
|
|
1074
|
+
env: {
|
|
1075
|
+
...process.env,
|
|
1076
|
+
GIT_LFS_SKIP_SMUDGE: "1",
|
|
1077
|
+
GCM_INTERACTIVE: "false",
|
|
1078
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
1079
|
+
GIT_ASKPASS: "echo"
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1082
|
+
let out = "";
|
|
1083
|
+
child.stdout.on("data", (d) => {
|
|
1084
|
+
out += d.toString();
|
|
1085
|
+
});
|
|
1086
|
+
child.stderr.on("data", (d) => {
|
|
1087
|
+
out += d.toString();
|
|
1088
|
+
});
|
|
1089
|
+
child.on("close", (code) => {
|
|
1090
|
+
if (code === 0) {
|
|
1091
|
+
resolve(out);
|
|
1092
|
+
} else {
|
|
1093
|
+
reject(new Error(out || `Git pull exited with code ${code}`));
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
child.on("error", (err) => reject(err));
|
|
1097
|
+
});
|
|
1098
|
+
if (didStash) {
|
|
1099
|
+
try {
|
|
1100
|
+
await git.raw(["stash", "pop"]);
|
|
1101
|
+
} catch (popErr) {
|
|
1102
|
+
console.warn("Auto-stash pop had merge notice:", popErr?.message);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
const alreadyUpToDate = pullOutput.includes("Already up to date.") || pullOutput.includes("Already up-to-date.");
|
|
1106
|
+
const lines = pullOutput.split(/[\r\n]+/).map((l) => l.trim());
|
|
1107
|
+
const changedFiles2 = [];
|
|
1108
|
+
for (const l of lines) {
|
|
1109
|
+
if (l.includes("|") && (l.includes("+") || l.includes("-"))) {
|
|
1110
|
+
const filePart = l.split("|")[0].trim();
|
|
1111
|
+
if (filePart) changedFiles2.push(filePart);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
const message = alreadyUpToDate ? "Already up to date with remote." : changedFiles2.length > 0 ? `Successfully pulled ${changedFiles2.length} file(s) from team!` : "Successfully pulled latest changes from team!";
|
|
1115
|
+
return {
|
|
1116
|
+
success: true,
|
|
1117
|
+
alreadyUpToDate,
|
|
1118
|
+
message,
|
|
1119
|
+
filesChanged: changedFiles2,
|
|
1120
|
+
raw: pullOutput
|
|
1121
|
+
};
|
|
1122
|
+
} catch (err) {
|
|
1123
|
+
if (didStash) {
|
|
1124
|
+
try {
|
|
1125
|
+
await git.raw(["stash", "pop"]);
|
|
1126
|
+
} catch {
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
const token = getToken(sessionId);
|
|
1130
|
+
let cleanMsg = err?.message || String(err);
|
|
1131
|
+
if (token) {
|
|
1132
|
+
cleanMsg = cleanMsg.split(token).join("***");
|
|
1133
|
+
}
|
|
1134
|
+
cleanMsg = cleanMsg.replace(/https:\/\/[^@]+@github\.com/g, "https://github.com");
|
|
1135
|
+
throw new Error(cleanMsg);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
async function checkRemoteUpdates(sessionId) {
|
|
1139
|
+
const { git, repoPath } = getGitSession(sessionId);
|
|
1140
|
+
try {
|
|
1141
|
+
const remotes = await getRemotes(sessionId);
|
|
1142
|
+
if (!remotes || remotes.length === 0) return { behind: 0, ahead: 0, current: "" };
|
|
1143
|
+
const remoteObj = remotes[0];
|
|
1144
|
+
const authUrl = remoteObj.refs?.fetch ? injectAuthToken(sessionId, remoteObj.refs.fetch) : remoteObj.name;
|
|
1145
|
+
await new Promise((resolve) => {
|
|
1146
|
+
const child = child_process.spawn(
|
|
1147
|
+
"git",
|
|
1148
|
+
["-c", "credential.helper=", "-c", "core.longpaths=true", "fetch", "--prune", authUrl],
|
|
1149
|
+
{
|
|
1150
|
+
cwd: repoPath,
|
|
1151
|
+
env: {
|
|
1152
|
+
...process.env,
|
|
1153
|
+
GIT_LFS_SKIP_SMUDGE: "1",
|
|
1154
|
+
GCM_INTERACTIVE: "false",
|
|
1155
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
1156
|
+
GIT_ASKPASS: "echo"
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
);
|
|
1160
|
+
child.on("close", () => resolve());
|
|
1161
|
+
child.on("error", () => resolve());
|
|
1162
|
+
});
|
|
1163
|
+
const status = await git.status();
|
|
1164
|
+
return {
|
|
1165
|
+
behind: status.behind,
|
|
1166
|
+
ahead: status.ahead,
|
|
1167
|
+
current: status.current || "main"
|
|
1168
|
+
};
|
|
1169
|
+
} catch {
|
|
1170
|
+
return { behind: 0, ahead: 0, current: "" };
|
|
1027
1171
|
}
|
|
1028
|
-
return await git.pull(remote, branch, options);
|
|
1029
1172
|
}
|
|
1030
1173
|
async function resetToRemote(sessionId, remote, branch) {
|
|
1031
1174
|
const { git } = getGitSession(sessionId);
|
|
@@ -1885,6 +2028,7 @@ const getLastWorkspace = async () => {
|
|
|
1885
2028
|
};
|
|
1886
2029
|
let currentWatcher = null;
|
|
1887
2030
|
let syncTimeout = null;
|
|
2031
|
+
let remotePollInterval = null;
|
|
1888
2032
|
let isAutoSyncEnabled = false;
|
|
1889
2033
|
let isResolving = false;
|
|
1890
2034
|
let globalOnLog = null;
|
|
@@ -1905,13 +2049,33 @@ function toggleAutoSync(sessionId, repoPath, enabled, onLog, onErrorApproval, on
|
|
|
1905
2049
|
}
|
|
1906
2050
|
if (syncTimeout) {
|
|
1907
2051
|
clearTimeout(syncTimeout);
|
|
2052
|
+
syncTimeout = null;
|
|
2053
|
+
}
|
|
2054
|
+
if (remotePollInterval) {
|
|
2055
|
+
clearInterval(remotePollInterval);
|
|
2056
|
+
remotePollInterval = null;
|
|
1908
2057
|
}
|
|
1909
2058
|
changedFiles.clear();
|
|
1910
2059
|
if (!enabled) {
|
|
1911
2060
|
onLog("Auto-Sync disabled.");
|
|
1912
2061
|
return;
|
|
1913
2062
|
}
|
|
1914
|
-
onLog("⚡ Auto-Sync enabled
|
|
2063
|
+
onLog("⚡ Auto-Sync enabled (Watching local edits & syncing team changes from GitHub)...");
|
|
2064
|
+
remotePollInterval = setInterval(async () => {
|
|
2065
|
+
if (!isAutoSyncEnabled || isResolving) return;
|
|
2066
|
+
try {
|
|
2067
|
+
const updates = await checkRemoteUpdates(sessionId);
|
|
2068
|
+
if (updates.behind > 0 && !isResolving) {
|
|
2069
|
+
onLog(`📥 Found ${updates.behind} new commit(s) from team members on GitHub! Syncing to your computer...`);
|
|
2070
|
+
const result = await pullFromRemote(sessionId);
|
|
2071
|
+
onLog(`✅ ${result.message}`);
|
|
2072
|
+
if (globalOnResolveComplete) {
|
|
2073
|
+
globalOnResolveComplete();
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
} catch {
|
|
2077
|
+
}
|
|
2078
|
+
}, 25e3);
|
|
1915
2079
|
currentWatcher = chokidar.watch(repoPath, {
|
|
1916
2080
|
ignored: [
|
|
1917
2081
|
/(^|[\/\\])\../,
|
|
@@ -2278,6 +2442,9 @@ electron.app.whenReady().then(async () => {
|
|
|
2278
2442
|
electron.ipcMain.handle("pull-from-remote", async (event, remote, branch) => {
|
|
2279
2443
|
return await pullFromRemote(event.sender.id, remote, branch);
|
|
2280
2444
|
});
|
|
2445
|
+
electron.ipcMain.handle("check-remote-updates", async (event) => {
|
|
2446
|
+
return await checkRemoteUpdates(event.sender.id);
|
|
2447
|
+
});
|
|
2281
2448
|
electron.ipcMain.handle("reset-to-remote", async (event, remote, branch) => {
|
|
2282
2449
|
return await resetToRemote(event.sender.id, remote, branch);
|
|
2283
2450
|
});
|
package/out/preload/index.js
CHANGED
|
@@ -20,6 +20,7 @@ const api = {
|
|
|
20
20
|
commitChanges: (message) => electron.ipcRenderer.invoke("commit-changes", message),
|
|
21
21
|
pushToRemote: (remote, branch) => electron.ipcRenderer.invoke("push-to-remote", remote, branch),
|
|
22
22
|
pullFromRemote: (remote, branch) => electron.ipcRenderer.invoke("pull-from-remote", remote, branch),
|
|
23
|
+
checkRemoteUpdates: () => electron.ipcRenderer.invoke("check-remote-updates"),
|
|
23
24
|
resetToRemote: (remote, branch) => electron.ipcRenderer.invoke("reset-to-remote", remote, branch),
|
|
24
25
|
fetchRemote: () => electron.ipcRenderer.invoke("fetch-remote"),
|
|
25
26
|
getBranches: () => electron.ipcRenderer.invoke("get-branches"),
|