git-chopstick-core 0.1.11 → 0.1.13

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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.13] — 2026-06-13
4
+
5
+ ### Added
6
+ - **`getRepositories(rootPath, options?)`**: New `src/git/discover.ts` module for discovering git repos in a directory tree. Walks directories using `fs.opendir` with depth control (default 5), skips `node_modules`/`.git`/`.yarn`/etc., handles symlinks and worktree `.git` files. Returns `Repository[]`.
7
+ - **`WorkingDirectoryFileChangeSummary`** type: Like `WorkingDirectoryChangeSummary` but includes `selectionType` and `selection` for staging decisions.
8
+ - **`getWorkingDirectoryChangesDetailed(repository)`**: Selection-aware variant of `getWorkingDirectoryChanges` that returns `WorkingDirectoryFileChangeSummary[]` with `DiffSelection` objects.
9
+ - **`fileChangeSummaryToWorkingDirectoryFile(summary)`**: Lossy roundtrip helper to convert a `WorkingDirectoryFileChangeSummary` back to `WorkingDirectoryFileChange` for use with `stageFiles()`.
10
+ - **Integration tests**: 8 new tests covering `getWorkingDirectoryChangesDetailed` (3), `fileChangeSummaryToWorkingDirectoryFile` roundtrip (2), and `getRepositories` (5). Total: 56 tests.
11
+
12
+ ### Changed
13
+ - **README Known Limitations**: Removed stale "Integration Tests" item from Known Limitations section (not a limitation). Cleaned up section.
14
+ - **README API reference**: Added `discover` module, `getWorkingDirectoryChangesDetailed`, `fileChangeSummaryToWorkingDirectoryFile`, `WorkingDirectoryChangeSummary`, and `WorkingDirectoryFileChangeSummary` to tables.
15
+ - **`src/git/index.ts`**: Added `discover.js` to barrel exports.
16
+ - **`src/git/status.ts`**: Re-exports `DiffSelectionType` and `DiffSelection` at module level for convenient imports.
17
+
18
+ ---
19
+
3
20
  ## [0.1.11] — 2026-06-13
4
21
 
5
22
  ### Added
@@ -175,6 +192,7 @@
175
192
 
176
193
  ---
177
194
 
195
+ [0.1.13]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.13
178
196
  [0.1.11]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.11
179
197
  [0.1.10]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.10
180
198
  [0.1.9]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.9
@@ -187,4 +205,4 @@
187
205
  [0.1.2]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.2
188
206
  [0.1.1]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.1
189
207
  [0.1.0]: https://github.com/parkiyong/git-chopstick-core/releases/tag/v0.1.0
