Skip to content

Commit

Permalink
#407 Hide Remote Head Symbolic References via a new extension setting.
Browse files Browse the repository at this point in the history
  • Loading branch information
wilkmaciej authored and mhutchie committed Nov 15, 2020
1 parent 2b88194 commit b7b9183
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 9 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,11 @@
"default": true,
"description": "Show Remote Branches in Git Graph by default. This can be overridden per repository from the Git Graph View's Control Bar."
},
"git-graph.repository.showRemoteHeads": {
"type": "boolean",
"default": true,
"description": "Show Remote HEAD Symbolic References in Git Graph (e.g. \"origin/HEAD\")."
},
"git-graph.repository.showTags": {
"type": "boolean",
"default": true,
Expand Down
7 changes: 7 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,13 @@ class Config {
return !!this.config.get('repository.showRemoteBranches', true);
}

/**
* Get the value of the `git-graph.repository.showRemoteHeads` Extension Setting.
*/
get showRemoteHeads() {
return !!this.config.get('repository.showRemoteHeads', true);
}

/**
* Get the value of the `git-graph.repository.showTags` Extension Setting.
*/
Expand Down
19 changes: 12 additions & 7 deletions src/dataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { Event } from './utils/event';

const DRIVE_LETTER_PATH_REGEX = /^[a-z]:\//;
const EOL_REGEX = /\r\n|\r|\n/g;
const INVALID_BRANCH_REGEX = /^\(.* .*\)$/;
const INVALID_BRANCH_REGEXP = /^\(.* .*\)$/;
const REMOTE_HEAD_BRANCH_REGEXP = /^remotes\/.*\/HEAD$/;
const GIT_LOG_SEPARATOR = 'XX7Nal-YARtTpjCikii9nJxER19D6diSyk-AWkPb';

export const GIT_CONFIG_USER_NAME = 'user.name';
Expand Down Expand Up @@ -149,7 +150,7 @@ export class DataSource extends Disposable {
const config = getConfig();
return Promise.all([
this.getLog(repo, branches, maxCommits + 1, showTags && config.showCommitsOnlyReferencedByTags, showRemoteBranches, includeCommitsMentionedByReflogs, onlyFollowFirstParent, commitOrdering, remotes, hideRemotes, stashes),
this.getRefs(repo, showRemoteBranches, hideRemotes).then((refData: GitRefData) => refData, (errorMessage: string) => errorMessage)
this.getRefs(repo, showRemoteBranches, config.showRemoteHeads, hideRemotes).then((refData: GitRefData) => refData, (errorMessage: string) => errorMessage)
]).then(async (results) => {
let commits: GitCommitRecord[] = results[0], refData: GitRefData | string = results[1], i;
let moreCommitsAvailable = commits.length === maxCommits + 1;
Expand Down Expand Up @@ -1151,14 +1152,17 @@ export class DataSource extends Disposable {
if (showRemoteBranches) args.push('-a');
args.push('--no-color');

let hideRemotePatterns = hideRemotes.map((remote) => 'remotes/' + remote + '/');
const hideRemotePatterns = hideRemotes.map((remote) => 'remotes/' + remote + '/');
const showRemoteHeads = getConfig().showRemoteHeads;

return this.spawnGit(args, repo, (stdout) => {
let branchData: GitBranchData = { branches: [], head: null, error: null };
let lines = stdout.split(EOL_REGEX);
for (let i = 0; i < lines.length - 1; i++) {
let name = lines[i].substring(2).split(' -> ')[0];
if (INVALID_BRANCH_REGEX.test(name) || hideRemotePatterns.some((pattern) => name.startsWith(pattern))) continue;
if (INVALID_BRANCH_REGEXP.test(name) || hideRemotePatterns.some((pattern) => name.startsWith(pattern)) || (!showRemoteHeads && REMOTE_HEAD_BRANCH_REGEXP.test(name))) {
continue;
}

if (lines[i][0] === '*') {
branchData.head = name;
Expand Down Expand Up @@ -1338,15 +1342,16 @@ export class DataSource extends Disposable {
* Get the references in a repository.
* @param repo The path of the repository.
* @param showRemoteBranches Are remote branches shown.
* @param showRemoteHeads Are remote heads shown.
* @param hideRemotes An array of hidden remotes.
* @returns The references data.
*/
private getRefs(repo: string, showRemoteBranches: boolean, hideRemotes: ReadonlyArray<string>) {
private getRefs(repo: string, showRemoteBranches: boolean, showRemoteHeads: boolean, hideRemotes: ReadonlyArray<string>) {
let args = ['show-ref'];
if (!showRemoteBranches) args.push('--heads', '--tags');
args.push('-d', '--head');

let hideRemotePatterns = hideRemotes.map((remote) => 'refs/remotes/' + remote + '/');
const hideRemotePatterns = hideRemotes.map((remote) => 'refs/remotes/' + remote + '/');

return this.spawnGit(args, repo, (stdout) => {
let refData: GitRefData = { head: null, heads: [], tags: [], remotes: [] };
Expand All @@ -1364,7 +1369,7 @@ export class DataSource extends Disposable {
let annotated = ref.endsWith('^{}');
refData.tags.push({ hash: hash, name: (annotated ? ref.substring(10, ref.length - 3) : ref.substring(10)), annotated: annotated });
} else if (ref.startsWith('refs/remotes/')) {
if (!hideRemotePatterns.some((pattern) => ref.startsWith(pattern))) {
if (!hideRemotePatterns.some((pattern) => ref.startsWith(pattern)) && (showRemoteHeads || !ref.endsWith('/HEAD'))) {
refData.remotes.push({ hash: hash, name: ref.substring(13) });
}
} else if (ref === 'HEAD') {
Expand Down
62 changes: 62 additions & 0 deletions tests/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3248,6 +3248,68 @@ describe('Config', () => {
});
});

describe('showRemoteHeads', () => {
it('Should return TRUE when the configuration value is TRUE', () => {
// Setup
workspaceConfiguration.get.mockReturnValueOnce(true);

// Run
const value = config.showRemoteHeads;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('repository.showRemoteHeads', true);
expect(value).toBe(true);
});

it('Should return FALSE when the configuration value is FALSE', () => {
// Setup
workspaceConfiguration.get.mockReturnValueOnce(false);

// Run
const value = config.showRemoteHeads;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('repository.showRemoteHeads', true);
expect(value).toBe(false);
});

it('Should return TRUE when the configuration value is truthy', () => {
// Setup
workspaceConfiguration.get.mockReturnValueOnce(5);

// Run
const value = config.showRemoteHeads;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('repository.showRemoteHeads', true);
expect(value).toBe(true);
});

it('Should return FALSE when the configuration value is falsy', () => {
// Setup
workspaceConfiguration.get.mockReturnValueOnce(0);

// Run
const value = config.showRemoteHeads;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('repository.showRemoteHeads', true);
expect(value).toBe(false);
});

it('Should return the default value (TRUE) when the configuration value is not set', () => {
// Setup
workspaceConfiguration.get.mockImplementationOnce((_, defaultValue) => defaultValue);

// Run
const value = config.showRemoteHeads;

// Assert
expect(workspaceConfiguration.get).toBeCalledWith('repository.showRemoteHeads', true);
expect(value).toBe(true);
});
});

describe('showTags', () => {
it('Should return TRUE when the configuration value is TRUE', () => {
// Setup
Expand Down

0 comments on commit b7b9183

Please sign in to comment.