Skip to content

Commit 37b66d9

Browse files
committed
display all authors
1 parent a78953c commit 37b66d9

File tree

8 files changed

+144
-16
lines changed

8 files changed

+144
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
coverage
22
media
33
node_modules
4+
node_modules_
45
out
56
*.vsix

src/dataSource.ts

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as vscode from 'vscode';
66
import { AskpassEnvironment, AskpassManager } from './askpass/askpassManager';
77
import { getConfig } from './config';
88
import { Logger } from './logger';
9-
import { CommitOrdering, DateType, DeepWriteable, ErrorInfo, ErrorInfoExtensionPrefix, GitCommit, GitCommitDetails, GitCommitStash, GitConfigLocation, GitFileChange, GitFileStatus, GitPushBranchMode, GitRepoConfig, GitRepoConfigBranches, GitResetMode, GitSignature, GitSignatureStatus, GitStash, GitTagDetails, MergeActionOn, RebaseActionOn, SquashMessageFormat, TagType, Writeable } from './types';
9+
import {ActionedUser, CommitOrdering, DateType, DeepWriteable, ErrorInfo, ErrorInfoExtensionPrefix, GitCommit, GitCommitDetails, GitCommitStash, GitConfigLocation, GitFileChange, GitFileStatus, GitPushBranchMode, GitRepoConfig, GitRepoConfigBranches, GitResetMode, GitSignature, GitSignatureStatus, GitStash, GitTagDetails, MergeActionOn, RebaseActionOn, SquashMessageFormat, TagType, Writeable } from './types';
1010
import { GitExecutable, GitVersionRequirement, UNABLE_TO_FIND_GIT_MSG, UNCOMMITTED, abbrevCommit, constructIncompatibleGitVersionMessage, doesVersionMeetRequirement, getPathFromStr, getPathFromUri, openGitTerminal, pathWithTrailingSlash, realpath, resolveSpawnOutput, showErrorMessage } from './utils';
1111
import { Disposable } from './utils/disposable';
1212
import { Event } from './utils/event';
@@ -140,12 +140,12 @@ export class DataSource extends Disposable {
140140
this.getRemotes(repo),
141141
showStashes ? this.getStashes(repo) : Promise.resolve([])
142142
]).then((results) => {
143+
/* eslint no-console: "error" */
143144
return { branches: results[0].branches, head: results[0].head, remotes: results[1], stashes: results[2], error: null };
144145
}).catch((errorMessage) => {
145146
return { branches: [], head: null, remotes: [], stashes: [], error: errorMessage };
146147
});
147148
}
148-
149149
/**
150150
* Get the commits in a repository.
151151
* @param repo The path of the repository.
@@ -282,11 +282,14 @@ export class DataSource extends Disposable {
282282
return Promise.all([
283283
this.getConfigList(repo),
284284
this.getConfigList(repo, GitConfigLocation.Local),
285-
this.getConfigList(repo, GitConfigLocation.Global)
285+
this.getConfigList(repo, GitConfigLocation.Global),
286+
this.getAuthorList(repo)
286287
]).then((results) => {
287-
const consolidatedConfigs = results[0], localConfigs = results[1], globalConfigs = results[2];
288+
const consolidatedConfigs = results[0], localConfigs = results[1], globalConfigs = results[2], authors = results[3];
288289

289290
const branches: GitRepoConfigBranches = {};
291+
// const authors:ReadonlyArray<GitRepoConfigAuthor> = [];
292+
console.warn(authors);
290293
Object.keys(localConfigs).forEach((key) => {
291294
if (key.startsWith('branch.')) {
292295
if (key.endsWith('.remote')) {
@@ -304,10 +307,34 @@ export class DataSource extends Disposable {
304307
}
305308
}
306309
});
307-
310+
console.warn({config: {
311+
branches: branches,
312+
authors,
313+
diffTool: getConfigValue(consolidatedConfigs, GitConfigKey.DiffTool),
314+
guiDiffTool: getConfigValue(consolidatedConfigs, GitConfigKey.DiffGuiTool),
315+
pushDefault: getConfigValue(consolidatedConfigs, GitConfigKey.RemotePushDefault),
316+
remotes: remotes.map((remote) => ({
317+
name: remote,
318+
url: getConfigValue(localConfigs, 'remote.' + remote + '.url'),
319+
pushUrl: getConfigValue(localConfigs, 'remote.' + remote + '.pushurl')
320+
})),
321+
user: {
322+
name: {
323+
local: getConfigValue(localConfigs, GitConfigKey.UserName),
324+
global: getConfigValue(globalConfigs, GitConfigKey.UserName)
325+
},
326+
email: {
327+
local: getConfigValue(localConfigs, GitConfigKey.UserEmail),
328+
global: getConfigValue(globalConfigs, GitConfigKey.UserEmail)
329+
}
330+
}
331+
},
332+
error: null
333+
});
308334
return {
309335
config: {
310336
branches: branches,
337+
authors,
311338
diffTool: getConfigValue(consolidatedConfigs, GitConfigKey.DiffTool),
312339
guiDiffTool: getConfigValue(consolidatedConfigs, GitConfigKey.DiffGuiTool),
313340
pushDefault: getConfigValue(consolidatedConfigs, GitConfigKey.RemotePushDefault),
@@ -330,11 +357,58 @@ export class DataSource extends Disposable {
330357
error: null
331358
};
332359
}).catch((errorMessage) => {
360+
console.log(errorMessage);
333361
return { config: null, error: errorMessage };
334362
});
335363
}
336364

337-
365+
private async getAuthorList(repo: string): Promise<ActionedUser[]> {
366+
const args = ['shortlog', '-e', '-s', '-n', 'HEAD'];
367+
const dict = new Set<string>();
368+
const result = await this.spawnGit(args, repo, (authors) => {
369+
return authors.split(/\r?\n/g)
370+
.map(line => line.trim())
371+
.filter(line => line.trim().length > 0)
372+
.map(line => line.substring(line.indexOf('\t') + 1))
373+
.map(line => {
374+
const indexOfEmailSeparator = line.indexOf('<');
375+
if (indexOfEmailSeparator === -1) {
376+
return {
377+
name: line.trim(),
378+
email: ''
379+
};
380+
} else {
381+
const nameParts = line.split('<');
382+
const name = nameParts.shift()!.trim();
383+
const email = nameParts[0].substring(0, nameParts[0].length - 1).trim();
384+
return {
385+
name,
386+
email
387+
};
388+
}
389+
})
390+
.filter(item => {
391+
if (dict.has(item.name)) {
392+
return false;
393+
}
394+
dict.add(item.name);
395+
return true;
396+
})
397+
.sort((a, b) => (a.name > b.name ? 1 : -1));
398+
}).catch((errorMessage) => {
399+
if (typeof errorMessage === 'string') {
400+
const message = errorMessage.toLowerCase();
401+
if (message.startsWith('fatal: unable to read config file') && message.endsWith('no such file or directory')) {
402+
// If the Git command failed due to the configuration file not existing, return an empty list instead of throwing the exception
403+
return {};
404+
}
405+
} else {
406+
errorMessage = 'An unexpected error occurred while spawning the Git child process.';
407+
}
408+
throw errorMessage;
409+
}) as Promise<ActionedUser[]>;
410+
return result;
411+
}
338412
/* Get Data Methods - Commit Details View */
339413

