Skip to content

Commit b336cc7

Browse files
clydinmgechev
authored andcommitted
fix(@angular/cli): ensure git repository is clean before updates
If not asking for update status then this change checks for a clean git repository before proceeding. This allows the user to easily reset any changes from the update and avoid any developer code changes from being mixed with update changes.
1 parent 635de55 commit b336cc7

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

packages/angular/cli/commands/update-impl.ts

+21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8+
import { execSync } from 'child_process';
89
import * as path from 'path';
910
import * as semver from 'semver';
1011
import { Arguments, Option } from '../models/interface';
@@ -80,6 +81,16 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
8081
return 1;
8182
}
8283

84+
// If not asking for status then check for a clean git repository.
85+
// This allows the user to easily reset any changes from the update.
86+
if ((packages.length !== 0 || options.all) && !this.checkCleanGit()) {
87+
this.logger.error(
88+
'Repository is not clean. Please commit or stash any changes before updating.',
89+
);
90+
91+
return 2;
92+
}
93+
8394
const packageManager = getPackageManager(this.workspace.root);
8495
this.logger.info(`Using package manager: '${packageManager}'`);
8596

@@ -266,4 +277,14 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
266277
},
267278
});
268279
}
280+
281+
checkCleanGit() {
282+
try {
283+
const result = execSync('git status --porcelain', { encoding: 'utf8', stdio: 'pipe' });
284+
285+
return result.trim().length === 0;
286+
} catch {
287+
return true;
288+
}
289+
}
269290
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { appendToFile } from '../../utils/fs';
2+
import { ng } from '../../utils/process';
3+
import { expectToFail } from '../../utils/utils';
4+
5+
export default async function() {
6+
await appendToFile('src/main.ts', 'console.log(\'changed\');\n');
7+
8+
const { message } = await expectToFail(() => ng('update', '--all'));
9+
if (!message || !message.includes('Repository is not clean.')) {
10+
throw new Error('Expected unclean repository');
11+
}
12+
}

0 commit comments

Comments
 (0)