190
- [Unreleased]: https://github.com/parkiyong/git-chopstick-core/compare/v0.1.11...HEAD
208
+ [Unreleased]: https://github.com/parkiyong/git-chopstick-core/compare/v0.1.13...HEAD
package/README.md CHANGED
@@ -213,6 +213,7 @@ try {
213
213
  | `config` | `getConfigValue`, `getGlobalConfigValue`, `getBooleanConfigValue` | Read git config |
214
214
  | `diff` | `getWorkingDirectoryDiff`, `getCommitDiff`, `getBranchMergeBaseDiff`, `getCommitRangeDiff`, `getBinaryPaths` | Diff rendering |
215
215
  | `diff-index` | `getIndexChanges` | Compare index with tree |
216
+ | `discover` | `getRepositories` | Discover git repos in a directory tree (monorepo support) |
216
217
  | `fetch` | `fetch`, `fetchRefspec`, `fastForwardBranches` | Fetch from remotes |
217
218
  | `for-each-ref` | `getBranches`, `getBranchesDifferingFromUpstream` | List refs |
218
219
  | `format-patch` | `formatPatch` | Generate patch files |
@@ -238,7 +239,7 @@ try {
238
239
  | `squash` | `squash` | Interactive rebase squashing |
239
240
  | `stage` | `stageManualConflictResolution`, `stageResolvedConflictFiles` | Stage conflict resolutions |
240
241
  | `stash` | `getStashes`, `getStashesByPath`, `createStashEntry`, `popStashEntry`, `getStashedFiles`, `dropStashEntry` | Stash management |
241
- | `status` | `getStatus` | Repository status |
242
+ | `status` | `getStatus`, `getWorkingDirectoryChanges`, `getWorkingDirectoryChangesDetailed`, `fileChangeSummaryToWorkingDirectoryFile` | Repository status + flat summaries + selection-aware variant with roundtrip |
242
243
  | `submodule` | `updateSubmodulesAfterOperation`, `listSubmodules`, `resetSubmodulePaths` | Submodule operations |
243
244
  | `tag` | `createTag`, `deleteTag`, `getTags`, `getAllTags` | Tag management |
244
245
  | `update-index` | `stageFiles` | Stage files |
@@ -263,6 +264,8 @@ try {
263
264
  | `WorkingDirectoryFileChange` | class | Uncommitted file change with diff selection |
264
265
  | `CommittedFileChange` | class | File change from a commit |
265
266
  | `WorkingDirectoryStatus` | class | Container for working directory changes |
267
+ | `WorkingDirectoryChangeSummary` | type | `{ path: string; status: string; oldPath?: string }` — flattened working directory change |
268
+ | `WorkingDirectoryFileChangeSummary` | type | Like `WorkingDirectoryChangeSummary` but also includes `selectionType` + `selection` for staging decisions |
266
269
  | `DiffSelection` / `DiffSelectionType` | class/enum | Partial file staging |
267
270
  | `ComputedAction` | enum | `Clean`, `Conflicts`, `Invalid`, `Loading` |
268
271
  | `ManualConflictResolution` | enum | `theirs` / `ours` |
@@ -295,10 +298,6 @@ Note: `git revert` does not produce progress output, so `RevertProgressParser` s
295
298
 
296
299
  `withTrampolineEnv` is a **stub** that calls through without setting up the Git LFS trampoline environment. Git LFS operations may not work correctly as a result.
297
300
 
298
- ### 🟢 Integration Tests
299
-
300
- Integration tests are available in `src/__tests__/integration.test.ts` and run against real git repositories in temp directories. Run `npm test` to execute them.
301
-
302
301
  ---
303
302
 
304
303
  ## Architecture
@@ -0,0 +1,37 @@
1
+ import { Repository } from '../models/repository.js';
2
+ /**
3
+ * Options for {@link getRepositories}.
4
+ */
5
+ export interface GetRepositoriesOptions {
6
+ /**
7
+ * Maximum recursion depth. Defaults to 5.
8
+ * Set to `-1` for unlimited depth.
9
+ */
10
+ readonly depth?: number;
11
+ /**
12
+ * Directories to skip when walking the tree.
13
+ * Defaults to `['node_modules', '.git', '.hg', '.svn', '.yarn', '.pnp']`.
14
+ */
15
+ readonly skipDirs?: ReadonlySet<string>;
16
+ /**
17
+ * Whether to include bare repositories. Defaults to `false`.
18
+ * Bare repos have no working directory and `Repository.path` will
19
+ * point to the bare git directory.
20
+ */
21
+ readonly includeBare?: boolean;
22
+ }
23
+ /**
24
+ * Discover git repositories in a directory tree.
25
+ *
26
+ * Walks the directory tree under `rootPath`, looking for `.git` entries
27
+ * (directories for regular repos, or files for worktrees and submodules).
28
+ * Returns the discovered repositories as an array of `Repository` objects.
29
+ *
30
+ * @example
31
+ * // Find all repos up to 3 levels deep, excluding node_modules
32
+ * const repos = await getRepositories('/path/to/monorepo', { depth: 3 })
33
+ * for (const repo of repos) {
34
+ * console.log(repo.name, repo.path)
35
+ * }
36
+ */
37
+ export declare function getRepositories(rootPath: string, options?: GetRepositoriesOptions): Promise<ReadonlyArray<Repository>>;
@@ -0,0 +1,124 @@
1
+ import { opendir, stat } from 'fs/promises';
2
+ import { join, resolve } from 'path';
3
+ import { Repository } from '../models/repository.js';
4
+ import { directoryExists } from '../lib/directory-exists.js';
5
+ const defaultSkipDirs = new Set([
6
+ 'node_modules',
7
+ '.git',
8
+ '.hg',
9
+ '.svn',
10
+ '.yarn',
11
+ '.pnp',
12
+ '__pycache__',
13
+ '.cache',
14
+ '.next',
15
+ '.turbo',
16
+ 'dist',
17
+ 'build',
18
+ '.venv',
19
+ 'vendor',
20
+ '.tox',
21
+ ]);
22
+ /**
23
+ * Discover git repositories in a directory tree.
24
+ *
25
+ * Walks the directory tree under `rootPath`, looking for `.git` entries
26
+ * (directories for regular repos, or files for worktrees and submodules).
27
+ * Returns the discovered repositories as an array of `Repository` objects.
28
+ *
29
+ * @example
30
+ * // Find all repos up to 3 levels deep, excluding node_modules
31
+ * const repos = await getRepositories('/path/to/monorepo', { depth: 3 })
32
+ * for (const repo of repos) {
33
+ * console.log(repo.name, repo.path)
34
+ * }
35
+ */
36
+ export async function getRepositories(rootPath, options = {}) {
37
+ const { depth = 5, skipDirs = defaultSkipDirs, includeBare = false, } = options;
38
+ if (includeBare) {
39
+ throw new Error('Bare repository detection is not yet implemented. ' +
40
+ 'Set includeBare to false (default) or omit it.');
41
+ }
42
+ if (!(await directoryExists(rootPath))) {
43
+ return [];
44
+ }
45
+ const resolvedRoot = resolve(rootPath);
46
+ const repos = [];
47
+ const seen = new Set();
48
+ /**
49
+ * Check if a path contains a `.git` entry, indicating a git repository.
50
+ */
51
+ async function hasGitDir(dirPath) {
52
+ const gitPath = join(dirPath, '.git');
53
+ try {
54
+ const s = await stat(gitPath);
55
+ return s.isDirectory() || s.isFile();
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
61
+ /**
62
+ * Recursively walk a directory tree looking for repos.
63
+ */
64
+ async function walk(currentPath, currentDepth) {
65
+ // Check depth limit
66
+ if (depth !== -1 && currentDepth > depth) {
67
+ return;
68
+ }
69
+ // Resolve to avoid duplicate entries from symlinks
70
+ const resolved = resolve(currentPath);
71
+ // Skip if already seen (e.g., symlink loop)
72
+ if (seen.has(resolved)) {
73
+ return;
74
+ }
75
+ seen.add(resolved);
76
+ // Check if this directory is itself a repo
77
+ if (await hasGitDir(resolved)) {
78
+ repos.push(new Repository(resolved, repos.length));
79
+ // Continue recursing — the parent repo may contain nested repos
80
+ // (e.g. monorepo workspaces where the root is a repo AND packages
81
+ // have their own .git directories)
82
+ }
83
+ // Recurse into subdirectories
84
+ let dir;
85
+ try {
86
+ dir = await opendir(resolved);
87
+ }
88
+ catch {
89
+ return; // Permission denied, etc.
90
+ }
91
+ for await (const entry of dir) {
92
+ if (entry.name.startsWith('.')) {
93
+ // Skip hidden directories (except the root itself)
94
+ // But .gitignore, .github, etc. could have submodules
95
+ // Only skip .git, .hg, .svn
96
+ if (entry.name === '.git' || entry.name === '.hg' || entry.name === '.svn') {
97
+ continue;
98
+ }
99
+ }
100
+ if (skipDirs.has(entry.name)) {
101
+ continue;
102
+ }
103
+ if (entry.isDirectory()) {
104
+ await walk(join(resolved, entry.name), currentDepth + 1);
105
+ }
106
+ else if (entry.isSymbolicLink()) {
107
+ // Follow symlinks to directories
108
+ const linkPath = join(resolved, entry.name);
109
+ try {
110
+ const linkStat = await stat(linkPath);
111
+ if (linkStat.isDirectory()) {
112
+ await walk(linkPath, currentDepth + 1);
113
+ }
114
+ }
115
+ catch {
116
+ // Broken symlink, skip
117
+ }
118
+ }
119
+ }
120
+ }
121
+ await walk(resolvedRoot, 0);
122
+ return repos;
123
+ }
124
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/git/discover.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export * from './checkout.js';
6
6
  export * from './checkout-index.js';
7
7
  export * from './cherry-pick.js';
8
8
  export * from './clean.js';
9
+ export * from './discover.js';
9
10
  export * from './clone.js';
10
11
  export * from './commit.js';
11
12
  export * from './config.js';
package/dist/git/index.js CHANGED
@@ -8,6 +8,7 @@ export * from './checkout.js';
8
8
  export * from './checkout-index.js';
9
9
  export * from './cherry-pick.js';
10
10
  export * from './clean.js';
11
+ export * from './discover.js';
11
12
  export * from './clone.js';
12
13
  export * from './commit.js';
13
14
  export * from './config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/git/index.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,4BAA4B,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAEjH,uBAAuB;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/git/index.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,4BAA4B,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAEjH,uBAAuB;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA;AAChC,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA"}
@@ -1,7 +1,9 @@
1
- import { WorkingDirectoryStatus } from '../models/status.js';
1
+ import { WorkingDirectoryStatus, WorkingDirectoryFileChange } from '../models/status.js';
2
+ import { DiffSelectionType, DiffSelection } from '../models/diff/index.js';
2
3
  import { Repository } from '../models/repository.js';
3
4
  import { IAheadBehind } from '../models/branch.js';
4
5
  import { RebaseInternalState } from '../models/rebase.js';
6
+ export { DiffSelectionType, DiffSelection } from '../models/diff/index.js';
5
7
  /** The encapsulation of the result from 'git status' */
6
8
  export interface IStatusResult {
7
9
  /** The name of the current branch */
@@ -37,3 +39,83 @@ export declare function getStatus(repository: Repository): Promise<IStatusResult
37
39
  export declare function getStatus(repository: Repository, includeUntracked: boolean): Promise<IStatusResult | null>;
38
40
  export declare function getStatus(repository: Repository, includeUntracked: boolean, rejectOnError: true): Promise<IStatusResult>;
39
41
  export declare function getStatus(repository: Repository, includeUntracked: boolean, rejectOnError: false): Promise<IStatusResult | null>;
42
+ /**
43
+ * A flattened summary of a working directory change.
44
+ *
45
+ * Saves consumers from digging into the nested `WorkingDirectoryFileChange.status`
46
+ * union type to get the path, status string, and optional oldPath.
47
+ */
48
+ export interface WorkingDirectoryChangeSummary {
49
+ readonly path: string;
50
+ readonly status: 'added' | 'modified' | 'deleted' | 'renamed' | 'copied' | 'conflicted' | 'untracked';
51
+ readonly oldPath?: string;
52
+ }
53
+ /**
54
+ * Get a flattened list of working directory changes for a repository.
55
+ *
56
+ * Wraps `getStatus` and maps each `WorkingDirectoryFileChange` to a simple
57
+ * `WorkingDirectoryChangeSummary` object, eliminating the need for consumers
58
+ * to dig into the `AppFileStatus` union type.
59
+ *
60
+ * Throws if the repository path is not a valid git repository.
61
+ */
62
+ export declare function getWorkingDirectoryChanges(repository: Repository): Promise<ReadonlyArray<WorkingDirectoryChangeSummary>>;
63
+ /**
64
+ * A flattened summary of a working directory change that also includes
65
+ * the `DiffSelection` for each file, enabling consumers to programmatically
66
+ * stage/unstage individual files or partial hunks.
67
+ *
68
+ * Use `fileChangeSummaryToWorkingDirectoryFile()` to convert back to
69
+ * `WorkingDirectoryFileChange[]` for use with `stageFiles()`.
70
+ */
71
+ export interface WorkingDirectoryFileChangeSummary {
72
+ readonly path: string;
73
+ readonly status: 'added' | 'modified' | 'deleted' | 'renamed' | 'copied' | 'conflicted' | 'untracked';
74
+ readonly oldPath?: string;
75
+ /**
76
+ * Whether this file is selected for commit.
77
+ * - `All`: fully staged for commit
78
+ * - `None`: excluded from commit
79
+ * - `Partial`: only selected hunks/lines are staged
80
+ */
81
+ readonly selectionType: DiffSelectionType;
82
+ /**
83
+ * The full `DiffSelection` object. Use the `withLineSelection()` or
84
+ * `withSelectAll()` / `withSelectNone()` methods to modify the selection,
85
+ * then pass through `fileChangeSummaryToWorkingDirectoryFile()` to
86
+ * create `WorkingDirectoryFileChange` instances for `stageFiles()`.
87
+ */
88
+ readonly selection: DiffSelection;
89
+ }
90
+ /**
91
+ * Get a detailed list of working directory changes, including the
92
+ * `DiffSelection` for each file.
93
+ *
94
+ * Unlike `getWorkingDirectoryChanges()`, this variant includes the selection
95
+ * state so consumers can programmatically stage/unstage individual files
96
+ * or partial hunks.
97
+ *
98
+ * Round-trip with `fileChangeSummaryToWorkingDirectoryFile()` to convert
99
+ * back to `WorkingDirectoryFileChange[]` for use with `stageFiles()`.
100
+ *
101
+ * @see getWorkingDirectoryChanges for a lighter variant without selection info
102
+ * @see fileChangeSummaryToWorkingDirectoryFile to convert back to WorkingDirectoryFileChange
103
+ */
104
+ export declare function getWorkingDirectoryChangesDetailed(repository: Repository): Promise<ReadonlyArray<WorkingDirectoryFileChangeSummary>>;
105
+ /**
106
+ * Convert a `WorkingDirectoryFileChangeSummary` back to a
107
+ * `WorkingDirectoryFileChange` for use with `stageFiles()`.
108
+ *
109
+ * This is a lossy conversion — the reconstructed `AppFileStatus` contains
110
+ * only the information available in the summary (path, status kind, oldPath).
111
+ * Submodule status and conflict marker counts are not preserved.
112
+ *
113
+ * @example
114
+ * const changes = await getWorkingDirectoryChangesDetailed(repo)
115
+ * // Exclude deleted files from the commit
116
+ * const toStage = changes
117
+ * .filter(c => c.status !== 'deleted')
118
+ * .map(fileChangeSummaryToWorkingDirectoryFile)
119
+ * await stageFiles(repo, toStage)
120
+ */
121
+ export declare function fileChangeSummaryToWorkingDirectoryFile(summary: WorkingDirectoryFileChangeSummary): WorkingDirectoryFileChange;
@@ -8,6 +8,9 @@ import { getBinaryPaths } from './diff.js';
8
8
  import { getRebaseInternalState } from './rebase.js';
9
9
  import { isCherryPickHeadFound } from './cherry-pick.js';
10
10
  import { git } from './index.js';
11
+ // Re-export DiffSelectionType and DiffSelection so consumers can import from the barrel
12
+ // without importing directly from models/diff
13
+ export { DiffSelectionType, DiffSelection } from '../models/diff/index.js';
11
14
  function parseConflictedState(entry, path, conflictDetails) {
12
15
  switch (entry.action) {
13
16
  case UnmergedEntrySummary.BothAdded: {
@@ -221,6 +224,140 @@ function parseStatusHeader(results, header) {
221
224
  match,
222
225
  };
223
226
  }
227
+ /**
228
+ * Get a flattened list of working directory changes for a repository.
229
+ *
230
+ * Wraps `getStatus` and maps each `WorkingDirectoryFileChange` to a simple
231
+ * `WorkingDirectoryChangeSummary` object, eliminating the need for consumers
232
+ * to dig into the `AppFileStatus` union type.
233
+ *
234
+ * Throws if the repository path is not a valid git repository.
235
+ */
236
+ export async function getWorkingDirectoryChanges(repository) {
237
+ const status = await getStatus(repository, true, true);
238
+ return status.workingDirectory.files.map(file => {
239
+ const summary = {
240
+ path: file.path,
241
+ status: statusKindToString(file.status.kind),
242
+ };
243
+ if ((file.status.kind === AppFileStatusKind.Renamed ||
244
+ file.status.kind === AppFileStatusKind.Copied) &&
245
+ 'oldPath' in file.status &&
246
+ file.status.oldPath !== undefined) {
247
+ return { ...summary, oldPath: file.status.oldPath };
248
+ }
249
+ return summary;
250
+ });
251
+ }
252
+ function statusKindToString(kind) {
253
+ switch (kind) {
254
+ case AppFileStatusKind.New:
255
+ return 'added';
256
+ case AppFileStatusKind.Modified:
257
+ return 'modified';
258
+ case AppFileStatusKind.Deleted:
259
+ return 'deleted';
260
+ case AppFileStatusKind.Renamed:
261
+ return 'renamed';
262
+ case AppFileStatusKind.Copied:
263
+ return 'copied';
264
+ case AppFileStatusKind.Conflicted:
265
+ return 'conflicted';
266
+ case AppFileStatusKind.Untracked:
267
+ return 'untracked';
268
+ }
269
+ }
270
+ /**
271
+ * Get a detailed list of working directory changes, including the
272
+ * `DiffSelection` for each file.
273
+ *
274
+ * Unlike `getWorkingDirectoryChanges()`, this variant includes the selection
275
+ * state so consumers can programmatically stage/unstage individual files
276
+ * or partial hunks.
277
+ *
278
+ * Round-trip with `fileChangeSummaryToWorkingDirectoryFile()` to convert
279
+ * back to `WorkingDirectoryFileChange[]` for use with `stageFiles()`.
280
+ *
281
+ * @see getWorkingDirectoryChanges for a lighter variant without selection info
282
+ * @see fileChangeSummaryToWorkingDirectoryFile to convert back to WorkingDirectoryFileChange
283
+ */
284
+ export async function getWorkingDirectoryChangesDetailed(repository) {
285
+ const status = await getStatus(repository, true, true);
286
+ return status.workingDirectory.files.map(file => {
287
+ const summary = {
288
+ path: file.path,
289
+ status: statusKindToString(file.status.kind),
290
+ selectionType: file.selection.getSelectionType(),
291
+ selection: file.selection,
292
+ };
293
+ if ((file.status.kind === AppFileStatusKind.Renamed ||
294
+ file.status.kind === AppFileStatusKind.Copied) &&
295
+ 'oldPath' in file.status &&
296
+ file.status.oldPath !== undefined) {
297
+ return { ...summary, oldPath: file.status.oldPath };
298
+ }
299
+ return summary;
300
+ });
301
+ }
302
+ /**
303
+ * Convert a `WorkingDirectoryFileChangeSummary` back to a
304
+ * `WorkingDirectoryFileChange` for use with `stageFiles()`.
305
+ *
306
+ * This is a lossy conversion — the reconstructed `AppFileStatus` contains
307
+ * only the information available in the summary (path, status kind, oldPath).
308
+ * Submodule status and conflict marker counts are not preserved.
309
+ *
310
+ * @example
311
+ * const changes = await getWorkingDirectoryChangesDetailed(repo)
312
+ * // Exclude deleted files from the commit
313
+ * const toStage = changes
314
+ * .filter(c => c.status !== 'deleted')
315
+ * .map(fileChangeSummaryToWorkingDirectoryFile)
316
+ * await stageFiles(repo, toStage)
317
+ */
318
+ export function fileChangeSummaryToWorkingDirectoryFile(summary) {
319
+ let appStatus;
320
+ switch (summary.status) {
321
+ case 'added':
322
+ appStatus = { kind: AppFileStatusKind.New };
323
+ break;
324
+ case 'modified':
325
+ appStatus = { kind: AppFileStatusKind.Modified };
326
+ break;
327
+ case 'deleted':
328
+ appStatus = { kind: AppFileStatusKind.Deleted };
329
+ break;
330
+ case 'renamed':
331
+ appStatus = {
332
+ kind: AppFileStatusKind.Renamed,
333
+ oldPath: summary.oldPath ?? summary.path,
334
+ renameIncludesModifications: false,
335
+ };
336
+ break;
337
+ case 'copied':
338
+ appStatus = {
339
+ kind: AppFileStatusKind.Copied,
340
+ oldPath: summary.oldPath ?? summary.path,
341
+ renameIncludesModifications: false,
342
+ };
343
+ break;
344
+ case 'conflicted':
345
+ appStatus = {
346
+ kind: AppFileStatusKind.Conflicted,
347
+ entry: {
348
+ kind: 'conflicted',
349
+ action: UnmergedEntrySummary.BothModified,
350
+ us: GitStatusEntry.UpdatedButUnmerged,
351
+ them: GitStatusEntry.UpdatedButUnmerged,
352
+ },
353
+ };
354
+ break;
355
+ case 'untracked':
356
+ appStatus = { kind: AppFileStatusKind.Untracked };
357
+ break;
358
+ }
359
+ return new WorkingDirectoryFileChange(summary.path, appStatus, summary.selection);
360
+ }
224
361
  async function getMergeConflictDetails(repository, conflictedFilesInIndex) {
225
362
  const conflictCountsByPath = await getFilesWithConflictMarkers(repository.path);
226
363
  const binaryFilePaths = await getBinaryPaths(repository, 'MERGE_HEAD', conflictedFilesInIndex);
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/git/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/git/status.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-chopstick-core",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -4,7 +4,7 @@ import { execSync } from 'child_process'
4
4
  import { tmpdir } from 'os'
5
5
  import { join } from 'path'
6
6
  import {
7
- Repository, getStatus, getCommits, getBranches,
7
+ Repository, getRepositories, getStatus, getWorkingDirectoryChanges, getWorkingDirectoryChangesDetailed, fileChangeSummaryToWorkingDirectoryFile, DiffSelectionType, getCommits, getBranches,
8
8
  createCommit, createBranch, deleteLocalBranch, renameBranch,
9
9
  getCurrentBranch, getRepositoryType, getRepositorySummary,
10
10
  getRemoteUrl, getRemotesFromPath, getAllTags,
@@ -89,6 +89,116 @@ describe('getStatus', () => {
89
89
  })
90
90
  })
91
91
 
92
+ describe('getWorkingDirectoryChanges', () => {
93
+ it('returns flattened changes for a repo with modified files', async () => {
94
+ // Modify an existing file and create a new (untracked) one
95
+ writeFileSync(join(repoPath, 'README.md'), 'modified content')
96
+ writeFileSync(join(repoPath, 'new-file.txt'), 'new content')
97
+
98
+ const changes = await getWorkingDirectoryChanges(repo)
99
+
100
+ expect(changes.length).toBeGreaterThanOrEqual(2)
101
+
102
+ const modified = changes.find(c => c.path === 'README.md')
103
+ expect(modified).toBeTruthy()
104
+ expect(modified!.status).toBe('modified')
105
+ expect(modified!.oldPath).toBeUndefined()
106
+
107
+ const untracked = changes.find(c => c.path === 'new-file.txt')
108
+ expect(untracked).toBeTruthy()
109
+ // Unstaged new files show as 'untracked' (not 'added' — that requires staging)
110
+ expect(untracked!.status).toBe('untracked')
111
+
112
+ // Clean up
113
+ git(repoPath, 'checkout -- README.md')
114
+ execSync(`rm -f ${join(repoPath, 'new-file.txt')}`)
115
+ })
116
+
117
+ it('throws for a non-repo path', async () => {
118
+ const nonRepoPath = mkdtempSync(join(tmpdir(), 'gcctest-nonrepo-'))
119
+ await expect(
120
+ getWorkingDirectoryChanges(new Repository(nonRepoPath))
121
+ ).rejects.toThrow()
122
+ execSync(`rm -rf ${nonRepoPath}`)
123
+ })
124
+
125
+ it('includes oldPath for renamed files', async () => {
126
+ // Use an existing tracked file to avoid creating a commit
127
+ git(repoPath, 'mv README.md readme-backup.md')
128
+
129
+ const changes = await getWorkingDirectoryChanges(repo)
130
+ const renamed = changes.find(c => c.path === 'readme-backup.md')
131
+ expect(renamed).toBeTruthy()
132
+ expect(renamed!.status).toBe('renamed')
133
+ expect(renamed!.oldPath).toBe('README.md')
134
+
135
+ // Clean up: reverse the rename
136
+ git(repoPath, 'mv readme-backup.md README.md')
137
+ })
138
+ })
139
+
140
+ describe('getWorkingDirectoryChangesDetailed', () => {
141
+ it('includes selectionType and selection for each file', async () => {
142
+ // Modify an existing file
143
+ writeFileSync(join(repoPath, 'README.md'), 'detailed test')
144
+
145
+ const changes = await getWorkingDirectoryChangesDetailed(repo)
146
+
147
+ expect(changes.length).toBeGreaterThanOrEqual(1)
148
+
149
+ const modified = changes.find(c => c.path === 'README.md')
150
+ expect(modified).toBeTruthy()
151
+ expect(modified!.status).toBe('modified')
152
+ expect(modified!.selectionType).toBe(DiffSelectionType.All)
153
+ expect(modified!.selection).toBeTruthy()
154
+ // DiffSelection should report the file as fully selected
155
+ expect(modified!.selection.isSelected(0)).toBe(true)
156
+
157
+ // Clean up
158
+ git(repoPath, 'checkout -- README.md')
159
+ })
160
+
161
+ it('round-trips through fileChangeSummaryToWorkingDirectoryFile', async () => {
162
+ // Create a file and stage it so it appears as 'added'
163
+ writeFileSync(join(repoPath, 'stage-test.txt'), 'stage me')
164
+ git(repoPath, 'add stage-test.txt')
165
+
166
+ const changes = await getWorkingDirectoryChangesDetailed(repo)
167
+ const added = changes.find(c => c.path === 'stage-test.txt')
168
+ expect(added).toBeTruthy()
169
+ expect(added!.status).toBe('added')
170
+
171
+ // Round-trip back to WorkingDirectoryFileChange
172
+ const wdfc = fileChangeSummaryToWorkingDirectoryFile(added!)
173
+ expect(wdfc.path).toBe('stage-test.txt')
174
+ expect(wdfc.selection.getSelectionType()).toBe(DiffSelectionType.All)
175
+ // Verify the status was properly reconstructed
176
+ expect(wdfc.status.kind).toBe(AppFileStatusKind.New)
177
+
178
+ // Clean up: unstage and remove
179
+ git(repoPath, 'reset HEAD -- stage-test.txt')
180
+ execSync(`rm -f ${join(repoPath, 'stage-test.txt')}`)
181
+ })
182
+
183
+ it('preserves oldPath through round-trip for renamed files', async () => {
184
+ git(repoPath, 'mv README.md readme-backup.md')
185
+
186
+ const changes = await getWorkingDirectoryChangesDetailed(repo)
187
+ const renamed = changes.find(c => c.path === 'readme-backup.md')
188
+ expect(renamed).toBeTruthy()
189
+ expect(renamed!.oldPath).toBe('README.md')
190
+
191
+ // Round-trip
192
+ const wdfc = fileChangeSummaryToWorkingDirectoryFile(renamed!)
193
+ expect(wdfc.path).toBe('readme-backup.md')
194
+ expect(wdfc.status.kind).toBe(AppFileStatusKind.Renamed)
195
+ expect((wdfc.status as any).oldPath).toBe('README.md')
196
+
197
+ // Clean up: reverse the rename
198
+ git(repoPath, 'mv readme-backup.md README.md')
199
+ })
200
+ })
201
+
92
202
  describe('getCommits', () => {
93
203
  it('returns commits in order (fixture has 6 commits reachable from main)', async () => {
94
204
  const commits = await getCommits(repo, 'HEAD', 10)
@@ -419,6 +529,89 @@ describe('getRemotesFromPath', () => {
419
529
  })
420
530
  })
421
531
 
532
+ describe('getRepositories', () => {
533
+ it('discovers the root repo when scanning from repo path', async () => {
534
+ // Scan the fixture repo — should find it at the root
535
+ const repos = await getRepositories(repoPath)
536
+ expect(repos.length).toBeGreaterThanOrEqual(1)
537
+
538
+ const root = repos.find(r => r.path === repoPath)
539
+ expect(root).toBeTruthy()
540
+ // The fixture is created in a temp dir, so name will be the temp dir name
541
+ expect(root!.path).toBe(repoPath)
542
+ })
543
+
544
+ it('finds nested repos in a monorepo-style layout', async () => {
545
+ const monorepoRoot = mkdtempSync(join(tmpdir(), 'gcctest-monorepo-'))
546
+ execSync(`git init ${monorepoRoot}`, { stdio: 'pipe' })
547
+ execSync(`git -C ${monorepoRoot} commit --allow-empty -m 'init'`, { stdio: 'pipe' })
548
+
549
+ const pkgA = join(monorepoRoot, 'packages', 'pkg-a')
550
+ const pkgB = join(monorepoRoot, 'packages', 'pkg-b')
551
+ execSync(`mkdir -p ${pkgA} ${pkgB}`)
552
+ execSync(`git init ${pkgA}`, { stdio: 'pipe' })
553
+ execSync(`git -C ${pkgA} commit --allow-empty -m 'init pkg-a'`, { stdio: 'pipe' })
554
+ execSync(`git init ${pkgB}`, { stdio: 'pipe' })
555
+ execSync(`git -C ${pkgB} commit --allow-empty -m 'init pkg-b'`, { stdio: 'pipe' })
556
+
557
+ const repos = await getRepositories(monorepoRoot)
558
+ expect(repos.length).toBe(3)
559
+
560
+ const paths = repos.map(r => r.path).sort()
561
+ expect(paths).toContain(monorepoRoot)
562
+ expect(paths).toContain(pkgA)
563
+ expect(paths).toContain(pkgB)
564
+
565
+ execSync(`rm -rf ${monorepoRoot}`)
566
+ })
567
+
568
+ it('skips node_modules directories', async () => {
569
+ const root = mkdtempSync(join(tmpdir(), 'gcctest-skips-'))
570
+ execSync(`git init ${root}`, { stdio: 'pipe' })
571
+ execSync(`git -C ${root} commit --allow-empty -m 'init'`, { stdio: 'pipe' })
572
+
573
+ const nm = join(root, 'node_modules', 'some-lib')
574
+ execSync(`mkdir -p ${nm}`)
575
+ execSync(`git init ${nm}`, { stdio: 'pipe' })
576
+ execSync(`git -C ${nm} commit --allow-empty -m 'dep'`, { stdio: 'pipe' })
577
+
578
+ const repos = await getRepositories(root)
579
+ expect(repos.length).toBe(1)
580
+ expect(repos[0].path).toBe(root)
581
+
582
+ execSync(`rm -rf ${root}`)
583
+ })
584
+
585
+ it('obeys the depth limit', async () => {
586
+ const root = mkdtempSync(join(tmpdir(), 'gcctest-depth-'))
587
+ execSync(`git init ${root}`, { stdio: 'pipe' })
588
+ execSync(`git -C ${root} commit --allow-empty -m 'init'`, { stdio: 'pipe' })
589
+
590
+ const deep = join(root, 'a', 'b', 'c')
591
+ execSync(`mkdir -p ${deep}`)
592
+ execSync(`git init ${deep}`, { stdio: 'pipe' })
593
+ execSync(`git -C ${deep} commit --allow-empty -m 'deep'`, { stdio: 'pipe' })
594
+
595
+ // With depth 2, should not find the deep repo
596
+ const repos = await getRepositories(root, { depth: 2 })
597
+ expect(repos.length).toBe(1)
598
+ expect(repos[0].path).toBe(root)
599
+
600
+ // With depth -1 (unlimited), should find the deep repo
601
+ const reposDeep = await getRepositories(root, { depth: -1 })
602
+ expect(reposDeep.length).toBe(2)
603
+
604
+ execSync(`rm -rf ${root}`)
605
+ })
606
+
607
+ it('returns empty array for a non-repo path', async () => {
608
+ const nonRepoPath = mkdtempSync(join(tmpdir(), 'gcctest-nonrepo-'))
609
+ const repos = await getRepositories(nonRepoPath)
610
+ expect(repos).toEqual([])
611
+ execSync(`rm -rf ${nonRepoPath}`)
612
+ })
613
+ })
614
+
422
615
  describe('addRemote', () => {
423
616
  it('adds a new remote and returns it', async () => {
424
617
  const remote = await addRemote(repo, 'upstream', 'https://github.com/upstream/repo.git')