all-hands-cli 0.1.7 → 0.1.8
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/bin/sync-cli.js +18 -1
- package/package.json +1 -1
- package/src/commands/push.ts +21 -2
- package/src/lib/git.ts +19 -0
package/bin/sync-cli.js
CHANGED
|
@@ -4905,6 +4905,15 @@ function getGitFiles(repoPath) {
|
|
|
4905
4905
|
}
|
|
4906
4906
|
return files;
|
|
4907
4907
|
}
|
|
4908
|
+
function getFileBlobHash(filePath, repoPath) {
|
|
4909
|
+
const result = git(["hash-object", filePath], repoPath);
|
|
4910
|
+
return result.success ? result.stdout.trim() : null;
|
|
4911
|
+
}
|
|
4912
|
+
function fileExistsInHistory(relPath, blobHash, repoPath) {
|
|
4913
|
+
const result = git(["rev-list", "HEAD", "--objects", "--", relPath], repoPath);
|
|
4914
|
+
if (!result.success || !result.stdout) return false;
|
|
4915
|
+
return result.stdout.split("\n").some((line) => line.startsWith(blobHash + " "));
|
|
4916
|
+
}
|
|
4908
4917
|
|
|
4909
4918
|
// src/lib/manifest.ts
|
|
4910
4919
|
import { readFileSync as readFileSync5, existsSync as existsSync3, statSync as statSync3 } from "fs";
|
|
@@ -7224,6 +7233,12 @@ function checkPrerequisites(cwd) {
|
|
|
7224
7233
|
}
|
|
7225
7234
|
return { success: true, ghUser };
|
|
7226
7235
|
}
|
|
7236
|
+
function wasModifiedByTargetRepo(cwd, relPath, allhandsRoot) {
|
|
7237
|
+
const localFile = join9(cwd, relPath);
|
|
7238
|
+
const localBlobHash = getFileBlobHash(localFile, allhandsRoot);
|
|
7239
|
+
if (!localBlobHash) return true;
|
|
7240
|
+
return !fileExistsInHistory(relPath, localBlobHash, allhandsRoot);
|
|
7241
|
+
}
|
|
7227
7242
|
function collectFilesToPush(cwd, finalIncludes, finalExcludes) {
|
|
7228
7243
|
const allhandsRoot = getAllhandsRoot();
|
|
7229
7244
|
const manifest = new Manifest(allhandsRoot);
|
|
@@ -7246,7 +7261,9 @@ function collectFilesToPush(cwd, finalIncludes, finalExcludes) {
|
|
|
7246
7261
|
const localFile = join9(cwd, relPath);
|
|
7247
7262
|
const upstreamFile = join9(allhandsRoot, relPath);
|
|
7248
7263
|
if (existsSync11(localFile) && filesAreDifferent(localFile, upstreamFile)) {
|
|
7249
|
-
|
|
7264
|
+
if (wasModifiedByTargetRepo(cwd, relPath, allhandsRoot)) {
|
|
7265
|
+
filesToPush.push({ path: relPath, type: "M" });
|
|
7266
|
+
}
|
|
7250
7267
|
}
|
|
7251
7268
|
}
|
|
7252
7269
|
for (const pattern of finalIncludes) {
|
package/package.json
CHANGED
package/src/commands/push.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { tmpdir } from 'os';
|
|
|
3
3
|
import { dirname, join } from 'path';
|
|
4
4
|
import { minimatch } from 'minimatch';
|
|
5
5
|
import * as readline from 'readline';
|
|
6
|
-
import { git, isGitRepo, getGitFiles } from '../lib/git.js';
|
|
6
|
+
import { git, isGitRepo, getGitFiles, getFileBlobHash, fileExistsInHistory } from '../lib/git.js';
|
|
7
7
|
import { checkGhAuth, checkGhInstalled, getGhUser, gh } from '../lib/gh.js';
|
|
8
8
|
import { Manifest, filesAreDifferent } from '../lib/manifest.js';
|
|
9
9
|
import { getAllhandsRoot, UPSTREAM_REPO } from '../lib/paths.js';
|
|
@@ -94,6 +94,23 @@ function checkPrerequisites(cwd: string): PrerequisiteResult {
|
|
|
94
94
|
return { success: true, ghUser };
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Determine if a file was actually modified by the target repo,
|
|
99
|
+
* vs simply being out of date because upstream moved forward.
|
|
100
|
+
*
|
|
101
|
+
* Compares the target file's content against all historical versions
|
|
102
|
+
* in the upstream repo. If it matches any previous version, the target
|
|
103
|
+
* repo hasn't modified it.
|
|
104
|
+
*/
|
|
105
|
+
function wasModifiedByTargetRepo(cwd: string, relPath: string, allhandsRoot: string): boolean {
|
|
106
|
+
const localFile = join(cwd, relPath);
|
|
107
|
+
const localBlobHash = getFileBlobHash(localFile, allhandsRoot);
|
|
108
|
+
|
|
109
|
+
if (!localBlobHash) return true; // safe default: assume modified on error
|
|
110
|
+
|
|
111
|
+
return !fileExistsInHistory(relPath, localBlobHash, allhandsRoot);
|
|
112
|
+
}
|
|
113
|
+
|
|
97
114
|
function collectFilesToPush(
|
|
98
115
|
cwd: string,
|
|
99
116
|
finalIncludes: string[],
|
|
@@ -126,7 +143,9 @@ function collectFilesToPush(
|
|
|
126
143
|
const upstreamFile = join(allhandsRoot, relPath);
|
|
127
144
|
|
|
128
145
|
if (existsSync(localFile) && filesAreDifferent(localFile, upstreamFile)) {
|
|
129
|
-
|
|
146
|
+
if (wasModifiedByTargetRepo(cwd, relPath, allhandsRoot)) {
|
|
147
|
+
filesToPush.push({ path: relPath, type: 'M' });
|
|
148
|
+
}
|
|
130
149
|
}
|
|
131
150
|
}
|
|
132
151
|
|
package/src/lib/git.ts
CHANGED
|
@@ -61,3 +61,22 @@ export function getGitFiles(repoPath: string): string[] {
|
|
|
61
61
|
}
|
|
62
62
|
return files;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Compute the git blob hash of a file (works on files outside the repo).
|
|
67
|
+
*/
|
|
68
|
+
export function getFileBlobHash(filePath: string, repoPath: string): string | null {
|
|
69
|
+
const result = git(['hash-object', filePath], repoPath);
|
|
70
|
+
return result.success ? result.stdout.trim() : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Check if a specific blob hash appears in the git history of a file path.
|
|
75
|
+
* Uses a single `rev-list --objects` call instead of per-commit lookups.
|
|
76
|
+
*/
|
|
77
|
+
export function fileExistsInHistory(relPath: string, blobHash: string, repoPath: string): boolean {
|
|
78
|
+
const result = git(['rev-list', 'HEAD', '--objects', '--', relPath], repoPath);
|
|
79
|
+
if (!result.success || !result.stdout) return false;
|
|
80
|
+
|
|
81
|
+
return result.stdout.split('\n').some(line => line.startsWith(blobHash + ' '));
|
|
82
|
+
}
|