Skip to content

Commit ee36065

Browse files
feat(branch): add startPoint param to specify start point for new branch
1 parent fe14078 commit ee36065

5 files changed

Lines changed: 204 additions & 23 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "git-essentials",
3-
"version": "0.3.28",
3+
"version": "0.3.29",
44
"description": "The essential GIT commands",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/api/branch.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ type BranchParams = {
1818
/** What to name the branch. */
1919
ref: string
2020

21+
/** What oid to use as the start point. Accepts a symbolic ref (default: `HEAD`). */
22+
startPoint?: string
23+
2124
/** Update `HEAD` to point at the newly created branch. */
2225
checkout?: boolean
2326

@@ -42,6 +45,7 @@ export async function branch({
4245
dir,
4346
gitdir = join(dir, '.git'),
4447
ref,
48+
startPoint = 'HEAD',
4549
checkout = false,
4650
force = false,
4751
}: BranchParams): Promise<void> {
@@ -54,6 +58,7 @@ export async function branch({
5458
gitdir,
5559
ref,
5660
checkout,
61+
startPoint,
5762
force
5863
})
5964
} catch (err: any) {

src/commands/branch.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type BranchParams = {
99
fs: FileSystem
1010
gitdir: string
1111
ref: string
12+
startPoint?: string
1213
checkout?: boolean
1314
force?: boolean
1415
}
@@ -26,7 +27,14 @@ type BranchParams = {
2627
*
2728
*/
2829
export async function _branch(
29-
{ fs, gitdir, ref, checkout = false, force = false }: BranchParams): Promise<void> {
30+
{
31+
fs,
32+
gitdir,
33+
ref,
34+
startPoint = 'HEAD',
35+
checkout = false,
36+
force = false
37+
}: BranchParams): Promise<void> {
3038
if (ref !== cleanGitRef.clean(ref)) {
3139
throw new InvalidRefNameError(ref, cleanGitRef.clean(ref))
3240
}
@@ -40,10 +48,10 @@ export async function _branch(
4048
}
4149
}
4250

43-
// Get current HEAD tree oid
51+
// Get start point tree oid
4452
let oid: string | undefined
4553
try {
46-
oid = await GitRefManager.resolve({ fs, gitdir, ref: 'HEAD' })
54+
oid = await GitRefManager.resolve({ fs, gitdir, ref: startPoint })
4755
} catch (e) {
4856
// Probably an empty repo
4957
}

tests/branch.test.ts

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { expectNotToFailAsync, expectToFailWithTypeAsync } from './helpers/asser
44
import * as path from './helpers/path'
55

66
import branchFsFixtureData from './fixtures/fs/branch.json'
7+
import branchStartPointFsFixtureData from './fixtures/fs/branch-start-point.json'
78

89
describe('branch', () => {
910
it('branch', async () => {
@@ -19,7 +20,28 @@ describe('branch', () => {
1920
expect(await currentBranch({ fs, dir })).toBe('main')
2021
})
2122

22-
it('branch force=false', async () => {
23+
it('branch with start point', async () => {
24+
// arrange
25+
const { fs, dir } = await makeFsFixture(branchStartPointFsFixtureData as FsFixtureData)
26+
let files = await fs.readdir(path.resolve(dir, '.git', 'refs', 'heads'))
27+
28+
// assert
29+
expect(files).toEqual(['main', 'start-point'])
30+
31+
// act
32+
await branch({ fs, dir, ref: 'test-branch', startPoint: 'start-point' })
33+
34+
// assert
35+
files = await fs.readdir(path.resolve(dir, '.git', 'refs', 'heads'))
36+
expect(files).toEqual(['main', 'start-point', 'test-branch'])
37+
expect(await currentBranch({ fs, dir })).toEqual('main')
38+
expect(await fs.readFile(path.resolve(dir, '.git', 'refs', 'heads', 'test-branch'), { encoding: 'utf8' })
39+
).toEqual(await fs.readFile(path.resolve(dir, '.git', 'refs', 'heads', 'start-point'), { encoding: 'utf8' }))
40+
expect(await listFiles({ fs, dir, ref: 'HEAD' })).toEqual(['new-file.txt'])
41+
expect(await listFiles({ fs, dir, ref: 'test-branch' })).toEqual([])
42+
})
43+
44+
it('branch force=undefined', async () => {
2345
// arrange
2446
const { fs, dir } = await makeFsFixture(branchFsFixtureData as FsFixtureData)
2547

@@ -79,28 +101,28 @@ describe('branch', () => {
79101
await expectNotToFailAsync(action)
80102
})
81103

82-
// it('branch with start point force', async () => {
83-
// // arrange
84-
// const { fs, dir } = await makeFsFixture('test-branch-start-point')
104+
it('branch with start point force', async () => {
105+
// arrange
106+
const { fs, dir } = await makeFsFixture(branchStartPointFsFixtureData as FsFixtureData)
85107

86-
// // act
87-
// await branch({ fs, dir, ref: 'test-branch', startPoint: 'start-point' })
108+
// act
109+
await branch({ fs, dir, ref: 'test-branch', startPoint: 'start-point' })
88110

89-
// // assert
90-
// expect(await currentBranch({ fs, dir })).toEqual('main')
91-
// expect(await fs.exists(path.resolve(dir, '.git', 'refs/heads/test-branch'))).toBeTruthy()
111+
// assert
112+
expect(await currentBranch({ fs, dir })).toEqual('main')
113+
expect(await fs.exists(path.resolve(dir, '.git', 'refs/heads/test-branch'))).toBeTruthy()
92114

93-
// // act
94-
// const action = async () => {
95-
// await branch({ fs, dir, ref: 'test-branch', force: true })
96-
// }
115+
// act
116+
const action = async () => {
117+
await branch({ fs, dir, ref: 'test-branch', force: true })
118+
}
97119

98-
// // assert
99-
// await expectNotToFailAsync(action)
100-
// expect(await listFiles({ fs, dir, ref: 'test-branch' })).toEqual([
101-
// 'new-file.txt',
102-
// ])
103-
// })
120+
// assert
121+
await expectNotToFailAsync(action)
122+
expect(await listFiles({ fs, dir, ref: 'test-branch' })).toEqual([
123+
'new-file.txt',
124+
])
125+
})
104126

105127
it('branch --checkout', async () => {
106128
// arrange
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
[
2+
{
3+
"name": ".git",
4+
"type": "dir",
5+
"children": [
6+
{
7+
"name": "objects",
8+
"type": "dir",
9+
"children": [
10+
{
11+
"name": "12",
12+
"type": "dir",
13+
"children": [
14+
{
15+
"name": "f00e90b6ef79117ce6e650416b8cf517099b78",
16+
"type": "file",
17+
"encoding": "base64",
18+
"content": "eAFLyslPUrBkSM7PK0nNKynmAgAuLQVx"
19+
}
20+
]
21+
},
22+
{
23+
"name": "13",
24+
"type": "dir",
25+
"children": [
26+
{
27+
"name": "86e77b0a7afa8333663a9e4cbf8e6158e625c1",
28+
"type": "file",
29+
"encoding": "base64",
30+
"content": "eAGdk8vOo0YUhLPmKXpvTWigaSDKRAGD8Q8GczHGsMNc2+ZmDBjz9OPMbLOasyqVVCodlb60axoyAgYy0h/jkOcAXUWWz1KM2PSK86uUQAxzHl0LMcMSK4rFNc+RBBGVTGPVDSAkdQ32pB67Fvz9aqqf6t+ySUj9Z9o1/wCGh0hkBU4UwDeIIKQ+7qdyzH8nW/blk5Tg23+naPqXDRzdAf6XbsunwNN++hQ458OTdO1fQG8nRwczQwEKEPcrVWRZkUtZV1wjfmaFKMudoRmRMZmhT3DCj6zrysZua3fMvNsZoxdfWnmJnfFsShQwNf5RrtG1C+hoSpbpbibJI6DrcXjujvW4eH7+Nax3JiqqruDD+GFkxItrizf49nGpaAr4N8FkhN6L9FsfoT3NGwFXaalnnfa66NgHnCCOSXi10YwjlF5yH4vx+a1uYfaYmrQtKLChh/W2bFVat1iewf1FmLxlqg15vU3L2Xo2ccQqDGy1ULhc9kIieH57clUUE37E93yhQHdolXn1PE6DfkT7Fo7so74Q4W7IF9xsH8/t6NZDbGCy02cGddzU7IWDLduHwNp758Pnizc8lU9ryvSzAblcDU9hIRibVpEDvDfoyj6RZvHlPYIdes08b5uVXq8MFjO6z/TdlQKnrl1suCyTMtNYoC9WdRqnrq0fpHK5wlBk1bATZ16GwVoRHWlqIXnKbuOtJBL9ABMKNHqkIHhR1xbbuieEBSfIdnV3wq4wjfGtmtaG6yMrRXgSHEayd/UbvYUe3gJ6waowUyBPSWxmqXibw3JleUsitIkCsWFOvigd/KFntY49wFU/snFyLcPLdr9atsnScs8lWbulgP2sj3bdu+pOyN9ZulmfelFKlWiRskFbppu9udJI4SS6s57fBVT8GxL95JhcjufXPH+2qF03ySGKIoyrcNuRIRVZpZyZw0mumOMwwTIWNmvyenz2CLiz0KZeuFvdPDh7I1bhjQKBjzu02XTsTYR3tpJNX0kp8F15lz71CxPNVv8PEkpr+vENfsFI/QDVEEHI"
31+
}
32+
]
33+
},
34+
{
35+
"name": "3b",
36+
"type": "dir",
37+
"children": [
38+
{
39+
"name": "24a8639f118afcb1883084e76971ff199f2607",
40+
"type": "file",
41+
"encoding": "base64",
42+
"content": "eAGVjUEKAjEMRV33FLmAkimdkIDIHEIP0HYyKlg6dCLo7S16And/8d77uZZyNxhIdtZUIST245wp+JxIk0Qk1DGkhWcSz7wk1SAYXHzarTY462Zw2bTB0fqc9BXL+tBDbddTr9IgjCwC+95Bl79v1un/PKdltTf8dPcBlp83SQ=="
43+
}
44+
]
45+
},
46+
{
47+
"name": "67",
48+
"type": "dir",
49+
"children": [
50+
{
51+
"name": "5fdb77c45298fb4248ae21f262454d15c71716",
52+
"type": "file",
53+
"encoding": "base64",
54+
"content": "eAGdjV0KQiEQRnt2FbOBREUnhYiCNjLq3LrhT1zsod1ntIMevwPnfKnXug7Qh7AbGzPY6I3LCa1JETkGUqjY2bj4jMF4v0RmG5QV9Br3vsGVGlxK4QbHTE0+JH3H+VZpLTL1egKNqINX3jnYz5gSk87LwX/JgutzvOHXEB+Fhjlu"
55+
}
56+
]
57+
},
58+
{
59+
"name": "97",
60+
"type": "dir",
61+
"children": [
62+
{
63+
"name": "e8c903c3647863f404e5f0100b3d3671621d9b",
64+
"type": "file",
65+
"encoding": "base64",
66+
"content": "eAGdjlEKwjAQBf3OKfYClmzbbBIQUfAi22RXK00qJeL1rVfwcx4Mb9Jaytyg7/2hbSKQgjgldIlsGElzUs8oyfKkPqbRhclZspjNizepDYapHznQEBUxsKYJQxh2VTxFj6oYo/ZkveF3e6wb3LjCdVmkwilz7Z4d/+ByLzwvXVrLGZAIY7DRjXDcr6zZ1z2xyV+y4Zyhygd0XsR8AcWJRgU="
67+
}
68+
]
69+
},
70+
{
71+
"name": "b0",
72+
"type": "dir",
73+
"children": [
74+
{
75+
"name": "356faa631d1e390ba42e0faba4ed99151a60e0",
76+
"type": "file",
77+
"encoding": "base64",
78+
"content": "eAGdjV0KAiEURnt2FXcDiYpzRyGGgjZy1Ts14U8M9tDuM9pBj9+Bc77YStk66Nkf+s4MNjgzpYjWxIAcPClUPNmwuoTeOLcGZuuVFfTq97bDlSpccuYKp0RVPiR9x/lWaMsytrKARtTeKTcbOI6YEoOOy85/yYLLs7/h1xAfhSE5bA=="
79+
}
80+
]
81+
},
82+
{
83+
"name": "c8",
84+
"type": "dir",
85+
"children": [
86+
{
87+
"name": "e5f615c60846fdcf7a1ec0abf79c458b50601d",
88+
"type": "file",
89+
"encoding": "base64",
90+
"content": "eAErKUpNVTAxYDA0MDAzMVHISy3XTcvMSdUrqShhEPrAN2Hb+0rBmmfPAhyze76Kc86uAAB+FhHw"
91+
}
92+
]
93+
},
94+
{
95+
"name": "e3",
96+
"type": "dir",
97+
"children": [
98+
{
99+
"name": "e4a27a404219060f4d3688af93080a298c12bf",
100+
"type": "file",
101+
"encoding": "base64",
102+
"content": "eAGVjksOwjAMBVnnFL4AKG4bx5EQ4hBwgCS1oVJ/SoPg+FTcgN0s3uhNXqZpqNCgP9QiApnFKaHLZLkj7bP6iJJtTOpD7hwnZ8lib9ZYZK7QpqaLTG1QRI6aEzK3uyqegkdVDEEbst7EV30uBW6yVbhvUuBcd7zKJ07rKKelPC6ARBjYBm7guL9Yk391dV//55nY9zDLG3QYxXwBUJxD0g=="
103+
}
104+
]
105+
}
106+
]
107+
},
108+
{
109+
"name": "refs",
110+
"type": "dir",
111+
"children": [
112+
{
113+
"name": "heads",
114+
"type": "dir",
115+
"children": [
116+
{
117+
"name": "main",
118+
"type": "file",
119+
"encoding": "utf8",
120+
"content": "e3e4a27a404219060f4d3688af93080a298c12bf\n"
121+
},
122+
{
123+
"name": "start-point",
124+
"type": "file",
125+
"encoding": "utf8",
126+
"content": "3b24a8639f118afcb1883084e76971ff199f2607\n"
127+
}
128+
]
129+
}
130+
]
131+
},
132+
{
133+
"name": "HEAD",
134+
"type": "file",
135+
"encoding": "utf8",
136+
"content": "ref: refs/heads/main\n"
137+
},
138+
{
139+
"name": "config",
140+
"type": "file",
141+
"encoding": "utf8",
142+
"content": "[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = true\n\tlogallrefupdates = true\n\tsymlinks = false\n\tignorecase = true\n"
143+
}
144+
]
145+
}
146+
]

0 commit comments

Comments
 (0)