@feng0531/dsh-vcs 0.7.0 → 0.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feng0531/dsh-vcs",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "private": false,
5
5
  "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" },
6
6
  "type": "module",
package/vcs.mjs CHANGED
@@ -65,12 +65,13 @@ export async function detectRepository(cwd) {
65
65
 
66
66
  const DISCOVERY_SKIP = new Set(['.git', '.svn', 'node_modules', 'bower_components', 'vendor', '.pnpm', '.yarn', '.npm', '.cache', '__pycache__', '.venv', 'venv', '.tox', '.mypy_cache', '.pytest_cache', '.gradle', '.nuget']);
67
67
 
68
- async function repositoryAt(directory, type, options = () => undefined) {
68
+ async function repositoryAt(directory, type, options = () => undefined, includeBranch = true) {
69
69
  if (type === 'svn') {
70
70
  const info = parseXML(await svn(directory, ['info', '--xml', '--', '.'], undefined, options())).info.entry[0];
71
71
  return { root: await fs.realpath(info['wc-info']['wcroot-abspath']), type };
72
72
  }
73
73
  const root = await fs.realpath((await git(directory, ['rev-parse', '--show-toplevel'], undefined, options())).toString('utf8').trim());
74
+ if (!includeBranch) return {root, type};
74
75
  let branch;
75
76
  try { branch = (await git(root, ['symbolic-ref', '--quiet', '--short', 'HEAD'], undefined, options())).toString('utf8').trim(); }
76
77
  catch (e) {
@@ -194,10 +195,10 @@ export async function discoverRepositories(cwd, { signal, maxDepth = 6, maxDirec
194
195
  return result;
195
196
  }
196
197
 
197
- async function checkedRepo(repo, signal, budget) {
198
+ async function checkedRepo(repo, signal, budget, includeBranch = true) {
198
199
  signal?.throwIfAborted();
199
200
  if (!repo || !['git', 'svn'].includes(repo.type) || typeof repo.root !== 'string') throw new Error('Invalid repository');
200
- const found = await repositoryAt(repo.root, repo.type, budget || (() => ({signal})));
201
+ const found = await repositoryAt(repo.root, repo.type, budget || (() => ({signal})), includeBranch);
201
202
  signal?.throwIfAborted();
202
203
  if (!found || found.type !== repo.type || path.resolve(found.root) !== path.resolve(repo.root)) throw new Error('Repository root changed or is invalid');
203
204
  return found;
@@ -206,8 +207,8 @@ function assertGit(repo, message) {
206
207
  if (repo.type !== 'git') throw new Error(message);
207
208
  return repo;
208
209
  }
209
- async function checkedGitRepo(repo, signal, message, budget) {
210
- return assertGit(await checkedRepo(repo, signal, budget), message);
210
+ async function checkedGitRepo(repo, signal, message, budget, includeBranch = true) {
211
+ return assertGit(await checkedRepo(repo, signal, budget, includeBranch), message);
211
212
  }
212
213
  // Probe --since-as-filter support so older Git cannot run a silently unfiltered query.
213
214
  async function assertSinceAsFilterSupport(repo, signal, label) {
@@ -338,7 +339,8 @@ export async function getHistoricalSegment(repo, {commit,path:file,offset,line,s
338
339
  return withOperationBudget({signal},async()=>{
339
340
  const expectedEpoch = historicalAccess.captureEpoch();
340
341
  // Capture before any await: revoked in-flight validation cannot refill object bytes.
341
- repo = await checkedGitRepo(repo, signal, 'Historical segments support Git only');
342
+ // Segment identity depends on the canonical root and pinned commit, not current HEAD metadata.
343
+ repo = await checkedGitRepo(repo, signal, 'Historical segments support Git only', undefined, false);
342
344
  return historicalAccess.segment(repo.root, {commit,path:file,offset,line,signal,expectedEpoch});
343
345
  });
344
346
  }