mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-11 03:38:07 +00:00
test: address review feedback — fake commit, same-commit case, regex docs
Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/e5decb67-7fec-40e7-b2a1-b5e94a0d393f Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
This commit is contained in:
parent
e7bf2de3a4
commit
7341ac6b9e
3 changed files with 65 additions and 21 deletions
|
|
@ -123,11 +123,15 @@ export async function checkCwdMatch(cwd: string): Promise<CwdMatch> {
|
|||
const cwdHead = getCurrentCommit(cwdGitRoot) || undefined;
|
||||
const drift = commitsAheadOfIndexed(cwdGitRoot, sibling.lastCommit);
|
||||
|
||||
let hint: string;
|
||||
// Same commit on both clones → still report match=sibling-by-remote
|
||||
// (the relationship is real and useful to callers like list_repos /
|
||||
// future tooling) but leave `hint` unset: there's nothing to warn
|
||||
// about, and `maybeWarnSiblingDrift` already short-circuits this
|
||||
// case independently. Surfacing a no-op hint would force callers
|
||||
// to second-guess whether they need to display it.
|
||||
let hint: string | undefined;
|
||||
if (cwdHead && cwdHead === sibling.lastCommit) {
|
||||
hint =
|
||||
`ℹ️ Indexed clone "${sibling.name}" lives at ${sibling.path}; ` +
|
||||
`your cwd (${cwdGitRoot}) is a different clone of the same repo at the same commit — results apply.`;
|
||||
hint = undefined;
|
||||
} else if (drift && drift > 0) {
|
||||
hint =
|
||||
`⚠️ Index for "${sibling.name}" was built at ${sibling.path}; ` +
|
||||
|
|
|
|||
|
|
@ -62,6 +62,12 @@ export const getRemoteUrl = (repoPath: string): string | undefined => {
|
|||
|
||||
// Lower-case the host segment of `scheme://[user@]host[:port]/...`
|
||||
// and the host segment of `git@host:owner/repo` SCP form.
|
||||
// SSH user-segment regex deliberately accepts the common
|
||||
// `git@`/`<alnum>-_@` cases. Less common usernames (e.g. with
|
||||
// dots) fall through to the URL-form branch — they will simply
|
||||
// not get host-case normalisation, which is acceptable: the raw
|
||||
// `git config` output is still a valid fingerprint, just slightly
|
||||
// less collapsible across host casings.
|
||||
const sshMatch = normalised.match(/^(git@|[a-zA-Z0-9_-]+@)([^:/]+)(:.+)$/);
|
||||
if (sshMatch) {
|
||||
normalised = `${sshMatch[1]}${sshMatch[2].toLowerCase()}${sshMatch[3]}`;
|
||||
|
|
|
|||
|
|
@ -36,11 +36,6 @@ const initRepoWithCommit = (dir: string, remoteUrl?: string): string => {
|
|||
return execSync('git rev-parse HEAD', { cwd: dir }).toString().trim();
|
||||
};
|
||||
|
||||
const advanceCommit = (dir: string): string => {
|
||||
execSync('git commit --allow-empty -q -m advance', { cwd: dir });
|
||||
return execSync('git rev-parse HEAD', { cwd: dir }).toString().trim();
|
||||
};
|
||||
|
||||
describe('registry persists remoteUrl', () => {
|
||||
let tmpHome: Awaited<ReturnType<typeof createTempDir>>;
|
||||
let tmpRepo: Awaited<ReturnType<typeof createTempDir>>;
|
||||
|
|
@ -178,19 +173,22 @@ describe('checkCwdMatch', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('detects sibling-by-remote at the same commit (no drift hint)', async () => {
|
||||
it('detects sibling-by-remote when sibling HEAD differs from indexed commit', async () => {
|
||||
const indexed = await createTempDir('cwd-indexed-');
|
||||
const sibling = await createTempDir('cwd-sibling-');
|
||||
try {
|
||||
const remote = 'https://example.com/foo/bar';
|
||||
const indexedHead = initRepoWithCommit(indexed.dbPath, remote);
|
||||
// Sibling is a separate `git init` with the same remote URL and
|
||||
// an identical-message empty commit — that's enough for the
|
||||
// remote-URL-based fingerprint to match. Commits differ; we use
|
||||
// the same lastCommit for the registered side anyway because
|
||||
// the warning logic only cares about the *registered* commit
|
||||
// vs the cwd HEAD.
|
||||
initRepoWithCommit(sibling.dbPath, remote);
|
||||
// Sibling is a separate `git init` with the same remote URL —
|
||||
// that's enough for the remote-URL-based fingerprint to match.
|
||||
// Use a distinct commit message so the sibling's SHA cannot
|
||||
// coincidentally collide with the indexed one even when both
|
||||
// commits land in the same second.
|
||||
execSync('git init -q', { cwd: sibling.dbPath });
|
||||
execSync('git config user.email test@example.com', { cwd: sibling.dbPath });
|
||||
execSync('git config user.name test', { cwd: sibling.dbPath });
|
||||
execSync('git commit --allow-empty -q -m sibling-distinct', { cwd: sibling.dbPath });
|
||||
execSync(`git remote add origin ${remote}`, { cwd: sibling.dbPath });
|
||||
|
||||
await registerRepo(indexed.dbPath, {
|
||||
repoPath: indexed.dbPath,
|
||||
|
|
@ -247,13 +245,15 @@ describe('checkCwdMatch', () => {
|
|||
// Use a fabricated indexed commit that doesn't exist in the
|
||||
// sibling clone — git rev-list will fail and `drift` is left
|
||||
// undefined. The hint must still flag this as a stale-or-divergent
|
||||
// sibling clone.
|
||||
const fakeIndexedCommit = '0000000000000000000000000000000000000000';
|
||||
// sibling clone. Named to make test intent obvious; not git's
|
||||
// all-zero "null" OID, which has special semantics in some git
|
||||
// commands.
|
||||
const FAKE_INDEXED_COMMIT = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef';
|
||||
initRepoWithCommit(sibling.dbPath, remote);
|
||||
|
||||
await registerRepo(indexed.dbPath, {
|
||||
repoPath: indexed.dbPath,
|
||||
lastCommit: fakeIndexedCommit,
|
||||
lastCommit: FAKE_INDEXED_COMMIT,
|
||||
indexedAt: new Date().toISOString(),
|
||||
remoteUrl: remote,
|
||||
});
|
||||
|
|
@ -261,11 +261,45 @@ describe('checkCwdMatch', () => {
|
|||
const m = await checkCwdMatch(sibling.dbPath);
|
||||
expect(m.match).toBe('sibling-by-remote');
|
||||
expect(m.cwdHead).toBeTruthy();
|
||||
expect(m.cwdHead).not.toBe(fakeIndexedCommit);
|
||||
expect(m.cwdHead).not.toBe(FAKE_INDEXED_COMMIT);
|
||||
expect(m.hint).toMatch(/sibling clone/);
|
||||
} finally {
|
||||
await indexed.cleanup();
|
||||
await sibling.cleanup();
|
||||
}
|
||||
});
|
||||
|
||||
it('omits hint when sibling cwd HEAD matches the indexed commit (no drift)', async () => {
|
||||
// Same-commit sibling: the relationship is real (and surfaces in
|
||||
// `match: 'sibling-by-remote'`) but there is nothing to warn
|
||||
// about. `LocalBackend.maybeWarnSiblingDrift` short-circuits in
|
||||
// exactly this case, so confirming `hint` is unset here pins the
|
||||
// contract those two pieces of code rely on.
|
||||
const indexed = await createTempDir('cwd-same-indexed-');
|
||||
const sibling = await createTempDir('cwd-same-sibling-');
|
||||
try {
|
||||
const remote = 'https://example.com/foo/bar';
|
||||
initRepoWithCommit(indexed.dbPath, remote);
|
||||
const siblingHead = initRepoWithCommit(sibling.dbPath, remote);
|
||||
|
||||
// Register the indexed entry with the SIBLING's HEAD as
|
||||
// `lastCommit`. That is the on-disk reality when both clones
|
||||
// happen to be at the same commit hash — e.g. immediately
|
||||
// after both fast-forwarded to the same `main`.
|
||||
await registerRepo(indexed.dbPath, {
|
||||
repoPath: indexed.dbPath,
|
||||
lastCommit: siblingHead,
|
||||
indexedAt: new Date().toISOString(),
|
||||
remoteUrl: remote,
|
||||
});
|
||||
|
||||
const m = await checkCwdMatch(sibling.dbPath);
|
||||
expect(m.match).toBe('sibling-by-remote');
|
||||
expect(m.cwdHead).toBe(siblingHead);
|
||||
expect(m.hint).toBeUndefined();
|
||||
} finally {
|
||||
await indexed.cleanup();
|
||||
await sibling.cleanup();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue