mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-18 06:22:28 +03:00
ForgeType
Set the type of repository forge type (e.g. GitHub, GitLab) once the base branch is determined. Get the available templates with the updated method
This commit is contained in:
parent
4ee01031f6
commit
d41e271e99
15
apps/desktop/src/lib/backend/forge.ts
Normal file
15
apps/desktop/src/lib/backend/forge.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { invoke } from './ipc';
|
||||||
|
|
||||||
|
export type ForgeType = 'github' | 'gitlab' | 'bitbucket' | 'azure';
|
||||||
|
|
||||||
|
export class ForgeService {
|
||||||
|
constructor(private projectId: string) {}
|
||||||
|
|
||||||
|
async getAvailableReviewTemplates(): Promise<string[]> {
|
||||||
|
const templates = await invoke<string[]>('get_available_review_templates', {
|
||||||
|
projectId: this.projectId
|
||||||
|
});
|
||||||
|
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import { persisted } from '@gitbutler/shared/persisted';
|
|||||||
import { open } from '@tauri-apps/api/dialog';
|
import { open } from '@tauri-apps/api/dialog';
|
||||||
import { plainToInstance } from 'class-transformer';
|
import { plainToInstance } from 'class-transformer';
|
||||||
import { derived, get, writable, type Readable } from 'svelte/store';
|
import { derived, get, writable, type Readable } from 'svelte/store';
|
||||||
|
import type { ForgeType } from './forge';
|
||||||
import type { HttpClient } from '@gitbutler/shared/httpClient';
|
import type { HttpClient } from '@gitbutler/shared/httpClient';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
|
||||||
@ -15,6 +16,8 @@ export type LocalKey = {
|
|||||||
|
|
||||||
export type Key = Exclude<KeyType, 'local'> | LocalKey;
|
export type Key = Exclude<KeyType, 'local'> | LocalKey;
|
||||||
|
|
||||||
|
export type HostType = { type: ForgeType };
|
||||||
|
|
||||||
export class Project {
|
export class Project {
|
||||||
id!: string;
|
id!: string;
|
||||||
title!: string;
|
title!: string;
|
||||||
@ -28,8 +31,8 @@ export class Project {
|
|||||||
snapshot_lines_threshold!: number | undefined;
|
snapshot_lines_threshold!: number | undefined;
|
||||||
use_new_locking!: boolean;
|
use_new_locking!: boolean;
|
||||||
git_host!: {
|
git_host!: {
|
||||||
hostType: 'github' | 'gitlab' | 'bitbucket' | 'azure';
|
hostType: HostType | undefined;
|
||||||
pullRequestTemplatePath: string;
|
reviewTemplatePath: string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Produced just for the frontend to determine if the project is open in any window.
|
// Produced just for the frontend to determine if the project is open in any window.
|
||||||
@ -217,6 +220,14 @@ export class ProjectsService {
|
|||||||
async getCloudProject(repositoryId: string): Promise<CloudProject> {
|
async getCloudProject(repositoryId: string): Promise<CloudProject> {
|
||||||
return await this.httpClient.get(`projects/${repositoryId}.json`);
|
return await this.httpClient.get(`projects/${repositoryId}.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setGitHostType(project: Project, type: ForgeType) {
|
||||||
|
if (project.git_host.hostType?.type === type) return;
|
||||||
|
const hostType: HostType = { type };
|
||||||
|
const gitHost = { hostType };
|
||||||
|
await invoke('update_project_git_host', { projectId: project.id, gitHost });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { AzureBranch } from './azureBranch';
|
import { AzureBranch } from './azureBranch';
|
||||||
|
import type { ForgeType } from '$lib/backend/forge';
|
||||||
import type { RepoInfo } from '$lib/url/gitUrl';
|
import type { RepoInfo } from '$lib/url/gitUrl';
|
||||||
import type { GitHost } from '../interface/gitHost';
|
import type { GitHost } from '../interface/gitHost';
|
||||||
import type { GitHostArguments } from '../interface/types';
|
import type { GitHostArguments } from '../interface/types';
|
||||||
@ -12,6 +13,7 @@ export const AZURE_DOMAIN = 'dev.azure.com';
|
|||||||
* https://github.com/gitbutlerapp/gitbutler/issues/2651
|
* https://github.com/gitbutlerapp/gitbutler/issues/2651
|
||||||
*/
|
*/
|
||||||
export class AzureDevOps implements GitHost {
|
export class AzureDevOps implements GitHost {
|
||||||
|
readonly type: ForgeType = 'azure';
|
||||||
private baseUrl: string;
|
private baseUrl: string;
|
||||||
private repo: RepoInfo;
|
private repo: RepoInfo;
|
||||||
private baseBranch: string;
|
private baseBranch: string;
|
||||||
@ -48,11 +50,6 @@ export class AzureDevOps implements GitHost {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async availablePullRequestTemplates(_path?: string) {
|
|
||||||
// See: https://learn.microsoft.com/en-us/azure/devops/repos/git/pull-request-templates?view=azure-devops#default-pull-request-templates
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
async pullRequestTemplateContent(_path?: string) {
|
async pullRequestTemplateContent(_path?: string) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { BitBucketBranch } from './bitbucketBranch';
|
import { BitBucketBranch } from './bitbucketBranch';
|
||||||
|
import type { ForgeType } from '$lib/backend/forge';
|
||||||
import type { RepoInfo } from '$lib/url/gitUrl';
|
import type { RepoInfo } from '$lib/url/gitUrl';
|
||||||
import type { GitHost } from '../interface/gitHost';
|
import type { GitHost } from '../interface/gitHost';
|
||||||
import type { DetailedPullRequest, GitHostArguments } from '../interface/types';
|
import type { DetailedPullRequest, GitHostArguments } from '../interface/types';
|
||||||
@ -16,6 +17,7 @@ export const BITBUCKET_DOMAIN = 'bitbucket.org';
|
|||||||
* https://github.com/gitbutlerapp/gitbutler/issues/3252
|
* https://github.com/gitbutlerapp/gitbutler/issues/3252
|
||||||
*/
|
*/
|
||||||
export class BitBucket implements GitHost {
|
export class BitBucket implements GitHost {
|
||||||
|
readonly type: ForgeType = 'bitbucket';
|
||||||
private baseUrl: string;
|
private baseUrl: string;
|
||||||
private repo: RepoInfo;
|
private repo: RepoInfo;
|
||||||
private baseBranch: string;
|
private baseBranch: string;
|
||||||
@ -52,11 +54,6 @@ export class BitBucket implements GitHost {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async availablePullRequestTemplates(_path?: string) {
|
|
||||||
// See: https://confluence.atlassian.com/bitbucketserver/create-a-pull-request-808488431.html#Createapullrequest-templatePullrequestdescriptiontemplates
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
async pullRequestTemplateContent(_path?: string) {
|
async pullRequestTemplateContent(_path?: string) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { GitHubListingService } from './githubListingService';
|
|||||||
import { GitHubPrService } from './githubPrService';
|
import { GitHubPrService } from './githubPrService';
|
||||||
import { GitHubIssueService } from '$lib/gitHost/github/issueService';
|
import { GitHubIssueService } from '$lib/gitHost/github/issueService';
|
||||||
import { Octokit } from '@octokit/rest';
|
import { Octokit } from '@octokit/rest';
|
||||||
|
import type { ForgeType } from '$lib/backend/forge';
|
||||||
import type { ProjectMetrics } from '$lib/metrics/projectMetrics';
|
import type { ProjectMetrics } from '$lib/metrics/projectMetrics';
|
||||||
import type { RepoInfo } from '$lib/url/gitUrl';
|
import type { RepoInfo } from '$lib/url/gitUrl';
|
||||||
import type { GitHost } from '../interface/gitHost';
|
import type { GitHost } from '../interface/gitHost';
|
||||||
@ -12,6 +13,7 @@ import type { GitHostArguments } from '../interface/types';
|
|||||||
export const GITHUB_DOMAIN = 'github.com';
|
export const GITHUB_DOMAIN = 'github.com';
|
||||||
|
|
||||||
export class GitHub implements GitHost {
|
export class GitHub implements GitHost {
|
||||||
|
readonly type: ForgeType = 'github';
|
||||||
private baseUrl: string;
|
private baseUrl: string;
|
||||||
private repo: RepoInfo;
|
private repo: RepoInfo;
|
||||||
private baseBranch: string;
|
private baseBranch: string;
|
||||||
|
@ -107,18 +107,4 @@ export class GitHubPrService implements GitHostPrService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async availablePullRequestTemplates(path: string): Promise<string[] | undefined> {
|
|
||||||
// TODO: Find a workaround to avoid this dynamic import
|
|
||||||
// https://github.com/sveltejs/kit/issues/905
|
|
||||||
const { join } = await import('@tauri-apps/api/path');
|
|
||||||
const targetPath = await join(path, '.github');
|
|
||||||
|
|
||||||
const availableTemplates: string[] | undefined = await invoke(
|
|
||||||
'available_pull_request_templates',
|
|
||||||
{ rootPath: targetPath }
|
|
||||||
);
|
|
||||||
|
|
||||||
return availableTemplates;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { GitLabBranch } from './gitlabBranch';
|
import { GitLabBranch } from './gitlabBranch';
|
||||||
|
import type { ForgeType } from '$lib/backend/forge';
|
||||||
import type { RepoInfo } from '$lib/url/gitUrl';
|
import type { RepoInfo } from '$lib/url/gitUrl';
|
||||||
import type { GitHost } from '../interface/gitHost';
|
import type { GitHost } from '../interface/gitHost';
|
||||||
import type { DetailedPullRequest, GitHostArguments } from '../interface/types';
|
import type { DetailedPullRequest, GitHostArguments } from '../interface/types';
|
||||||
@ -17,6 +18,7 @@ export const GITLAB_SUB_DOMAIN = 'gitlab'; // For self hosted instance of Gitlab
|
|||||||
* https://github.com/gitbutlerapp/gitbutler/issues/2511
|
* https://github.com/gitbutlerapp/gitbutler/issues/2511
|
||||||
*/
|
*/
|
||||||
export class GitLab implements GitHost {
|
export class GitLab implements GitHost {
|
||||||
|
readonly type: ForgeType = 'gitlab';
|
||||||
private baseUrl: string;
|
private baseUrl: string;
|
||||||
private repo: RepoInfo;
|
private repo: RepoInfo;
|
||||||
private baseBranch: string;
|
private baseBranch: string;
|
||||||
@ -53,11 +55,6 @@ export class GitLab implements GitHost {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async availablePullRequestTemplates(_path?: string) {
|
|
||||||
// See: https://docs.gitlab.com/ee/user/project/description_templates.html
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
async pullRequestTemplateContent(_path?: string) {
|
async pullRequestTemplateContent(_path?: string) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { buildContextStore } from '@gitbutler/shared/context';
|
import { buildContextStore } from '@gitbutler/shared/context';
|
||||||
|
import type { ForgeType } from '$lib/backend/forge';
|
||||||
import type { GitHostIssueService } from '$lib/gitHost/interface/gitHostIssueService';
|
import type { GitHostIssueService } from '$lib/gitHost/interface/gitHostIssueService';
|
||||||
import type { GitHostBranch } from './gitHostBranch';
|
import type { GitHostBranch } from './gitHostBranch';
|
||||||
import type { GitHostChecksMonitor } from './gitHostChecksMonitor';
|
import type { GitHostChecksMonitor } from './gitHostChecksMonitor';
|
||||||
@ -6,6 +7,7 @@ import type { GitHostListingService } from './gitHostListingService';
|
|||||||
import type { GitHostPrService } from './gitHostPrService';
|
import type { GitHostPrService } from './gitHostPrService';
|
||||||
|
|
||||||
export interface GitHost {
|
export interface GitHost {
|
||||||
|
readonly type: ForgeType;
|
||||||
// Lists PRs for the repo.
|
// Lists PRs for the repo.
|
||||||
listService(): GitHostListingService | undefined;
|
listService(): GitHostListingService | undefined;
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ export interface GitHostPrService {
|
|||||||
baseBranchName,
|
baseBranchName,
|
||||||
upstreamName
|
upstreamName
|
||||||
}: CreatePullRequestArgs): Promise<PullRequest>;
|
}: CreatePullRequestArgs): Promise<PullRequest>;
|
||||||
availablePullRequestTemplates(path: string): Promise<string[] | undefined>;
|
|
||||||
pullRequestTemplateContent(path: string, projectId: string): Promise<string | undefined>;
|
pullRequestTemplateContent(path: string, projectId: string): Promise<string | undefined>;
|
||||||
merge(method: MergeMethod, prNumber: number): Promise<void>;
|
merge(method: MergeMethod, prNumber: number): Promise<void>;
|
||||||
prMonitor(prNumber: number): GitHostPrMonitor;
|
prMonitor(prNumber: number): GitHostPrMonitor;
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
props.type === 'preview-series' ? props.upstreamName : branch.upstreamName
|
props.type === 'preview-series' ? props.upstreamName : branch.upstreamName
|
||||||
);
|
);
|
||||||
const baseBranchName = $derived($baseBranch.shortName);
|
const baseBranchName = $derived($baseBranch.shortName);
|
||||||
const prTemplatePath = $derived(project.git_host.pullRequestTemplatePath);
|
const prTemplatePath = $derived(project.git_host.reviewTemplatePath);
|
||||||
let isDraft = $state<boolean>($preferredPRAction === PRAction.CreateDraft);
|
let isDraft = $state<boolean>($preferredPRAction === PRAction.CreateDraft);
|
||||||
|
|
||||||
let modal = $state<ReturnType<typeof Modal>>();
|
let modal = $state<ReturnType<typeof Modal>>();
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import notFoundSvg from '$lib/assets/empty-state/not-found.svg?raw';
|
import notFoundSvg from '$lib/assets/empty-state/not-found.svg?raw';
|
||||||
import { Project, ProjectsService } from '$lib/backend/projects';
|
import { ForgeService } from '$lib/backend/forge';
|
||||||
|
import { ProjectService, ProjectsService } from '$lib/backend/projects';
|
||||||
import SectionCard from '$lib/components/SectionCard.svelte';
|
import SectionCard from '$lib/components/SectionCard.svelte';
|
||||||
import { getGitHost } from '$lib/gitHost/interface/gitHost';
|
|
||||||
import { createGitHostPrServiceStore } from '$lib/gitHost/interface/gitHostPrService';
|
|
||||||
import Select from '$lib/select/Select.svelte';
|
import Select from '$lib/select/Select.svelte';
|
||||||
import SelectItem from '$lib/select/SelectItem.svelte';
|
import SelectItem from '$lib/select/SelectItem.svelte';
|
||||||
import Section from '$lib/settings/Section.svelte';
|
import Section from '$lib/settings/Section.svelte';
|
||||||
@ -14,25 +13,27 @@
|
|||||||
import EmptyStatePlaceholder from '@gitbutler/ui/EmptyStatePlaceholder.svelte';
|
import EmptyStatePlaceholder from '@gitbutler/ui/EmptyStatePlaceholder.svelte';
|
||||||
|
|
||||||
const projectsService = getContext(ProjectsService);
|
const projectsService = getContext(ProjectsService);
|
||||||
const project = getContext(Project);
|
const projectService = getContext(ProjectService);
|
||||||
const gitHost = getGitHost();
|
const forgeService = getContext(ForgeService);
|
||||||
const prService = createGitHostPrServiceStore(undefined);
|
|
||||||
$effect(() => prService.set($gitHost?.prService()));
|
|
||||||
|
|
||||||
let useTemplate = $state(!!project.git_host?.pullRequestTemplatePath);
|
const projectStore = projectService.project;
|
||||||
let selectedTemplate = $state(project.git_host?.pullRequestTemplatePath ?? '');
|
const project = $derived($projectStore);
|
||||||
|
const useTemplate = $derived(!!project?.git_host.reviewTemplatePath);
|
||||||
|
const selectedTemplate = $derived(project?.git_host.reviewTemplatePath);
|
||||||
let allAvailableTemplates = $state<{ label: string; value: string }[]>([]);
|
let allAvailableTemplates = $state<{ label: string; value: string }[]>([]);
|
||||||
let isTemplatesAvailable = $state(false);
|
let isTemplatesAvailable = $state(false);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!project.path) return;
|
if (!project) {
|
||||||
$prService?.availablePullRequestTemplates(project.path).then((availableTemplates) => {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
forgeService.getAvailableReviewTemplates().then((availableTemplates) => {
|
||||||
if (availableTemplates) {
|
if (availableTemplates) {
|
||||||
allAvailableTemplates = availableTemplates.map((availableTemplate) => {
|
allAvailableTemplates = availableTemplates.map((availableTemplate) => {
|
||||||
const relativePath = availableTemplate.replace(`${project.path}/`, '');
|
|
||||||
return {
|
return {
|
||||||
label: relativePath,
|
label: availableTemplate,
|
||||||
value: relativePath
|
value: availableTemplate
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -42,15 +43,26 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function setUsePullRequestTemplate(value: boolean) {
|
async function setUsePullRequestTemplate(value: boolean) {
|
||||||
if (!value) {
|
if (!project) return;
|
||||||
project.git_host.pullRequestTemplatePath = '';
|
|
||||||
|
setTemplate: {
|
||||||
|
if (!value) {
|
||||||
|
project.git_host.reviewTemplatePath = undefined;
|
||||||
|
break setTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allAvailableTemplates[0]) {
|
||||||
|
project.git_host.reviewTemplatePath = allAvailableTemplates[0].value;
|
||||||
|
break setTemplate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await projectsService.updateProject(project);
|
await projectsService.updateProject(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setPullRequestTemplatePath(value: string) {
|
async function setPullRequestTemplatePath(value: string) {
|
||||||
selectedTemplate = value;
|
if (!project) return;
|
||||||
project.git_host.pullRequestTemplatePath = value;
|
project.git_host.reviewTemplatePath = value;
|
||||||
await projectsService.updateProject(project);
|
await projectsService.updateProject(project);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -66,7 +78,8 @@
|
|||||||
<svelte:fragment slot="actions">
|
<svelte:fragment slot="actions">
|
||||||
<Toggle
|
<Toggle
|
||||||
id="use-pull-request-template-boolean"
|
id="use-pull-request-template-boolean"
|
||||||
bind:checked={useTemplate}
|
checked={useTemplate}
|
||||||
|
disabled={!isTemplatesAvailable}
|
||||||
on:click={(e) => {
|
on:click={(e) => {
|
||||||
setUsePullRequestTemplate(
|
setUsePullRequestTemplate(
|
||||||
(e.target as MouseEvent['target'] & { checked: boolean }).checked
|
(e.target as MouseEvent['target'] & { checked: boolean }).checked
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { ForgeService } from '$lib/backend/forge';
|
||||||
import { Project, ProjectService } from '$lib/backend/projects';
|
import { Project, ProjectService } from '$lib/backend/projects';
|
||||||
import FileMenuAction from '$lib/barmenuActions/FileMenuAction.svelte';
|
import FileMenuAction from '$lib/barmenuActions/FileMenuAction.svelte';
|
||||||
import ProjectSettingsMenuAction from '$lib/barmenuActions/ProjectSettingsMenuAction.svelte';
|
import ProjectSettingsMenuAction from '$lib/barmenuActions/ProjectSettingsMenuAction.svelte';
|
||||||
@ -71,6 +72,7 @@
|
|||||||
setContext(BranchController, data.branchController);
|
setContext(BranchController, data.branchController);
|
||||||
setContext(BaseBranchService, data.baseBranchService);
|
setContext(BaseBranchService, data.baseBranchService);
|
||||||
setContext(CommitService, data.commitService);
|
setContext(CommitService, data.commitService);
|
||||||
|
setContext(ForgeService, data.forgeService);
|
||||||
setContext(BaseBranch, baseBranch);
|
setContext(BaseBranch, baseBranch);
|
||||||
setContext(Project, project);
|
setContext(Project, project);
|
||||||
setContext(BranchDragActionsFactory, data.branchDragActionsFactory);
|
setContext(BranchDragActionsFactory, data.branchDragActionsFactory);
|
||||||
@ -146,6 +148,8 @@
|
|||||||
|
|
||||||
const ghListService = gitHost?.listService();
|
const ghListService = gitHost?.listService();
|
||||||
|
|
||||||
|
if (gitHost) projectsService.setGitHostType(project, gitHost.type);
|
||||||
|
|
||||||
listServiceStore.set(ghListService);
|
listServiceStore.set(ghListService);
|
||||||
gitHostStore.set(gitHost);
|
gitHostStore.set(gitHost);
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ForgeService } from '$lib/backend/forge';
|
||||||
import { getUserErrorCode, invoke } from '$lib/backend/ipc';
|
import { getUserErrorCode, invoke } from '$lib/backend/ipc';
|
||||||
import { ProjectService, type Project } from '$lib/backend/projects';
|
import { ProjectService, type Project } from '$lib/backend/projects';
|
||||||
import { BaseBranchService } from '$lib/baseBranch/baseBranchService';
|
import { BaseBranchService } from '$lib/baseBranch/baseBranchService';
|
||||||
@ -61,6 +62,7 @@ export const load: LayoutLoad = async ({ params, parent }) => {
|
|||||||
const historyService = new HistoryService(projectId);
|
const historyService = new HistoryService(projectId);
|
||||||
const baseBranchService = new BaseBranchService(projectId);
|
const baseBranchService = new BaseBranchService(projectId);
|
||||||
const commitService = new CommitService(projectId);
|
const commitService = new CommitService(projectId);
|
||||||
|
const forgeService = new ForgeService(projectId);
|
||||||
|
|
||||||
const branchListingService = new BranchListingService(projectId);
|
const branchListingService = new BranchListingService(projectId);
|
||||||
const remoteBranchService = new RemoteBranchService(
|
const remoteBranchService = new RemoteBranchService(
|
||||||
@ -108,6 +110,7 @@ export const load: LayoutLoad = async ({ params, parent }) => {
|
|||||||
authService,
|
authService,
|
||||||
baseBranchService,
|
baseBranchService,
|
||||||
commitService,
|
commitService,
|
||||||
|
forgeService,
|
||||||
branchController,
|
branchController,
|
||||||
historyService,
|
historyService,
|
||||||
projectId,
|
projectId,
|
||||||
|
Loading…
Reference in New Issue
Block a user