@@ -6,6 +6,8 @@ import { createLocalProject, createSshProject, getSshProjectPathStatus } from '.
66
77const mocks = vi . hoisted ( ( ) => ( {
88 detectInfoMock : vi . fn ( ) ,
9+ getBranchesMock : vi . fn ( ) ,
10+ getDefaultBranchMock : vi . fn ( ) ,
911 initRepositoryMock : vi . fn ( ) ,
1012 openProjectMock : vi . fn ( ) ,
1113 getProjectMock : vi . fn ( ) ,
@@ -20,6 +22,8 @@ vi.mock('@main/core/git/impl/git-service', () => ({
2022 GitService : vi . fn ( function MockGitService ( ) {
2123 return {
2224 detectInfo : mocks . detectInfoMock ,
25+ getBranches : mocks . getBranchesMock ,
26+ getDefaultBranch : mocks . getDefaultBranchMock ,
2327 initRepository : mocks . initRepositoryMock ,
2428 } ;
2529 } ) ,
@@ -59,6 +63,8 @@ beforeEach(() => {
5963 mocks . valuesMock . mockReturnValue ( { returning : mocks . returningMock } ) ;
6064 mocks . openProjectMock . mockResolvedValue ( undefined ) ;
6165 mocks . getProjectMock . mockReturnValue ( undefined ) ;
66+ mocks . getBranchesMock . mockResolvedValue ( [ ] ) ;
67+ mocks . getDefaultBranchMock . mockResolvedValue ( 'main' ) ;
6268 mocks . initRepositoryMock . mockResolvedValue ( undefined ) ;
6369 mocks . sshConnectMock . mockResolvedValue ( { id : 'ssh-proxy' } ) ;
6470 mocks . sshStatMock . mockResolvedValue ( { path : '' , type : 'dir' } ) ;
@@ -172,6 +178,84 @@ describe('createLocalProject', () => {
172178 expect ( mocks . initRepositoryMock ) . not . toHaveBeenCalled ( ) ;
173179 expect ( mocks . detectInfoMock ) . toHaveBeenCalledTimes ( 1 ) ;
174180 } ) ;
181+
182+ it ( 'stores the git remote default branch as baseRef instead of the current feature branch' , async ( ) => {
183+ const projectPath = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'emdash-project-' ) ) ;
184+ tempDirs . push ( projectPath ) ;
185+ const row = {
186+ id : 'project-id' ,
187+ name : 'Project' ,
188+ path : projectPath ,
189+ baseRef : 'origin/main' ,
190+ createdAt : '2026-04-16T00:00:00.000Z' ,
191+ updatedAt : '2026-04-16T00:00:00.000Z' ,
192+ } ;
193+
194+ mocks . detectInfoMock . mockResolvedValue ( {
195+ isGitRepo : true ,
196+ baseRef : 'origin/feature/current' ,
197+ rootPath : projectPath ,
198+ } ) ;
199+ mocks . getDefaultBranchMock . mockResolvedValue ( 'main' ) ;
200+ mocks . getBranchesMock . mockResolvedValue ( [
201+ {
202+ type : 'remote' ,
203+ branch : 'main' ,
204+ remote : { name : 'origin' , url : 'git@github.com:example/repo.git' } ,
205+ } ,
206+ ] ) ;
207+ mocks . returningMock . mockResolvedValue ( [ row ] ) ;
208+
209+ const created = await createLocalProject ( {
210+ id : 'project-id' ,
211+ name : 'Project' ,
212+ path : projectPath ,
213+ } ) ;
214+
215+ expect ( mocks . valuesMock ) . toHaveBeenCalledWith (
216+ expect . objectContaining ( { baseRef : 'origin/main' } )
217+ ) ;
218+ expect ( created . baseRef ) . toBe ( 'origin/main' ) ;
219+ } ) ;
220+
221+ it ( 'keeps the detected baseRef when the git default branch is not present on the remote' , async ( ) => {
222+ const projectPath = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'emdash-project-' ) ) ;
223+ tempDirs . push ( projectPath ) ;
224+ const row = {
225+ id : 'project-id' ,
226+ name : 'Project' ,
227+ path : projectPath ,
228+ baseRef : 'origin/feature/current' ,
229+ createdAt : '2026-04-16T00:00:00.000Z' ,
230+ updatedAt : '2026-04-16T00:00:00.000Z' ,
231+ } ;
232+
233+ mocks . detectInfoMock . mockResolvedValue ( {
234+ isGitRepo : true ,
235+ baseRef : 'origin/feature/current' ,
236+ rootPath : projectPath ,
237+ } ) ;
238+ mocks . getDefaultBranchMock . mockResolvedValue ( 'main' ) ;
239+ mocks . getBranchesMock . mockResolvedValue ( [
240+ {
241+ type : 'remote' ,
242+ branch : 'develop' ,
243+ remote : { name : 'origin' , url : 'git@github.com:example/repo.git' } ,
244+ } ,
245+ ] ) ;
246+ mocks . returningMock . mockResolvedValue ( [ row ] ) ;
247+
248+ const created = await createLocalProject ( {
249+ id : 'project-id' ,
250+ name : 'Project' ,
251+ path : projectPath ,
252+ } ) ;
253+
254+ expect ( mocks . valuesMock ) . toHaveBeenCalledWith (
255+ expect . objectContaining ( { baseRef : 'origin/feature/current' } )
256+ ) ;
257+ expect ( created . baseRef ) . toBe ( 'origin/feature/current' ) ;
258+ } ) ;
175259} ) ;
176260
177261describe ( 'createSshProject' , ( ) => {
@@ -262,6 +346,40 @@ describe('createSshProject', () => {
262346 expect ( mocks . detectInfoMock ) . not . toHaveBeenCalled ( ) ;
263347 expect ( mocks . initRepositoryMock ) . not . toHaveBeenCalled ( ) ;
264348 } ) ;
349+
350+ it ( 'stores the git remote default branch as the SSH project baseRef' , async ( ) => {
351+ const rowWithDefault = {
352+ ...row ,
353+ baseRef : 'origin/main' ,
354+ } ;
355+
356+ mocks . detectInfoMock . mockResolvedValue ( {
357+ isGitRepo : true ,
358+ baseRef : 'origin/feature/current' ,
359+ rootPath : row . path ,
360+ } ) ;
361+ mocks . getDefaultBranchMock . mockResolvedValue ( 'main' ) ;
362+ mocks . getBranchesMock . mockResolvedValue ( [
363+ {
364+ type : 'remote' ,
365+ branch : 'main' ,
366+ remote : { name : 'origin' , url : 'git@github.com:example/repo.git' } ,
367+ } ,
368+ ] ) ;
369+ mocks . returningMock . mockResolvedValue ( [ rowWithDefault ] ) ;
370+
371+ const created = await createSshProject ( {
372+ id : 'project-id' ,
373+ name : 'Project' ,
374+ path : projectPath ,
375+ connectionId : 'connection-id' ,
376+ } ) ;
377+
378+ expect ( mocks . valuesMock ) . toHaveBeenCalledWith (
379+ expect . objectContaining ( { baseRef : 'origin/main' } )
380+ ) ;
381+ expect ( created . baseRef ) . toBe ( 'origin/main' ) ;
382+ } ) ;
265383} ) ;
266384
267385describe ( 'getSshProjectPathStatus' , ( ) => {
0 commit comments