Skip to content

Commit dffe6f4

Browse files
committed
feat(fetch) Add updated/deleted branches to fetch response.
Parses more of the git fetch response, notably updates + deletes. This returns the to/from commit of each branch. When `--prune` is passed, git will also return deleted branches.
1 parent 61d4ee0 commit dffe6f4

File tree

3 files changed

+136
-10
lines changed

3 files changed

+136
-10
lines changed

simple-git/src/lib/parsers/parse-fetch.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,40 @@ const parsers: LineParser<FetchResult>[] = [
55
new LineParser(/From (.+)$/, (result, [remote]) => {
66
result.remote = remote;
77
}),
8-
new LineParser(/\* \[new branch]\s+(\S+)\s*-> (.+)$/, (result, [name, tracking]) =>{
9-
result.branches.push({
10-
name,
11-
tracking,
8+
new LineParser(
9+
/\* \[new branch]\s+(\S+)\s*-> (.+)$/,
10+
(result, [name, tracking]) => {
11+
result.branches.push({
12+
name,
13+
tracking
14+
});
15+
}
16+
),
17+
new LineParser(
18+
/\* \[new tag]\s+(\S+)\s*-> (.+)$/,
19+
(result, [name, tracking]) => {
20+
result.tags.push({
21+
name,
22+
tracking
23+
});
24+
}
25+
),
26+
new LineParser(/- \[deleted]\s+\S+\s*-> (.+)$/, (result, [tracking]) => {
27+
result.deleted.push({
28+
tracking
1229
});
1330
}),
14-
new LineParser(/\* \[new tag]\s+(\S+)\s*-> (.+)$/, (result, [name, tracking]) => {
15-
result.tags.push({
16-
name,
17-
tracking,
18-
});
19-
})
31+
new LineParser(
32+
/\s*([^.]+)\.\.(\S+)\s+(\S+)\s*-> (.+)$/,
33+
(result, [from, to, name, tracking]) => {
34+
result.updated.push({
35+
name,
36+
tracking,
37+
to,
38+
from
39+
});
40+
}
41+
)
2042
];
2143

2244
export function parseFetchResult (stdOut: string, stdErr: string): FetchResult {
@@ -25,6 +47,8 @@ export function parseFetchResult (stdOut: string, stdErr: string): FetchResult {
2547
remote: null,
2648
branches: [],
2749
tags: [],
50+
updated: [],
51+
deleted: []
2852
};
2953
return parseStringResponse(result, parsers, [stdOut, stdErr]);
3054
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// ./simple-git/test/integration/fetch.spec.ts
2+
3+
import {
4+
createTestContext,
5+
newSimpleGit,
6+
setUpInit,
7+
SimpleGitTestContext
8+
} from '../__fixtures__';
9+
10+
describe('fetch', () => {
11+
let context: SimpleGitTestContext;
12+
let upstream: string;
13+
let local: string;
14+
15+
beforeEach(async () => (context = await createTestContext()));
16+
beforeEach(async () => {
17+
upstream = await context.dir('upstream');
18+
local = context.path('local');
19+
await context.file(['upstream', 'file']);
20+
21+
await givenRemote(upstream);
22+
await givenLocal(upstream, local);
23+
});
24+
25+
it('fetches updates', async () => {
26+
const git = newSimpleGit(local);
27+
const bravoPriorHead = await git.revparse('origin/bravo');
28+
await givenRemoteChanges(upstream);
29+
30+
const result = await git.fetch(['--prune']);
31+
32+
const bravoCurrentHead = await git.revparse('origin/bravo');
33+
34+
expect(result).toEqual({
35+
branches: [
36+
{
37+
name: 'delta',
38+
tracking: 'origin/delta'
39+
}
40+
],
41+
deleted: [{ tracking: 'origin/charlie' }],
42+
raw: '',
43+
remote: upstream,
44+
tags: [
45+
{
46+
name: 'alpha',
47+
tracking: 'alpha'
48+
}
49+
],
50+
updated: [
51+
{
52+
from: bravoPriorHead.substring(0, 7),
53+
name: 'bravo',
54+
to: bravoCurrentHead.substring(0, 7),
55+
tracking: 'origin/bravo'
56+
}
57+
]
58+
});
59+
});
60+
61+
/**
62+
* Sets up the repo to be used as a local - by cloning the remote
63+
*/
64+
async function givenLocal(upstream: string, local: string) {
65+
await newSimpleGit(context.root).clone(upstream, local);
66+
await setUpInit({ git: newSimpleGit(local) });
67+
}
68+
69+
/**
70+
* Sets up the repo to be used as a remote
71+
*/
72+
async function givenRemote(upstream: string) {
73+
const git = newSimpleGit(upstream);
74+
await setUpInit({ git });
75+
await git.add('.');
76+
await git.commit('first');
77+
await git.raw('checkout', '-b', 'bravo');
78+
await git.raw('checkout', '-b', 'charlie');
79+
}
80+
/**
81+
* Configure the remote with changes to be retrieved when using fetch on the local
82+
*/
83+
async function givenRemoteChanges(upstream: string) {
84+
const git = newSimpleGit(upstream);
85+
await git.raw('tag', 'alpha');
86+
await git.raw('checkout', 'bravo');
87+
await context.file(['upstream', 'another-file']);
88+
await git.add('.');
89+
await git.commit('second');
90+
await git.raw('checkout', '-b', 'delta');
91+
await git.raw('branch', '-d', 'charlie');
92+
}
93+
});

simple-git/typings/response.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,15 @@ export interface FetchResult {
176176
name: string;
177177
tracking: string;
178178
}[];
179+
updated: {
180+
name: string;
181+
tracking: string;
182+
to: string;
183+
from: string;
184+
}[];
185+
deleted: {
186+
tracking: string;
187+
}[];
179188
}
180189

181190
/** Represents the response to git.grep */

0 commit comments

Comments
 (0)