mirror of
https://github.com/flutter/flutter
synced 2024-10-03 06:54:10 +00:00
104 lines
4.2 KiB
Dart
104 lines
4.2 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// This script looks at the current commit and branch of the git repository in
|
|
// which it was run, and finds the contemporary commit in the master branch of
|
|
// another git repository, whose path is provided on the command line. The
|
|
// contemporary commit is the one that was public at the time of the last commit
|
|
// on the master branch before the current commit's branch was created.
|
|
|
|
import 'dart:io';
|
|
|
|
const bool debugLogging = false;
|
|
|
|
void log(String message) {
|
|
if (debugLogging)
|
|
print(message);
|
|
}
|
|
|
|
class Commit {
|
|
Commit(this.hash, this.timestamp);
|
|
|
|
final String hash;
|
|
final DateTime timestamp;
|
|
|
|
static String formatArgument = '--format=%H %cI';
|
|
|
|
static Commit parse(String line) {
|
|
final int space = line.indexOf(' ');
|
|
return Commit(line.substring(0, space), DateTime.parse(line.substring(space+1, line.length).trimRight()));
|
|
}
|
|
|
|
static List<Commit> parseList(String lines) {
|
|
return lines.split('\n').where((String line) => line.isNotEmpty).map(parse).toList().reversed.toList();
|
|
}
|
|
}
|
|
|
|
String findCommit({
|
|
required String primaryRepoDirectory,
|
|
required String primaryBranch,
|
|
required String primaryTrunk,
|
|
required String secondaryRepoDirectory,
|
|
required String secondaryBranch,
|
|
}) {
|
|
final Commit anchor;
|
|
if (primaryBranch == primaryTrunk) {
|
|
log('on $primaryTrunk, using last commit as anchor');
|
|
anchor = Commit.parse(git(primaryRepoDirectory, <String>['log', Commit.formatArgument, '--max-count=1', primaryBranch, '--']));
|
|
} else {
|
|
final List<Commit> branchCommits = Commit.parseList(git(primaryRepoDirectory, <String>['log', Commit.formatArgument, primaryBranch, '--']));
|
|
final List<Commit> trunkCommits = Commit.parseList(git(primaryRepoDirectory, <String>['log', Commit.formatArgument, primaryTrunk, '--']));
|
|
if (branchCommits.isEmpty || trunkCommits.isEmpty || branchCommits.first.hash != trunkCommits.first.hash)
|
|
throw StateError('Branch $primaryBranch does not seem to have a common history with trunk $primaryTrunk.');
|
|
if (branchCommits.last.hash == trunkCommits.last.hash) {
|
|
log('$primaryBranch is even with $primaryTrunk, using last commit as anchor');
|
|
anchor = trunkCommits.last;
|
|
} else {
|
|
int index = 0;
|
|
while (branchCommits.length > index && trunkCommits.length > index && branchCommits[index].hash == trunkCommits[index].hash)
|
|
index += 1;
|
|
log('$primaryBranch branched from $primaryTrunk ${branchCommits.length - index} commits ago, trunk has advanced by ${trunkCommits.length - index} commits since then.');
|
|
anchor = trunkCommits[index - 1];
|
|
}
|
|
}
|
|
return git(secondaryRepoDirectory, <String>[
|
|
'log',
|
|
'--format=%H',
|
|
'--until=${anchor.timestamp.toIso8601String()}',
|
|
'--max-count=1',
|
|
secondaryBranch,
|
|
'--',
|
|
]);
|
|
}
|
|
|
|
String git(String workingDirectory, List<String> arguments) {
|
|
final ProcessResult result = Process.runSync('git', arguments, workingDirectory: workingDirectory);
|
|
if (result.exitCode != 0 || '${result.stderr}'.isNotEmpty)
|
|
throw ProcessException('git', arguments, '${result.stdout}${result.stderr}', result.exitCode);
|
|
return '${result.stdout}';
|
|
}
|
|
|
|
void main(List<String> arguments) {
|
|
if (arguments.isEmpty || arguments.length > 2 || arguments.contains('--help') || arguments.contains('-h')) {
|
|
print(
|
|
'Usage: dart find_commit.dart [<path-to-primary-repo>] <path-to-secondary-repo>\n'
|
|
'This script will find the commit in the secondary repo that was contemporary\n'
|
|
'when the commit in the primary repo was created. If that commit is on a\n'
|
|
"branch, then the date of the branch's creation is used instead.\n"
|
|
'If <path-to-primary-repo> is omitted, the current directory is used for the\n'
|
|
'primary repo.'
|
|
);
|
|
} else {
|
|
final String primaryRepo = arguments.length == 1 ? '.' : arguments.first;
|
|
final String secondaryRepo = arguments.last;
|
|
print(findCommit(
|
|
primaryRepoDirectory: primaryRepo,
|
|
primaryBranch: git(primaryRepo, <String>['rev-parse', '--abbrev-ref', 'HEAD']).trim(),
|
|
primaryTrunk: 'master',
|
|
secondaryRepoDirectory: secondaryRepo,
|
|
secondaryBranch: 'master',
|
|
).trim());
|
|
}
|
|
}
|