340414
/**

src/gitGraphView.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,8 @@ export class GitGraphView extends Disposable {
722722
<div id="controls"${stickyClassAttr}>
723723
<span id="repoControl"><span class="unselectable">Repo: </span><div id="repoDropdown" class="dropdown"></div></span>
724724
<span id="branchControl"><span class="unselectable">Branches: </span><div id="branchDropdown" class="dropdown"></div></span>
725+
<span id="authorControl"><span class="unselectable">Authors: </span><div id="authorDropdown" class="dropdown"></div></span>
726+
725727
<label id="showRemoteBranchesControl"><input type="checkbox" id="showRemoteBranchesCheckbox" tabindex="-1"><span class="customCheckbox"></span>Show Remote Branches</label>
726728
<div id="findBtn" title="Find"></div>
727729
<div id="terminalBtn" title="Open a Terminal for this Repository"></div>

src/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export const enum GitPushBranchMode {
8989

9090
export interface GitRepoConfig {
9191
readonly branches: GitRepoConfigBranches;
92+
readonly authors: ActionedUser[];
9293
readonly diffTool: string | null;
9394
readonly guiDiffTool: string | null;
9495
readonly pushDefault: string | null;
@@ -106,7 +107,10 @@ export interface GitRepoConfig {
106107
}
107108

108109
export type GitRepoConfigBranches = { [branchName: string]: GitRepoConfigBranch };
109-
110+
export interface ActionedUser{
111+
name: string;
112+
email: string;
113+
};
110114
export interface GitRepoConfigBranch {
111115
readonly pushRemote: string | null;
112116
readonly remote: string | null;

web/dropdown.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,17 @@ class Dropdown {
9494
* @param options An array of the options to display in the dropdown.
9595
* @param optionsSelected An array of the selected options in the dropdown.
9696
*/
97-
public setOptions(options: ReadonlyArray<DropdownOption>, optionsSelected: string[]) {
97+
public setOptions(options: ReadonlyArray<DropdownOption>, optionsSelected: string[]|null) {
9898
this.options = options;
9999
this.optionsSelected = [];
100100
let selectedOption = -1, isSelected;
101-
for (let i = 0; i < options.length; i++) {
102-
isSelected = optionsSelected.includes(options[i].value);
103-
this.optionsSelected[i] = isSelected;
104-
if (isSelected) {
105-
selectedOption = i;
101+
if(optionsSelected) {
102+
for (let i = 0; i < options.length; i++) {
103+
isSelected = optionsSelected.includes(options[i].value);
104+
this.optionsSelected[i] = isSelected;
105+
if (isSelected) {
106+
selectedOption = i;
107+
}
106108
}
107109
}
108110
if (selectedOption === -1) {

web/global.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ declare global {
5858
readonly commitHead: string | null;
5959
readonly avatars: AvatarImageCollection;
6060
readonly currentBranches: string[] | null;
61+
readonly currentAuthors: string[] | null;
6162
readonly moreCommitsAvailable: boolean;
6263
readonly maxCommits: number;
6364
readonly onlyFollowFirstParent: boolean;

web/main.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
class GitGraphView {
23
private gitRepos: GG.GitRepoSet;
34
private gitBranches: ReadonlyArray<string> = [];
@@ -12,6 +13,7 @@ class GitGraphView {
1213
private onlyFollowFirstParent: boolean = false;
1314
private avatars: AvatarImageCollection = {};
1415
private currentBranches: string[] | null = null;
16+
private currentAuthors: string[] | null = null;
1517

1618
private currentRepo!: string;
1719
private currentRepoLoading: boolean = true;
@@ -45,6 +47,7 @@ class GitGraphView {
4547
private readonly settingsWidget: SettingsWidget;
4648
private readonly repoDropdown: Dropdown;
4749
private readonly branchDropdown: Dropdown;
50+
private readonly authorDropdown: Dropdown;
4851

4952
private readonly viewElem: HTMLElement;
5053
private readonly controlsElem: HTMLElement;
@@ -92,7 +95,13 @@ class GitGraphView {
9295
this.clearCommits();
9396
this.requestLoadRepoInfoAndCommits(true, true);
9497
});
95-
98+
this.authorDropdown = new Dropdown('authorDropdown', false, true, 'Authors', (values) => {
99+
this.currentAuthors = values;
100+
this.maxCommits = this.config.initialLoadCommits;
101+
this.saveState();
102+
this.clearCommits();
103+
this.requestLoadRepoInfoAndCommits(true, true);
104+
});
96105
this.showRemoteBranchesElem = <HTMLInputElement>document.getElementById('showRemoteBranchesCheckbox')!;
97106
this.showRemoteBranchesElem.addEventListener('change', () => {
98107
this.saveRepoStateValue(this.currentRepo, 'showRemoteBranchesV2', this.showRemoteBranchesElem.checked ? GG.BooleanOverride.Enabled : GG.BooleanOverride.Disabled);
@@ -123,6 +132,7 @@ class GitGraphView {
123132
if (prevState && !prevState.currentRepoLoading && typeof this.gitRepos[prevState.currentRepo] !== 'undefined') {
124133
this.currentRepo = prevState.currentRepo;
125134
this.currentBranches = prevState.currentBranches;
135+
this.currentAuthors = prevState.currentAuthors;
126136
this.maxCommits = prevState.maxCommits;
127137
this.expandedCommit = prevState.expandedCommit;
128138
this.avatars = prevState.avatars;
@@ -207,6 +217,7 @@ class GitGraphView {
207217
}
208218

209219
private loadRepo(repo: string) {
220+
console.warn('loadRepro');
210221
this.currentRepo = repo;
211222
this.currentRepoLoading = true;
212223
this.showRemoteBranchesElem.checked = getShowRemoteBranches(this.gitRepos[this.currentRepo].showRemoteBranchesV2);
@@ -216,6 +227,7 @@ class GitGraphView {
216227
this.gitStashes = [];
217228
this.gitTags = [];
218229
this.currentBranches = null;
230+
this.currentAuthors = null;
219231
this.renderFetchButton();
220232
this.closeCommitDetails(false);
221233
this.settingsWidget.close();
@@ -270,10 +282,22 @@ class GitGraphView {
270282
}
271283
}
272284

285+
// Configure current branches
286+
if (this.currentBranches !== null && !(this.currentBranches.length === 1 && this.currentBranches[0] === SHOW_ALL_BRANCHES)) {
287+
// Filter any branches that are currently selected, but no longer exist
288+
const globPatterns = this.config.customBranchGlobPatterns.map((pattern) => pattern.glob);
289+
this.currentBranches = this.currentBranches.filter((branch) =>
290+
this.gitBranches.includes(branch) || globPatterns.includes(branch)
291+
);
292+
}
273293
this.saveState();
294+
this.currentAuthors = [];
295+
this.currentAuthors.push(SHOW_ALL_BRANCHES);
274296

275297
// Set up branch dropdown options
276298
this.branchDropdown.setOptions(this.getBranchOptions(true), this.currentBranches);
299+
console.warn('test2');
300+
this.authorDropdown.setOptions(this.getAuthorOptions(), this.currentAuthors);
277301

278302
// Remove hidden remotes that no longer exist
279303
let hiddenRemotes = this.gitRepos[this.currentRepo].hideRemotes;
@@ -496,6 +520,7 @@ class GitGraphView {
496520
this.renderCdvExternalDiffBtn();
497521
}
498522
this.settingsWidget.refresh();
523+
this.authorDropdown.setOptions(this.getAuthorOptions(), this.currentAuthors);
499524
}
500525

501526
private displayLoadDataError(message: string, reason: string) {
@@ -539,7 +564,17 @@ class GitGraphView {
539564
}
540565
return options;
541566
}
542-
567+
public getAuthorOptions(): ReadonlyArray<DialogSelectInputOption> {
568+
const options: DialogSelectInputOption[] = [];
569+
options.push({ name: 'All', value: SHOW_ALL_BRANCHES });
570+
if(this.gitConfig && this.gitConfig.authors) {
571+
for (let i = 0; i < this!.gitConfig!.authors.length; i++) {
572+
const author = this!.gitConfig!.authors[i];
573+
options.push({ name: author.name, value: author.name });
574+
}
575+
}
576+
return options;
577+
}
543578
public getCommitId(hash: string) {
544579
return typeof this.commitLookup[hash] === 'number' ? this.commitLookup[hash] : null;
545580
}
@@ -611,6 +646,7 @@ class GitGraphView {
611646
repo: this.currentRepo,
612647
refreshId: ++this.currentRepoRefreshState.loadCommitsRefreshId,
613648
branches: this.currentBranches === null || (this.currentBranches.length === 1 && this.currentBranches[0] === SHOW_ALL_BRANCHES) ? null : this.currentBranches,
649+
// authors: this.currentBranches === null || (this.currentBranches.length === 1 && this.currentBranches[0] === SHOW_ALL_BRANCHES) ? null : this.currentBranches,
614650
maxCommits: this.maxCommits,
615651
showTags: getShowTags(repoState.showTags),
616652
showRemoteBranches: getShowRemoteBranches(repoState.showRemoteBranchesV2),
@@ -724,6 +760,7 @@ class GitGraphView {
724760
commitHead: this.commitHead,
725761
avatars: this.avatars,
726762
currentBranches: this.currentBranches,
763+
currentAuthors: this.currentAuthors,
727764
moreCommitsAvailable: this.moreCommitsAvailable,
728765
maxCommits: this.maxCommits,
729766
onlyFollowFirstParent: this.onlyFollowFirstParent,
@@ -979,6 +1016,8 @@ class GitGraphView {
9791016
private getBranchContextMenuActions(target: DialogTarget & RefTarget): ContextMenuActions {
9801017
const refName = target.ref, visibility = this.config.contextMenuActionsVisibility.branch;
9811018
const isSelectedInBranchesDropdown = this.branchDropdown.isSelected(refName);
1019+
// const isSelectedInBranchesDropdown = this.authorDropdown.isSelected(refName);
1020+
9821021
return [[
9831022
{
9841023
title: 'Checkout Branch',
@@ -2010,6 +2049,8 @@ class GitGraphView {
20102049
editorFontFamily = eff;
20112050
this.repoDropdown.refresh();
20122051
this.branchDropdown.refresh();
2052+
this.authorDropdown.refresh();
2053+
20132054
}
20142055
if (fmc !== findMatchColour) {
20152056
findMatchColour = fmc;
@@ -2125,6 +2166,9 @@ class GitGraphView {
21252166
} else if (this.branchDropdown.isOpen()) {
21262167
this.branchDropdown.close();
21272168
handledEvent(e);
2169+
} else if (this.authorDropdown.isOpen()) {
2170+
this.authorDropdown.close();
2171+
handledEvent(e);
21282172
} else if (this.settingsWidget.isVisible()) {
21292173
this.settingsWidget.close();
21302174
handledEvent(e);

web/styles/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ body.tagLabelsRightAligned .gitRef.tag{
809809
white-space:nowrap;
810810
margin:0 10px;
811811
}
812-
#repoDropdown, #branchDropdown{
812+
#repoDropdown, #branchDropdown #authorDropdown{
813813
margin-left:3px;
814814
}
815815
#showRemoteBranchesControl > .customCheckbox{

0 commit comments

Comments
 (0)