Skip to content
Open
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
32 changes: 32 additions & 0 deletions src/application/GitRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { join } from 'path'
import { readFile } from 'fs'
import Git from '../models/Git'
import Submodule from '../models/Submodule'
import Branch from '../models/Branch'
import Logger from '../UI/Logger'
import Status from '../UI/Status'
import StatusBar from '../UI/StatusBar'
Expand Down Expand Up @@ -470,6 +471,37 @@ export default class GitRepository {
})
}

/**
* Get the list of branches that conatining current commit
* @param gitModel Git-Model of Submodule
*/
static async getBranchesContain(gitModel: Git): Promise<Branch[]> {
let simplegit = GitRepository.getSimplegit(gitModel.getRelativePath())
const branches_local = await simplegit.branch(['--contains', gitModel.getBranch()])
const branches_remote = await simplegit.branch(['--remote', '--contains', gitModel.getBranch()])
let branches : Branch[] = []
let branches_local_names : string[] = []
let discardfirst : boolean = branches_local.detached
branches_local.all.forEach((key: any) => {
// Discard the first local branch if detached (it is our detached branch)
if (discardfirst) {
discardfirst = false
} else {
branches.push(new Branch(branches_local.branches[key].name, branches_local.branches[key].commit))
branches_local_names.push(branches_local.branches[key].name)
}
})
branches_remote.all.forEach((key: any) => {
// Get the branch name by removing the first part before slash which is the origin
let name = branches_remote.branches[key].name.split("/",2)[1]
// Make sure that we don't add twice a remote branch and local branch
if (!branches_local_names.includes(name)) {
branches.push(new Branch(name, branches_remote.branches[key].commit))
}
})
return branches
}

/*******************************************************************************************/
/* PULL */
/*******************************************************************************************/
Expand Down
49 changes: 23 additions & 26 deletions src/handlers/git/branch_changed/DetectDetachedHead.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,44 +66,41 @@ export default class DetectDetachedHead extends ChangeHandler {
* finds the corresponding Branch for a Commit-Hash
*/
private static getRealBranchForHash = async (gitModel: Git): Promise<string> => {
// the first one in the list is the current "detached HEAD"
const branches = gitModel.getLocalBranches().filter((branch, index) => index > 1)
const current = gitModel.getBranch()

const realBranches: string[] = []
branches.forEach((branch: Branch) => {
if (current === branch.getCommit() || current === branch.getName()) {
realBranches.push(branch.getName())
}
})

if (realBranches.length) {
if (realBranches.length === 1) {
return realBranches[0]
}

// Get the list of branches that contain the specified commit
const branches = await GitRepository.getBranchesContain(gitModel)
// If there is only one, we have found it
if (branches.length === 1) {
return branches[0].getName()
}
// Otherwise, if we have many options ...
if (branches.length) {
// Create a list with the branches names
const branches_names: string[] = []
branches.forEach((branch: Branch) => {
branches_names.push(branch.getName())
})
// Check if any of them match with the configured one in .gitmodules
if (gitModel.getMainRepositoryPath()) {
const configuredBranch = await GitRepository.getConfiguredBranchForSubmodule(gitModel)
if (configuredBranch && realBranches.includes(configuredBranch)) {
if (configuredBranch && branches_names.includes(configuredBranch)) {
return configuredBranch
}

const options: QuickPickOption[] = realBranches.map((branch) => new QuickPickOption(branch, branch))

const selectedBranch = await QuickPick.showQuickPick('choose the branch to check out', ...options)
if (selectedBranch) {
return selectedBranch
}
}
// Otherwise ask the user
const options: QuickPickOption[] = branches_names.map((branch) => new QuickPickOption(branch, branch))
const selectedBranch = await QuickPick.showQuickPick('choose the branch to check out', ...options)
if (selectedBranch) {
return selectedBranch
}
}

// If no branch contains the current commit, just warn the user
const current = gitModel.getBranch()
Logger.showError(
`could not find branch for '${current}' ${
!gitModel.isRootGit() ? ` in Submodule '${gitModel.getRelativePath()}'` : ''
}. You have to checkout the branch manually.`,
true,
)

return ''
}
}