Skip to content

Commit be11c08

Browse files
authored
feat(git-node): improve backport workflow (#732)
Checkout from staging branch and ask to update if needed. Fixes: #731
1 parent d103f28 commit be11c08

File tree

1 file changed

+75
-2
lines changed

1 file changed

+75
-2
lines changed

lib/backport_session.js

+75-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export default class BackportSession extends Session {
6161
cli.stopSpinner(`${file} does not exist in current working tree`,
6262
cli.SPINNER_STATUS.WARN);
6363
continue;
64-
};
64+
}
6565
if (ancestors.length === 0) {
6666
cli.stopSpinner(`Cannot find ancestor commits of ${file}`,
6767
cli.SPINNER_STATUS.INFO);
@@ -155,12 +155,33 @@ export default class BackportSession extends Session {
155155
cli.log(` - ${commit.sha} ${commit.title}`);
156156
}
157157

158+
if (!this.isLocalBranchExists(this.stagingBranch)) {
159+
const shouldCreateStagingBranch = await cli.prompt(
160+
`It seems like ${this.stagingBranch} is missing locally, ` +
161+
'do you want to create it locally to get ready for backporting?', {
162+
defaultAnswer: true
163+
});
164+
165+
if (shouldCreateStagingBranch) {
166+
this.syncBranchWithUpstream(this.stagingBranch);
167+
}
168+
} else if (!this.isBranchUpToDateWithUpstream(this.stagingBranch)) {
169+
const shouldSyncBranch = await cli.prompt(
170+
`It seems like your ${this.stagingBranch} is behind the ${this.upstream} remote` +
171+
'do you want to sync it?', { defaultAnswer: true });
172+
173+
if (shouldSyncBranch) {
174+
this.syncBranchWithUpstream(this.stagingBranch);
175+
}
176+
}
177+
158178
const newBranch = `backport-${this.prid}-to-${this.target}`;
159179
const shouldCheckout = await cli.prompt(
160180
`Do you want to checkout to a new branch \`${newBranch}\`` +
161181
' to start backporting?', { defaultAnswer: false });
182+
162183
if (shouldCheckout) {
163-
await runAsync('git', ['checkout', '-b', newBranch]);
184+
await runAsync('git', ['checkout', '-b', newBranch, this.stagingBranch]);
164185
}
165186

166187
const shouldAnalyze = await cli.prompt(
@@ -226,4 +247,56 @@ export default class BackportSession extends Session {
226247
};
227248
});
228249
}
250+
251+
getCurrentBranch() {
252+
return runSync('git',
253+
['rev-parse', '--abbrev-ref', 'HEAD']
254+
).trim();
255+
}
256+
257+
updateUpstreamRefs(branchName) {
258+
runSync('git',
259+
['fetch', this.upstream, branchName]
260+
);
261+
}
262+
263+
getBranchCommit(branch) {
264+
return runSync('git',
265+
['rev-parse', branch]
266+
).trim();
267+
}
268+
269+
isBranchUpToDateWithUpstream(branch) {
270+
this.updateUpstreamRefs(branch);
271+
272+
const localCommit = this.getBranchCommit(branch);
273+
const upstreamCommit = this.getBranchCommit(`${this.upstream}/${branch}`);
274+
275+
return localCommit === upstreamCommit;
276+
};
277+
278+
isLocalBranchExists(branch) {
279+
try {
280+
// will exit with code 1 if branch does not exist
281+
runSync('git',
282+
['rev-parse', '--verify', '--quiet', branch]
283+
);
284+
return true;
285+
} catch (e) {
286+
return false;
287+
}
288+
}
289+
290+
syncBranchWithUpstream(branch) {
291+
const currentBranch = this.getCurrentBranch();
292+
293+
runSync('git',
294+
[
295+
currentBranch !== branch ? 'fetch' : 'pull',
296+
this.upstream,
297+
`${branch}:${branch}`,
298+
'-f'
299+
]
300+
);
301+
}
229302
}

0 commit comments

Comments
 (0)