Skip to content

Commit 962c359

Browse files
committed
fix(git-node): use stash and detached head for release operations
1 parent 63171d7 commit 962c359

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

components/git/release.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ReleasePreparation from '../../lib/prepare_release.js';
44
import ReleasePromotion from '../../lib/promote_release.js';
55
import TeamInfo from '../../lib/team_info.js';
66
import Request from '../../lib/request.js';
7-
import { runPromise } from '../../lib/run.js';
7+
import { forceRunAsync, runPromise } from '../../lib/run.js';
88

99
export const command = 'release [prid..]';
1010
export const describe = 'Manage an in-progress release or start a new one.';
@@ -114,14 +114,31 @@ function release(state, argv) {
114114
cli.setAssumeYes();
115115
}
116116

117-
return runPromise(main(state, argv, cli, dir)).catch((err) => {
117+
return runPromise(wrapStash(() => main(state, argv, cli, dir))).catch((err) => {
118118
if (cli.spinner.enabled) {
119119
cli.spinner.fail();
120120
}
121121
throw err;
122122
});
123123
}
124124

125+
async function wrapStash(fn) {
126+
let stashed = false;
127+
try {
128+
await forceRunAsync('git', ['--no-pager', 'diff', '--exit-code'], { ignoreFailure: false });
129+
} catch {
130+
await forceRunAsync('git', ['stash', '--include-untracked'], { ignoreFailure: false });
131+
stashed = true;
132+
}
133+
try {
134+
await fn();
135+
} finally {
136+
if (stashed) {
137+
await forceRunAsync('git', ['stash', 'pop'], { ignoreFailure: false });
138+
}
139+
}
140+
}
141+
125142
async function main(state, argv, cli, dir) {
126143
if (state === PREPARE) {
127144
const release = new ReleasePreparation(argv, cli, dir);

lib/promote_release.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,12 @@ export default class ReleasePromotion extends Session {
5656
cli.warn('Current HEAD is not the release commit');
5757
localCloneIsClean = false;
5858
}
59-
try {
60-
await forceRunAsync('git', ['--no-pager', 'diff', '--exit-code'], { ignoreFailure: false });
61-
} catch {
62-
cli.warn('Some local changes have not been committed');
63-
localCloneIsClean = false;
64-
}
6559
if (!localCloneIsClean) {
66-
if (await cli.prompt('Should we reset the local HEAD to be the release proposal?')) {
60+
if (await cli.prompt('Should we checkout the release proposal?')) {
6761
cli.startSpinner('Fetching the proposal upstream...');
6862
await forceRunAsync('git', ['fetch', proposalUpstreamRemote, releaseCommitSha],
6963
{ ignoreFailure: false });
70-
await forceRunAsync('git', ['reset', releaseCommitSha, '--hard'], { ignoreFailure: false });
64+
await forceRunAsync('git', ['checkout', releaseCommitSha], { ignoreFailure: false });
7165
cli.stopSpinner('Local HEAD is now in sync with the proposal');
7266
} else {
7367
cli.error('Local clone is not ready');

0 commit comments

Comments
 (0)