fix: run git remote prune origin before updating (#1717)

Co-authored-by: Felix Angelov <felix@shorebird.dev>
This commit is contained in:
Eric Seidel
2024-02-07 16:29:56 -08:00
committed by GitHub
parent 2aea14c95e
commit c3911cd055
4 changed files with 84 additions and 0 deletions
@@ -87,6 +87,29 @@ class Git {
}
}
/// Run `git remote` at [directory].
// TODO(eseidel): add a generic `git` method for running arbitrary git
// commands and removing duplication between these methods.
Future<void> remote({
required String directory,
List<String>? args,
}) async {
final arguments = ['remote', ...?args];
final result = await process.run(
executable,
arguments,
workingDirectory: directory,
);
if (result.exitCode != 0) {
throw ProcessException(
executable,
arguments,
'${result.stderr}',
result.exitCode,
);
}
}
/// Iterate over all refs that match [pattern] and show them
/// according to the given [format].
Future<String> forEachRef({
@@ -28,6 +28,9 @@ class ShorebirdVersion {
///
/// Exits if HEAD isn't pointing to a branch, or there is no upstream.
Future<String> fetchLatestGitHash() async {
// Dependabot pushed branches with the same name breaking all clients
// and requiring a prune to repair them.
await git.remote(directory: _workingDirectory, args: ['prune', 'origin']);
// Fetch upstream branch's commits and tags
await git.fetch(directory: _workingDirectory, args: ['--tags']);
// Get the latest commit revision of the upstream
@@ -328,6 +328,58 @@ origin/flutter_release/3.10.6''';
});
});
group('remote', () {
const directory = './output';
test('executes correct command', () async {
await expectLater(
runWithOverrides(
() => git.remote(directory: directory),
),
completes,
);
verify(
() => process.run(
'git',
['remote'],
workingDirectory: directory,
),
).called(1);
});
test('executes correct command w/args', () async {
const args = ['prune', 'origin'];
await expectLater(
runWithOverrides(
() => git.remote(
directory: directory,
args: args,
),
),
completes,
);
verify(
() => process.run(
'git',
['remote', ...args],
workingDirectory: directory,
),
).called(1);
});
test('throws ProcessException if process exits with error', () async {
const error = 'oops';
when(() => processResult.exitCode).thenReturn(ExitCode.software.code);
when(() => processResult.stderr).thenReturn(error);
expect(
() => runWithOverrides(() => git.remote(directory: directory)),
throwsA(
isA<ProcessException>().having((e) => e.message, 'message', error),
),
);
});
});
group('revParse', () {
const directory = './output';
const revision = 'revision';
@@ -36,6 +36,12 @@ void main() {
args: any(named: 'args'),
),
).thenAnswer((_) async => {});
when(
() => git.remote(
directory: any(named: 'directory'),
args: any(named: 'args'),
),
).thenAnswer((_) async => {});
when(
() => git.revParse(
revision: any(named: 'revision'),