@vibe-validate/git 0.9.0 → 0.9.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-validate/git",
3
- "version": "0.9.0",
3
+ "version": "0.9.3",
4
4
  "description": "Git utilities for vibe-validate - tree hash calculation, branch sync, and post-merge cleanup",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,68 +0,0 @@
1
- /**
2
- * Smart Branch Sync Checker
3
- *
4
- * Safely checks if the current branch is behind a remote branch without auto-merging.
5
- * Provides clear status reporting and next-step instructions.
6
- *
7
- * Key safety features:
8
- * - Never auto-merges (preserves conflict visibility)
9
- * - Clear exit codes for CI/agent integration
10
- * - Explicit instructions when manual intervention needed
11
- * - Cross-platform compatibility
12
- */
13
- declare const GIT_OPTIONS: {
14
- timeout: number;
15
- encoding: "utf8";
16
- maxBuffer: number;
17
- };
18
- export interface SyncCheckResult {
19
- isUpToDate: boolean;
20
- behindBy: number;
21
- currentBranch: string;
22
- hasRemote: boolean;
23
- error?: string;
24
- }
25
- export type ExecAsyncFunction = (command: string, options: typeof GIT_OPTIONS) => Promise<{
26
- stdout: string;
27
- stderr: string;
28
- }>;
29
- export interface SyncCheckOptions {
30
- remoteBranch?: string;
31
- execAsync?: ExecAsyncFunction;
32
- }
33
- /**
34
- * Branch Sync Checker
35
- *
36
- * Checks if current branch is behind a remote branch
37
- */
38
- export declare class BranchSyncChecker {
39
- private readonly remoteBranch;
40
- private readonly execAsync;
41
- constructor(options?: SyncCheckOptions);
42
- /**
43
- * Check if the current branch is synchronized with remote branch
44
- *
45
- * @returns Promise resolving to sync status information
46
- */
47
- checkSync(): Promise<SyncCheckResult>;
48
- private getCurrentBranch;
49
- private hasRemoteBranch;
50
- private fetchRemote;
51
- private getCommitsBehind;
52
- /**
53
- * Get appropriate exit code based on sync result
54
- *
55
- * @param result - The sync check result
56
- * @returns Exit code (0=success, 1=needs merge, 2=error)
57
- */
58
- getExitCode(result: SyncCheckResult): number;
59
- }
60
- /**
61
- * Convenience function for quick sync checking
62
- *
63
- * @param options - Sync check options
64
- * @returns Sync check result
65
- */
66
- export declare function checkBranchSync(options?: SyncCheckOptions): Promise<SyncCheckResult>;
67
- export {};
68
- //# sourceMappingURL=branch-sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"branch-sync.d.ts","sourceRoot":"","sources":["../src/branch-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,QAAA,MAAM,WAAW;;;;CAIhB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,WAAW,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE9H,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;gBAElC,OAAO,GAAE,gBAAqB;IAK1C;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;YA0C7B,gBAAgB;YAUhB,eAAe;YASf,WAAW;YAUX,gBAAgB;IAW9B;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM;CAK7C;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAG9F"}
@@ -1,139 +0,0 @@
1
- /**
2
- * Smart Branch Sync Checker
3
- *
4
- * Safely checks if the current branch is behind a remote branch without auto-merging.
5
- * Provides clear status reporting and next-step instructions.
6
- *
7
- * Key safety features:
8
- * - Never auto-merges (preserves conflict visibility)
9
- * - Clear exit codes for CI/agent integration
10
- * - Explicit instructions when manual intervention needed
11
- * - Cross-platform compatibility
12
- */
13
- import { exec } from 'child_process';
14
- import { promisify } from 'util';
15
- const GIT_TIMEOUT = 10000; // 10 seconds timeout for git operations
16
- const GIT_OPTIONS = {
17
- timeout: GIT_TIMEOUT,
18
- encoding: 'utf8',
19
- maxBuffer: 1024 * 1024 // 1MB buffer
20
- };
21
- /**
22
- * Branch Sync Checker
23
- *
24
- * Checks if current branch is behind a remote branch
25
- */
26
- export class BranchSyncChecker {
27
- remoteBranch;
28
- execAsync;
29
- constructor(options = {}) {
30
- this.remoteBranch = options.remoteBranch || 'origin/main';
31
- this.execAsync = options.execAsync || promisify(exec);
32
- }
33
- /**
34
- * Check if the current branch is synchronized with remote branch
35
- *
36
- * @returns Promise resolving to sync status information
37
- */
38
- async checkSync() {
39
- try {
40
- // Get current branch name
41
- const currentBranch = await this.getCurrentBranch();
42
- // Check if remote branch exists
43
- const hasRemote = await this.hasRemoteBranch();
44
- if (!hasRemote) {
45
- return {
46
- isUpToDate: true,
47
- behindBy: 0,
48
- currentBranch,
49
- hasRemote: false,
50
- error: `No remote branch ${this.remoteBranch} found`
51
- };
52
- }
53
- // Fetch latest from remote
54
- await this.fetchRemote();
55
- // Check how many commits behind
56
- const behindBy = await this.getCommitsBehind();
57
- return {
58
- isUpToDate: behindBy === 0,
59
- behindBy,
60
- currentBranch,
61
- hasRemote: true
62
- };
63
- }
64
- catch (error) {
65
- const errorMessage = error instanceof Error ? error.message : String(error);
66
- return {
67
- isUpToDate: false,
68
- behindBy: -1,
69
- currentBranch: 'unknown',
70
- hasRemote: false,
71
- error: errorMessage
72
- };
73
- }
74
- }
75
- async getCurrentBranch() {
76
- try {
77
- const { stdout } = await this.execAsync('git rev-parse --abbrev-ref HEAD', GIT_OPTIONS);
78
- return stdout.trim();
79
- }
80
- catch (error) {
81
- const errorMessage = error instanceof Error ? error.message : String(error);
82
- throw new Error(`Not in a git repository or unable to determine current branch: ${errorMessage}`);
83
- }
84
- }
85
- async hasRemoteBranch() {
86
- try {
87
- await this.execAsync(`git rev-parse --verify ${this.remoteBranch}`, GIT_OPTIONS);
88
- return true;
89
- }
90
- catch (error) {
91
- return false;
92
- }
93
- }
94
- async fetchRemote() {
95
- try {
96
- const [remote, branch] = this.remoteBranch.split('/');
97
- await this.execAsync(`git fetch --quiet ${remote} ${branch}`, GIT_OPTIONS);
98
- }
99
- catch (error) {
100
- const errorMessage = error instanceof Error ? error.message : String(error);
101
- throw new Error(`Failed to fetch from ${this.remoteBranch}: ${errorMessage}`);
102
- }
103
- }
104
- async getCommitsBehind() {
105
- try {
106
- const { stdout } = await this.execAsync(`git rev-list --count HEAD..${this.remoteBranch}`, GIT_OPTIONS);
107
- const count = parseInt(stdout.trim(), 10);
108
- return isNaN(count) ? 0 : count;
109
- }
110
- catch (error) {
111
- const errorMessage = error instanceof Error ? error.message : String(error);
112
- throw new Error(`Failed to check commits behind: ${errorMessage}`);
113
- }
114
- }
115
- /**
116
- * Get appropriate exit code based on sync result
117
- *
118
- * @param result - The sync check result
119
- * @returns Exit code (0=success, 1=needs merge, 2=error)
120
- */
121
- getExitCode(result) {
122
- if (result.error)
123
- return 2; // Error condition
124
- if (!result.hasRemote)
125
- return 0; // No remote, consider OK
126
- return result.isUpToDate ? 0 : 1; // 0 = up to date, 1 = needs merge
127
- }
128
- }
129
- /**
130
- * Convenience function for quick sync checking
131
- *
132
- * @param options - Sync check options
133
- * @returns Sync check result
134
- */
135
- export async function checkBranchSync(options = {}) {
136
- const checker = new BranchSyncChecker(options);
137
- return checker.checkSync();
138
- }
139
- //# sourceMappingURL=branch-sync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"branch-sync.js","sourceRoot":"","sources":["../src/branch-sync.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * @vibe-validate/git
3
- *
4
- * Git utilities for vibe-validate - deterministic tree hash calculation,
5
- * branch synchronization, and post-merge cleanup.
6
- *
7
- * @packageDocumentation
8
- */
9
- export { getGitTreeHash, getHeadTreeHash, hasWorkingTreeChanges } from './tree-hash.js';
10
- export { BranchSyncChecker, checkBranchSync, type SyncCheckResult, type SyncCheckOptions } from './branch-sync.js';
11
- export { PostPRMergeCleanup, cleanupMergedBranches, type CleanupResult, type CleanupOptions } from './post-merge-cleanup.js';
12
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,eAAe,EACf,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC"}
package/dist/index.js DELETED
@@ -1,15 +0,0 @@
1
- /**
2
- * @vibe-validate/git
3
- *
4
- * Git utilities for vibe-validate - deterministic tree hash calculation,
5
- * branch synchronization, and post-merge cleanup.
6
- *
7
- * @packageDocumentation
8
- */
9
- // Tree hash calculation (deterministic, content-based)
10
- export { getGitTreeHash, getHeadTreeHash, hasWorkingTreeChanges } from './tree-hash.js';
11
- // Branch sync checking (safe, no auto-merge)
12
- export { BranchSyncChecker, checkBranchSync } from './branch-sync.js';
13
- // Post-merge cleanup (delete merged branches)
14
- export { PostPRMergeCleanup, cleanupMergedBranches } from './post-merge-cleanup.js';
15
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,uDAAuD;AACvD,OAAO,EACL,cAAc,EACd,eAAe,EACf,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAExB,6CAA6C;AAC7C,OAAO,EACL,iBAAiB,EACjB,eAAe,EAGhB,MAAM,kBAAkB,CAAC;AAE1B,8CAA8C;AAC9C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EAGtB,MAAM,yBAAyB,CAAC"}
@@ -1,77 +0,0 @@
1
- /**
2
- * Post-PR Merge Cleanup Tool
3
- *
4
- * Comprehensive post-PR cleanup workflow that:
5
- * 1. Switches to main branch
6
- * 2. Syncs main branch with remote origin
7
- * 3. Deletes local branches that have been merged
8
- * 4. Provides clean workspace for next PR
9
- *
10
- * Safe operations:
11
- * - Only deletes branches that are confirmed merged
12
- * - Never deletes the current main branch or unmerged branches
13
- * - Provides clear feedback on all actions taken
14
- */
15
- export interface CleanupResult {
16
- success: boolean;
17
- error?: string;
18
- branchesDeleted: string[];
19
- currentBranch: string;
20
- mainSynced: boolean;
21
- }
22
- export interface CleanupOptions {
23
- mainBranch?: string;
24
- remoteName?: string;
25
- dryRun?: boolean;
26
- }
27
- /**
28
- * Post-PR Merge Cleanup
29
- *
30
- * Cleans up merged branches and syncs main branch after PR merge
31
- */
32
- export declare class PostPRMergeCleanup {
33
- private readonly mainBranch;
34
- private readonly remoteName;
35
- private readonly dryRun;
36
- constructor(options?: CleanupOptions);
37
- /**
38
- * Run comprehensive post-PR merge cleanup workflow
39
- */
40
- runCleanup(): Promise<CleanupResult>;
41
- /**
42
- * Get the current git branch name
43
- */
44
- private getCurrentBranch;
45
- /**
46
- * Switch to main branch
47
- */
48
- private switchToMain;
49
- /**
50
- * Sync main branch with remote origin
51
- */
52
- private syncMainBranch;
53
- /**
54
- * Fetch remote branch information
55
- */
56
- private fetchRemoteInfo;
57
- /**
58
- * Find and delete branches that have been merged
59
- */
60
- private deleteMergedBranches;
61
- /**
62
- * Check if a branch has been merged into main
63
- */
64
- private isBranchMerged;
65
- /**
66
- * Clean up remote tracking references
67
- */
68
- private pruneRemoteReferences;
69
- }
70
- /**
71
- * Convenience function for quick cleanup
72
- *
73
- * @param options - Cleanup options
74
- * @returns Cleanup result
75
- */
76
- export declare function cleanupMergedBranches(options?: CleanupOptions): Promise<CleanupResult>;
77
- //# sourceMappingURL=post-merge-cleanup.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"post-merge-cleanup.d.ts","sourceRoot":"","sources":["../src/post-merge-cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;gBAErB,OAAO,GAAE,cAAmB;IAMxC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;IAqC1C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAYpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAkD5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAW9B;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAGhG"}
@@ -1,221 +0,0 @@
1
- /**
2
- * Post-PR Merge Cleanup Tool
3
- *
4
- * Comprehensive post-PR cleanup workflow that:
5
- * 1. Switches to main branch
6
- * 2. Syncs main branch with remote origin
7
- * 3. Deletes local branches that have been merged
8
- * 4. Provides clean workspace for next PR
9
- *
10
- * Safe operations:
11
- * - Only deletes branches that are confirmed merged
12
- * - Never deletes the current main branch or unmerged branches
13
- * - Provides clear feedback on all actions taken
14
- */
15
- import { execSync } from 'child_process';
16
- const TIMEOUT = 30000; // 30 seconds timeout for git operations
17
- /**
18
- * Post-PR Merge Cleanup
19
- *
20
- * Cleans up merged branches and syncs main branch after PR merge
21
- */
22
- export class PostPRMergeCleanup {
23
- mainBranch;
24
- remoteName;
25
- dryRun;
26
- constructor(options = {}) {
27
- this.mainBranch = options.mainBranch || 'main';
28
- this.remoteName = options.remoteName || 'origin';
29
- this.dryRun = options.dryRun || false;
30
- }
31
- /**
32
- * Run comprehensive post-PR merge cleanup workflow
33
- */
34
- async runCleanup() {
35
- const result = {
36
- success: false,
37
- branchesDeleted: [],
38
- currentBranch: '',
39
- mainSynced: false
40
- };
41
- try {
42
- // Step 1: Get current branch
43
- result.currentBranch = this.getCurrentBranch();
44
- // Step 2: Switch to main branch
45
- this.switchToMain();
46
- // Step 3: Sync main branch with remote
47
- this.syncMainBranch();
48
- result.mainSynced = true;
49
- // Step 4: Fetch remote branch information
50
- this.fetchRemoteInfo();
51
- // Step 5: Find and delete merged branches
52
- result.branchesDeleted = this.deleteMergedBranches();
53
- // Step 6: Clean up remote tracking branches
54
- this.pruneRemoteReferences();
55
- result.success = true;
56
- return result;
57
- }
58
- catch (error) {
59
- result.error = error instanceof Error ? error.message : String(error);
60
- return result;
61
- }
62
- }
63
- /**
64
- * Get the current git branch name
65
- */
66
- getCurrentBranch() {
67
- try {
68
- return execSync('git branch --show-current', {
69
- encoding: 'utf8',
70
- timeout: TIMEOUT
71
- }).trim();
72
- }
73
- catch (error) {
74
- throw new Error(`Failed to get current branch: ${error}`);
75
- }
76
- }
77
- /**
78
- * Switch to main branch
79
- */
80
- switchToMain() {
81
- try {
82
- execSync(`git checkout ${this.mainBranch}`, {
83
- encoding: 'utf8',
84
- timeout: TIMEOUT,
85
- stdio: ['pipe', 'pipe', 'pipe']
86
- });
87
- }
88
- catch (error) {
89
- throw new Error(`Failed to switch to ${this.mainBranch} branch: ${error}`);
90
- }
91
- }
92
- /**
93
- * Sync main branch with remote origin
94
- */
95
- syncMainBranch() {
96
- try {
97
- // Fetch latest changes from remote
98
- execSync(`git fetch ${this.remoteName} ${this.mainBranch}`, {
99
- encoding: 'utf8',
100
- timeout: TIMEOUT,
101
- stdio: ['pipe', 'pipe', 'pipe']
102
- });
103
- // Fast-forward merge remote/main
104
- execSync(`git merge ${this.remoteName}/${this.mainBranch} --ff-only`, {
105
- encoding: 'utf8',
106
- timeout: TIMEOUT,
107
- stdio: ['pipe', 'pipe', 'pipe']
108
- });
109
- }
110
- catch (error) {
111
- throw new Error(`Failed to sync ${this.mainBranch} branch: ${error}`);
112
- }
113
- }
114
- /**
115
- * Fetch remote branch information
116
- */
117
- fetchRemoteInfo() {
118
- try {
119
- execSync(`git fetch ${this.remoteName} --prune`, {
120
- encoding: 'utf8',
121
- timeout: TIMEOUT,
122
- stdio: ['pipe', 'pipe', 'pipe']
123
- });
124
- }
125
- catch (error) {
126
- throw new Error(`Failed to fetch remote info: ${error}`);
127
- }
128
- }
129
- /**
130
- * Find and delete branches that have been merged
131
- */
132
- deleteMergedBranches() {
133
- try {
134
- // Get list of local branches (excluding main)
135
- const allBranches = execSync('git branch --format="%(refname:short)"', {
136
- encoding: 'utf8',
137
- timeout: TIMEOUT
138
- })
139
- .trim()
140
- .split('\n')
141
- .filter(branch => branch && branch !== this.mainBranch && !branch.startsWith('*'));
142
- const deletedBranches = [];
143
- for (const branch of allBranches) {
144
- if (this.isBranchMerged(branch)) {
145
- if (this.dryRun) {
146
- deletedBranches.push(branch);
147
- continue;
148
- }
149
- try {
150
- execSync(`git branch -d "${branch}"`, {
151
- encoding: 'utf8',
152
- timeout: TIMEOUT,
153
- stdio: ['pipe', 'pipe', 'pipe']
154
- });
155
- deletedBranches.push(branch);
156
- }
157
- catch (deleteError) {
158
- // Try force delete if regular delete fails
159
- try {
160
- execSync(`git branch -D "${branch}"`, {
161
- encoding: 'utf8',
162
- timeout: TIMEOUT,
163
- stdio: ['pipe', 'pipe', 'pipe']
164
- });
165
- deletedBranches.push(branch);
166
- }
167
- catch (forceDeleteError) {
168
- // Couldn't delete - skip this branch
169
- }
170
- }
171
- }
172
- }
173
- return deletedBranches;
174
- }
175
- catch (error) {
176
- return [];
177
- }
178
- }
179
- /**
180
- * Check if a branch has been merged into main
181
- */
182
- isBranchMerged(branch) {
183
- try {
184
- const mergedBranches = execSync(`git branch --merged ${this.mainBranch} --format="%(refname:short)"`, {
185
- encoding: 'utf8',
186
- timeout: TIMEOUT
187
- });
188
- return mergedBranches.includes(branch);
189
- }
190
- catch (error) {
191
- // If we can't determine merge status, don't delete the branch
192
- return false;
193
- }
194
- }
195
- /**
196
- * Clean up remote tracking references
197
- */
198
- pruneRemoteReferences() {
199
- try {
200
- execSync(`git remote prune ${this.remoteName}`, {
201
- encoding: 'utf8',
202
- timeout: TIMEOUT,
203
- stdio: ['pipe', 'pipe', 'pipe']
204
- });
205
- }
206
- catch (error) {
207
- // Non-critical operation - don't fail on error
208
- }
209
- }
210
- }
211
- /**
212
- * Convenience function for quick cleanup
213
- *
214
- * @param options - Cleanup options
215
- * @returns Cleanup result
216
- */
217
- export async function cleanupMergedBranches(options = {}) {
218
- const cleanup = new PostPRMergeCleanup(options);
219
- return cleanup.runCleanup();
220
- }
221
- //# sourceMappingURL=post-merge-cleanup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"post-merge-cleanup.js","sourceRoot":"","sources":["../src/post-merge-cleanup.ts"],"names":[],"mappings":"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"}
@@ -1,44 +0,0 @@
1
- /**
2
- * Deterministic Git Tree Hash Calculation
3
- *
4
- * Provides content-based hashing of working tree state including:
5
- * - Staged changes (index)
6
- * - Unstaged changes (working tree modifications)
7
- * - Untracked files
8
- *
9
- * CRITICAL FIX: Uses git write-tree instead of git stash create for determinism.
10
- * git stash create includes timestamps, making hashes non-deterministic.
11
- * git write-tree produces content-based hashes only (no timestamps).
12
- */
13
- /**
14
- * Get deterministic git tree hash representing current working tree state
15
- *
16
- * Implementation:
17
- * 1. Mark untracked files with --intent-to-add (no actual staging)
18
- * 2. Calculate tree hash with git write-tree (content-based, no timestamps)
19
- * 3. Reset index to clean state (no side effects)
20
- *
21
- * Why this is better than git stash create:
22
- * - git stash create: includes timestamps in commit → different hash each time
23
- * - git write-tree: content-based only → same content = same hash (deterministic)
24
- *
25
- * @returns Git tree SHA-1 hash (40 hex characters)
26
- * @throws Error if not in a git repository or git command fails
27
- */
28
- export declare function getGitTreeHash(): Promise<string>;
29
- /**
30
- * Get tree hash for HEAD commit (committed state only, no working tree changes)
31
- *
32
- * This is useful for comparing committed state vs working tree state.
33
- *
34
- * @returns Git tree SHA-1 hash of HEAD commit
35
- * @throws Error if not in a git repository or HEAD doesn't exist
36
- */
37
- export declare function getHeadTreeHash(): Promise<string>;
38
- /**
39
- * Check if working tree has any changes compared to HEAD
40
- *
41
- * @returns true if working tree differs from HEAD, false if clean
42
- */
43
- export declare function hasWorkingTreeChanges(): Promise<boolean>;
44
- //# sourceMappingURL=tree-hash.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree-hash.d.ts","sourceRoot":"","sources":["../src/tree-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CA6CtD;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,CAQvD;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAS9D"}
package/dist/tree-hash.js DELETED
@@ -1,110 +0,0 @@
1
- /**
2
- * Deterministic Git Tree Hash Calculation
3
- *
4
- * Provides content-based hashing of working tree state including:
5
- * - Staged changes (index)
6
- * - Unstaged changes (working tree modifications)
7
- * - Untracked files
8
- *
9
- * CRITICAL FIX: Uses git write-tree instead of git stash create for determinism.
10
- * git stash create includes timestamps, making hashes non-deterministic.
11
- * git write-tree produces content-based hashes only (no timestamps).
12
- */
13
- import { execSync } from 'child_process';
14
- const GIT_TIMEOUT = 10000; // 10 seconds
15
- const GIT_OPTIONS = {
16
- encoding: 'utf8',
17
- timeout: GIT_TIMEOUT,
18
- stdio: ['pipe', 'pipe', 'ignore'],
19
- };
20
- /**
21
- * Get deterministic git tree hash representing current working tree state
22
- *
23
- * Implementation:
24
- * 1. Mark untracked files with --intent-to-add (no actual staging)
25
- * 2. Calculate tree hash with git write-tree (content-based, no timestamps)
26
- * 3. Reset index to clean state (no side effects)
27
- *
28
- * Why this is better than git stash create:
29
- * - git stash create: includes timestamps in commit → different hash each time
30
- * - git write-tree: content-based only → same content = same hash (deterministic)
31
- *
32
- * @returns Git tree SHA-1 hash (40 hex characters)
33
- * @throws Error if not in a git repository or git command fails
34
- */
35
- export async function getGitTreeHash() {
36
- try {
37
- // Check if we're in a git repository
38
- execSync('git rev-parse --is-inside-work-tree', GIT_OPTIONS);
39
- // Step 1: Mark all untracked files with --intent-to-add
40
- // This adds them to the index WITHOUT staging their content
41
- // --force: include ignored files for complete state tracking
42
- try {
43
- execSync('git add --intent-to-add --all --force', {
44
- ...GIT_OPTIONS,
45
- stdio: ['pipe', 'pipe', 'pipe'] // Capture stderr for error handling
46
- });
47
- }
48
- catch (addError) {
49
- // If no untracked files, git add fails with "nothing to add"
50
- // This is fine - just means we only have tracked files
51
- const errorMessage = addError instanceof Error ? addError.message : String(addError);
52
- if (!errorMessage.includes('nothing')) {
53
- // Real error - re-throw
54
- throw addError;
55
- }
56
- }
57
- // Step 2: Get tree hash (content-based, no timestamps)
58
- const treeHash = execSync('git write-tree', GIT_OPTIONS).trim();
59
- // Step 3: Reset index to clean state (remove intent-to-add marks)
60
- // This ensures no side effects from our hash calculation
61
- execSync('git reset', GIT_OPTIONS);
62
- return treeHash;
63
- }
64
- catch (error) {
65
- // Handle not-in-git-repo case
66
- const errorMessage = error instanceof Error ? error.message : String(error);
67
- if (errorMessage.includes('not a git repository')) {
68
- // Not in git repo - fall back to timestamp-based hash
69
- console.warn('⚠️ Not in git repository, using timestamp-based hash');
70
- return `nogit-${Date.now()}`;
71
- }
72
- // Other git errors
73
- throw new Error(`Failed to calculate git tree hash: ${errorMessage}`);
74
- }
75
- }
76
- /**
77
- * Get tree hash for HEAD commit (committed state only, no working tree changes)
78
- *
79
- * This is useful for comparing committed state vs working tree state.
80
- *
81
- * @returns Git tree SHA-1 hash of HEAD commit
82
- * @throws Error if not in a git repository or HEAD doesn't exist
83
- */
84
- export async function getHeadTreeHash() {
85
- try {
86
- const treeHash = execSync('git rev-parse HEAD^{tree}', GIT_OPTIONS).trim();
87
- return treeHash;
88
- }
89
- catch (error) {
90
- const errorMessage = error instanceof Error ? error.message : String(error);
91
- throw new Error(`Failed to get HEAD tree hash: ${errorMessage}`);
92
- }
93
- }
94
- /**
95
- * Check if working tree has any changes compared to HEAD
96
- *
97
- * @returns true if working tree differs from HEAD, false if clean
98
- */
99
- export async function hasWorkingTreeChanges() {
100
- try {
101
- const workingTreeHash = await getGitTreeHash();
102
- const headTreeHash = await getHeadTreeHash();
103
- return workingTreeHash !== headTreeHash;
104
- }
105
- catch (error) {
106
- // If we can't determine, assume there are changes (safe default)
107
- return true;
108
- }
109
- }
110
- //# sourceMappingURL=tree-hash.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree-hash.js","sourceRoot":"","sources":["../src/tree-hash.ts"],"names":[],"mappings":"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"}