Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,18 @@ async function githubinator({
}

const gitDir = gitDirectories.git
const commonGitDir = gitDirectories.commonGit
const repoDir = gitDirectories.repository

let headBranch: [string, string | null] | null = null
if (mainBranch) {
const res = await findShaForBranches(gitDir)
const res = await findShaForBranches(commonGitDir)
if (res == null) {
return err(`Could not find SHA for branch in ${mainBranches()}`)
}
headBranch = res
} else {
headBranch = await git.head(gitDir)
headBranch = await git.head(gitDir, commonGitDir)
}
if (headBranch == null) {
return err("Could not find HEAD.")
Expand All @@ -209,7 +210,7 @@ async function githubinator({
const parsedUrl = await new provider(
providersConfig,
globalDefaultRemote,
(remote) => git.origin(gitDir, remote),
(remote) => git.origin(commonGitDir, remote),
).getUrls({
selection,
// priority: permalink > branch > branch from HEAD
Expand Down
18 changes: 16 additions & 2 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface IRemote {

interface IGitDirectories {
git: string
commonGit: string
repository: string
}

Expand Down Expand Up @@ -71,6 +72,7 @@ export async function getSHAForBranch(
/** Get the current SHA and branch from HEAD for a git directory */
export async function head(
gitDir: string,
commonGitDir?: string,
): Promise<[string, string | null] | null> {
const headPath = path.resolve(gitDir, "HEAD")
if (!(await fs.exists(headPath))) {
Expand All @@ -91,7 +93,7 @@ export async function head(
return [maybeSha.trim(), null]
}
const branchName = maybeHeadInfo.trim().replace("refs/heads/", "")
const sha = await getSHAForBranch(gitDir, branchName)
const sha = await getSHAForBranch(commonGitDir ?? gitDir, branchName)
if (sha == null) {
return null
}
Expand All @@ -102,6 +104,15 @@ export function dir(filePath: string) {
return walkUpDirectories(filePath, ".git")
}

function resolveCommonGitDir(gitDir: string): string {
const commondirPath = path.resolve(gitDir, "commondir")
if (fs.existsSync(commondirPath)) {
const commondir = fs.readFileSync(commondirPath, "utf8").trim()
return path.resolve(gitDir, commondir)
}
return gitDir
}

function walkUpDirectories(
file_path: string,
file_or_folder: string,
Expand All @@ -116,8 +127,10 @@ function walkUpDirectories(
.match(/gitdir: (.+)/)

if (submoduleMatch) {
const gitDir = path.resolve(directory, submoduleMatch[1])
return {
git: path.resolve(path.join(directory, submoduleMatch[1])),
git: gitDir,
commonGit: resolveCommonGitDir(gitDir),
repository: directory,
}
} else {
Expand All @@ -126,6 +139,7 @@ function walkUpDirectories(
} else {
return {
git: newPath,
commonGit: newPath,
repository: directory,
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/test/suite/git.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ suite("git", async () => {

assert.deepStrictEqual(dir(__dirname), {
git: gitPath,
commonGit: gitPath,
repository: repoPath,
})
assert.deepStrictEqual(dir(repoPath), {
git: gitPath,
commonGit: gitPath,
repository: repoPath,
})

Expand All @@ -24,7 +26,30 @@ suite("git", async () => {

assert.deepStrictEqual(dir(submodulePath), {
git: path.join(repoPath, ".git/modules/test_submodule"),
commonGit: path.join(repoPath, ".git/modules/test_submodule"),
repository: submodulePath,
})

// worktree: gitdir redirect with a commondir file
const worktreeGitDir = path.join(repoPath, ".git/worktrees/my-feature")
fs.mkdirSync(worktreeGitDir, { recursive: true })
fs.writeFileSync(path.join(worktreeGitDir, "commondir"), "../..")

const worktreePath = path.join(__dirname, "test_worktree")
fs.mkdirSync(worktreePath, { recursive: true })
fs.writeFileSync(
path.join(worktreePath, ".git"),
`gitdir: ${worktreeGitDir}`,
)

assert.deepStrictEqual(dir(worktreePath), {
git: worktreeGitDir,
commonGit: gitPath,
repository: worktreePath,
})

// cleanup
fs.rmSync(worktreePath, { recursive: true })
fs.rmSync(worktreeGitDir, { recursive: true })
})
})