This commit is contained in:
João Moreno 2020-11-09 14:23:24 +01:00
parent 147f623629
commit dd97a9d335
3 changed files with 60 additions and 29 deletions

View file

@ -1662,10 +1662,27 @@
"scope": "resource"
},
"git.checkoutType": {
"type": "string",
"type": "array",
"items": {
"type": "string",
"enum": [
"local",
"tags",
"remote"
],
"enumDescriptions": [
"%config.checkoutType.local%",
"%config.checkoutType.tags%",
"%config.checkoutType.remote%"
]
},
"uniqueItems": true,
"markdownDescription": "%config.checkoutType%",
"default": "local,remote,tags"
"default": [
"local",
"remote",
"tags"
]
},
"git.ignoreLegacyWarning": {
"type": "boolean",

View file

@ -101,7 +101,10 @@
"config.countBadge.all": "Count all changes.",
"config.countBadge.tracked": "Count only tracked changes.",
"config.countBadge.off": "Turn off counter.",
"config.checkoutType": "Controls what type of branches (local, remote or tags, split with ',') are listed when running `Checkout to...`.",
"config.checkoutType": "Controls what type of git refs are listed when running `Checkout to...`.",
"config.checkoutType.local": "Local branches",
"config.checkoutType.tags": "Tags",
"config.checkoutType.remote": "Remote branches",
"config.branchValidationRegex": "A regular expression to validate new branch names.",
"config.branchWhitespaceChar": "The character to replace whitespace in new branch names.",
"config.ignoreLegacyWarning": "Ignores the legacy Git warning.",

View file

@ -70,11 +70,6 @@ class CheckoutRemoteHeadItem extends CheckoutItem {
}
}
interface RefTypeAndCheckoutItem {
refType: RefType;
checkoutItemCtor: { new(ref: Ref): CheckoutItem; };
}
class BranchDeleteItem implements QuickPickItem {
private get shortCommit(): string { return (this.ref.commit || '').substr(0, 8); }
@ -212,37 +207,53 @@ async function categorizeResourceByResolution(resources: Resource[]): Promise<{
function createCheckoutItems(repository: Repository): CheckoutItem[] {
const config = workspace.getConfiguration('git');
const checkoutTypeString = config.get<string>('checkoutType');
const checkoutTypeConfig = config.get<string | string[]>('checkoutType');
let checkoutTypes: string[];
const checkoutTypeOptions = ['local', 'remote', 'tags'];
const checkoutTypes = checkoutTypeString?.trim().split(',').map(type => type.trim()).filter(type => checkoutTypeOptions.includes(type));
if (checkoutTypeConfig === 'all' || !checkoutTypeConfig || checkoutTypeConfig.length === 0) {
checkoutTypes = ['local', 'remote', 'tags'];
} else if (typeof checkoutTypeConfig === 'string') {
checkoutTypes = [checkoutTypeConfig];
} else {
checkoutTypes = checkoutTypeConfig;
}
const results: CheckoutItem[] = [];
const seens = new Set<string>();
(checkoutTypes && checkoutTypes.length ? checkoutTypes : checkoutTypeOptions).forEach(type => {
if (seens.has(type)) {
return;
const processors = checkoutTypes.map(getCheckoutProcessor)
.filter(p => !!p) as CheckoutProcessor[];
for (const ref of repository.refs) {
for (const processor of processors) {
processor.onRef(ref);
}
seens.add(type);
}
const { refType, checkoutItemCtor } = getRefTypeAndCheckoutItem(type);
results.push(...repository.refs.filter(ref => ref.type === refType).map(ref => new checkoutItemCtor(ref)));
});
return results;
return processors.reduce<CheckoutItem[]>((r, p) => r.concat(...p.items), []);
}
function getRefTypeAndCheckoutItem(type: string): RefTypeAndCheckoutItem {
class CheckoutProcessor {
private refs: Ref[] = [];
get items(): CheckoutItem[] { return this.refs.map(r => new this.ctor(r)); }
constructor(private type: RefType, private ctor: { new(ref: Ref): CheckoutItem }) { }
onRef(ref: Ref): void {
if (ref.type === this.type) {
this.refs.push(ref);
}
}
}
function getCheckoutProcessor(type: string): CheckoutProcessor | undefined {
switch (type) {
case 'local':
return { refType: RefType.Head, checkoutItemCtor: CheckoutItem };
return new CheckoutProcessor(RefType.Head, CheckoutItem);
case 'remote':
return { refType: RefType.RemoteHead, checkoutItemCtor: CheckoutRemoteHeadItem };
return new CheckoutProcessor(RefType.RemoteHead, CheckoutRemoteHeadItem);
case 'tags':
return { refType: RefType.Tag, checkoutItemCtor: CheckoutTagItem };
default:
throw new Error(`Unexpected type: ${type}`);
return new CheckoutProcessor(RefType.Tag, CheckoutTagItem);
}
return undefined;
}
function sanitizeRemoteName(name: string) {