run method
Runs this command.
The return value is wrapped in a Future
if necessary and returned by
CommandRunner.runCommand
.
Implementation
@override
Future run() async {
var gitRootDir = GitRepository.findRootDir(Directory.current.path)!;
var repo = await GitRepository.load(gitRootDir);
var showAll = argResults!['all'] as bool?;
var delete = argResults!['delete'] as bool?;
var hasNoArgs = argResults!['set-upstream-to'] == null && delete == false;
if (hasNoArgs) {
if (argResults!.rest.isEmpty) {
var head = await repo.head();
if (head == null) {
print('fatal: no head');
return;
}
if (head.isHash) {
print('* (HEAD detached at ${head.hash!.toOid()})');
}
var branches = await repo.branches();
branches.sort();
for (var branch in branches) {
if (head.isSymbolic && head.target!.branchName() == branch) {
print('* ${head.target!.branchName()}');
continue;
}
print(' $branch');
}
if (showAll!) {
for (var remote in repo.config.remotes) {
var refs = await repo.remoteBranches(remote.name);
refs.sort((a, b) {
return a.name.branchName()!.compareTo(b.name.branchName()!);
});
for (var ref in refs) {
var branch = ref.name.branchName();
if (ref.isHash) {
print(' remotes/${remote.name}/$branch');
} else {
var tb = ref.target!.branchName();
if (ref.target!.isRemote()) {
tb = '${ref.target!.remoteName()}/$tb';
}
print(' remotes/${remote.name}/$branch -> $tb');
}
}
}
}
return;
} else {
var rest = argResults!.rest;
if (rest.length == 1) {
var name = argResults!.rest.first;
var hash = await repo.createBranch(name);
if (hash == null) {
print("fatal: A branch named '$name' already exists.");
}
} else {
var parts = splitPath(argResults!.rest[1]);
var remoteName = parts.item1;
var remoteBranchName = parts.item2;
var branchName = rest.first;
var refName = ReferenceName.remote(remoteName, remoteBranchName);
var ref = await repo.resolveReferenceName(refName);
if (ref == null) {
print('fatal');
return;
}
assert(ref.isHash);
await repo.createBranch(branchName, hash: ref.hash);
var remote = repo.config.remote(remoteName)!;
await repo.setBranchUpstreamTo(branchName, remote, remoteBranchName);
print(
"Branch '$branchName' set up to track remote branch '$remoteBranchName' from '$remoteName'.");
}
return;
}
}
if (delete!) {
if (argResults!.rest.isEmpty) {
print('fatal: branch name required');
return;
}
var branchName = argResults!.rest.first;
var hash = await repo.deleteBranch(branchName);
if (hash == null) {
print("error: branch '$branchName' not found.");
return;
}
print('Deleted branch $branchName (was ${hash.toOid()}).');
return;
}
var upstream = argResults!['set-upstream-to'] as String;
if (!upstream.contains('/')) {
// FIXME: We need to check if a local branch with this name exists!
print("error: the requested upstream branch '$upstream' does not exist");
}
var parts = splitPath(upstream);
var remoteName = parts.item1;
var remoteBranchName = parts.item2;
var remote = repo.config.remote(remoteName);
if (remote == null) {
print("error: the requested upstream branch '$upstream' does not exist");
return;
}
BranchConfig? localBranch;
try {
localBranch = await repo.setUpstreamTo(remote, remoteBranchName);
} catch (e) {
print(e);
}
print(
"Branch '${localBranch!.name}' set up to track remote branch '$remoteBranchName' from '$remoteName'.");
}