gitdone-agent 0.7.1 → 0.7.3
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/index.js +52 -7
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -561,6 +561,28 @@ function gitTry(cmd, cwd) {
|
|
|
561
561
|
}
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
+
// Like gitTry(), but hands git an ARGV array instead of a shell command string,
|
|
565
|
+
// so git.exe runs directly with no shell in between. A shell string goes through
|
|
566
|
+
// cmd.exe on Windows, which (a) mangles Cyrillic and (b) treats &, |, %, ^, <, >
|
|
567
|
+
// as operators — so a Bulgarian commit message, or a path containing such a
|
|
568
|
+
// character, silently corrupted the command and the commit failed. The old
|
|
569
|
+
// commit path swallowed that via git() + `|| 'committed'` and reported a fake
|
|
570
|
+
// success while nothing was committed (gd-445). gitDiffUntracked() already uses
|
|
571
|
+
// execFileSync for the same reason. Local calls get 2 min; pass net for 5.
|
|
572
|
+
function gitArgs(args, cwd, { net = false } = {}) {
|
|
573
|
+
try {
|
|
574
|
+
const out = execFileSync('git', args, {
|
|
575
|
+
cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'],
|
|
576
|
+
maxBuffer: GIT_MAX_BUFFER, timeout: net ? GIT_NET_TIMEOUT_MS : GIT_TIMEOUT_MS, env: GIT_ENV,
|
|
577
|
+
}).trim()
|
|
578
|
+
return { ok: true, out }
|
|
579
|
+
} catch (err) {
|
|
580
|
+
const timedOut = err.signal === 'SIGTERM' && err.code == null
|
|
581
|
+
const out = (err.stderr || err.stdout || (timedOut ? `git не отговори и беше прекратен` : err.message) || '').toString().trim()
|
|
582
|
+
return { ok: false, out }
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
564
586
|
// Never let a token reach the log file or the server's command-result.
|
|
565
587
|
function redact(text, token) {
|
|
566
588
|
if (!text || !token) return text
|
|
@@ -762,7 +784,18 @@ function getSnapshot(repoPath) {
|
|
|
762
784
|
// -uall lists every untracked file individually instead of collapsing a new
|
|
763
785
|
// directory into a single `dir/` entry — so the change list matches what
|
|
764
786
|
// GitHub Desktop shows, file-for-file (gd-369).
|
|
765
|
-
|
|
787
|
+
// Read the status RAW (not via git(), which .trim()s the whole output). The
|
|
788
|
+
// porcelain format is fixed-width — 2 status columns, a space, then the path —
|
|
789
|
+
// and the first line of a worktree-only change starts with a space (e.g.
|
|
790
|
+
// " M .env.example"). git().trim() ate that leading space on the FIRST line
|
|
791
|
+
// only, shifting its columns so the path lost its first character (".env.example"
|
|
792
|
+
// → "env.example"); the mangled path then failed `git add` (or, before gd-445,
|
|
793
|
+
// failed silently). Strip only a trailing \r per line, never leading spaces (gd-446).
|
|
794
|
+
const statusLines = gitRaw('git status --porcelain -uall', repoPath)
|
|
795
|
+
.toString('utf8')
|
|
796
|
+
.split('\n')
|
|
797
|
+
.map((l) => l.replace(/\r$/, ''))
|
|
798
|
+
.filter(Boolean)
|
|
766
799
|
const modified = []
|
|
767
800
|
const staged = []
|
|
768
801
|
const statuses = {}
|
|
@@ -1700,20 +1733,32 @@ async function executeCommand(cfg, cmd, repoPath) {
|
|
|
1700
1733
|
const auth = cfg.auth?.[repoPath] ?? null
|
|
1701
1734
|
try {
|
|
1702
1735
|
if (cmd.type === 'commit') {
|
|
1703
|
-
|
|
1736
|
+
// Everything here goes through gitArgs (argv, no shell): the message and the
|
|
1737
|
+
// paths are user/Cyrillic data that cmd.exe would corrupt, which used to make
|
|
1738
|
+
// the commit fail silently while the console showed a fake ✓ (gd-445).
|
|
1739
|
+
const msg = (cmd.payload?.message ?? '').trim() || 'commit'
|
|
1704
1740
|
// When the UI sends a list of selected files, stage ONLY those so the
|
|
1705
1741
|
// resulting commit (and the push that follows) contains just the checked
|
|
1706
1742
|
// files. No list → stage everything (old behaviour / older UIs).
|
|
1707
1743
|
const files = Array.isArray(cmd.payload?.files)
|
|
1708
1744
|
? cmd.payload.files.filter((f) => typeof f === 'string' && f.trim())
|
|
1709
1745
|
: []
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1746
|
+
const add = files.length
|
|
1747
|
+
? gitArgs(['add', '--', ...files], repoPath)
|
|
1748
|
+
: gitArgs(['add', '-A'], repoPath)
|
|
1749
|
+
if (!add.ok) throw new Error(`git add се провали: ${add.out}`)
|
|
1750
|
+
const commit = gitArgs(['commit', '-m', msg], repoPath)
|
|
1751
|
+
if (commit.ok) {
|
|
1752
|
+
result = commit.out || 'committed'
|
|
1753
|
+
} else if (/nothing to commit|no changes added|working tree clean/i.test(commit.out)) {
|
|
1754
|
+
// Benign: the checked files carried no staged change (already committed or
|
|
1755
|
+
// whitespace-only). Say so plainly instead of faking success.
|
|
1756
|
+
result = 'няма промени за commit'
|
|
1713
1757
|
} else {
|
|
1714
|
-
|
|
1758
|
+
// Real failure (hook, identity, lock, corrupt path…) — surface it so the
|
|
1759
|
+
// console shows the reason instead of the old silent fake ✓.
|
|
1760
|
+
throw new Error(commit.out || 'git commit се провали')
|
|
1715
1761
|
}
|
|
1716
|
-
result = git(`git commit -m "${msg}"`, repoPath) || 'committed'
|
|
1717
1762
|
} else if (cmd.type === 'push' || cmd.type === 'pull') {
|
|
1718
1763
|
result = pushOrPull(cmd.type, repoPath, auth)
|
|
1719
1764
|
} else if (cmd.type === 'discard') {
|