Browse Source

Adds indicator for all branch tips

main
Eric Amodio 6 years ago
parent
commit
0b351b3d85
6 changed files with 52 additions and 15 deletions
  1. +7
    -0
      CHANGELOG.md
  2. +3
    -4
      src/git/models/branch.ts
  3. +1
    -1
      src/git/parsers/branchParser.ts
  4. +23
    -0
      src/system/array.ts
  5. +12
    -6
      src/views/branchNode.ts
  6. +6
    -4
      src/views/commitNode.ts

+ 7
- 0
CHANGELOG.md View File

@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Added
- Adds an indicator to the *GitLens* explorer's branch history to mark the the tips of all branches
### Fixed
- Fixes issue where username and/or password in a remote urls could be shown
## [8.2.1] - 2018-04-11
### Added
- Adds better logging for failed git commands

+ 3
- 4
src/git/models/branch.ts View File

@ -4,7 +4,6 @@ import { GlyphChars } from '../../constants';
export class GitBranch {
readonly current: boolean;
readonly name: string;
readonly remote: boolean;
readonly tracking?: string;
@ -16,7 +15,8 @@ export class GitBranch {
constructor(
public readonly repoPath: string,
branch: string,
current: boolean = false,
public readonly current: boolean = false,
public readonly sha?: string,
tracking?: string,
ahead: number = 0,
behind: number = 0
@ -29,9 +29,8 @@ export class GitBranch {
this.remote = false;
}
this.current = current;
this.name = branch;
this.tracking = tracking === '' || tracking == null ? undefined : tracking;
this.tracking = (tracking === '' || tracking == null) ? undefined : tracking;
this.state = {
ahead: ahead,
behind: behind

+ 1
- 1
src/git/parsers/branchParser.ts View File

@ -17,7 +17,7 @@ export class GitBranchParser {
if (match == null) break;
const [ahead, behind] = this.parseState(match[5]);
branches.push(new GitBranch(repoPath, match[2], match[1] === '*', match[4], ahead, behind));
branches.push(new GitBranch(repoPath, match[2], match[1] === '*', match[3], match[4], ahead, behind));
} while (match != null);
if (!branches.length) return undefined;

+ 23
- 0
src/system/array.ts View File

@ -40,6 +40,29 @@ export namespace Arrays {
}, Object.create(null));
}
export function groupByMap<TKey, TValue>(source: TValue[], accessor: (item: TValue) => TKey): Map<TKey, TValue[]> {
return source.reduce((groupings, current) => {
const value = accessor(current);
const group = groupings.get(value) || [];
groupings.set(value, group);
group.push(current);
return groupings;
}, new Map<TKey, TValue[]>());
}
export function groupByFilterMap<TKey, TValue, TMapped>(source: TValue[], accessor: (item: TValue) => TKey, predicateMapper: (item: TValue) => TMapped | null | undefined): Map<TKey, TMapped[]> {
return source.reduce((groupings, current) => {
const mapped = predicateMapper(current);
if (mapped != null) {
const value = accessor(current);
const group = groupings.get(value) || [];
groupings.set(value, group);
group.push(mapped);
}
return groupings;
}, new Map<TKey, TMapped[]>());
}
export interface IHierarchicalItem<T> {
name: string;
relativePath: string;

+ 12
- 6
src/views/branchNode.ts View File

@ -1,5 +1,5 @@
'use strict';
import { Iterables } from '../system';
import { Arrays, Iterables } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { ExplorerBranchesLayout } from '../configuration';
@ -40,12 +40,18 @@ export class BranchNode extends ExplorerRefNode {
const log = await Container.git.getLog(this.uri.repoPath!, { maxCount: this.maxCount, ref: this.branch.name });
if (log === undefined) return [new MessageNode('No commits yet')];
let trackingRef: string | undefined = undefined;
if (this.branch.tracking !== undefined) {
trackingRef = await Container.git.getMergeBase(this.uri.repoPath!, this.branch.name, this.branch.tracking);
}
const branches = await Container.git.getBranches(this.uri.repoPath);
// Get the sha length, since `git branch` can return variable length shas
const shaLength = branches[0].sha!.length;
const branchesBySha = Arrays.groupByFilterMap(branches, b => b.sha!, b => b.name === this.branch.name ? undefined : b.name);
const getBranchTips = (sha: string) => {
const branches = branchesBySha.get(sha.substr(0, shaLength));
if (branches === undefined || branches.length === 0) return undefined;
return branches.join(', ');
};
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer, this.branch, trackingRef))];
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer, this.branch, getBranchTips))];
if (log.truncated) {
children.push(new ShowAllNode('Show All Commits', this, this.explorer));
}

+ 6
- 4
src/views/commitNode.ts View File

@ -17,7 +17,7 @@ export class CommitNode extends ExplorerRefNode {
public readonly commit: GitLogCommit,
private readonly explorer: Explorer,
public readonly branch?: GitBranch,
private readonly trackingRef?: string
private readonly getBranchTips?: (sha: string) => string | undefined
) {
super(commit.toGitUri());
}
@ -51,9 +51,11 @@ export class CommitNode extends ExplorerRefNode {
dataFormat: Container.config.defaultDateFormat
} as ICommitFormatOptions);
if (this.trackingRef === this.commit.sha) {
label = `${GlyphChars.AngleBracketLeftHeavy}${GlyphChars.SpaceThin}${this.branch!.tracking!}${GlyphChars.SpaceThin}${GlyphChars.AngleBracketRightHeavy}${GlyphChars.ArrowHeadRight}${GlyphChars.Space} ${label}`;
const branchTips = this.getBranchTips && this.getBranchTips(this.commit.sha);
if (branchTips !== undefined) {
label = `${GlyphChars.AngleBracketLeftHeavy}${GlyphChars.SpaceThin}${branchTips}${GlyphChars.SpaceThin}${GlyphChars.AngleBracketRightHeavy}${GlyphChars.ArrowHeadRight}${GlyphChars.Space} ${label}`;
}
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
item.contextValue = (this.branch === undefined || this.branch.current)
@ -72,7 +74,7 @@ export class CommitNode extends ExplorerRefNode {
item.tooltip = CommitFormatter.fromTemplate(
this.commit.isUncommitted
? `\${author} ${GlyphChars.Dash} \${id}\n\${ago} (\${date})`
: `\${author} ${GlyphChars.Dash} \${id}${this.trackingRef === this.commit.sha ? ` (${this.branch!.tracking!})` : ''}\n\${ago} (\${date})\n\n\${message}`,
: `\${author} ${GlyphChars.Dash} \${id}${branchTips !== undefined ? ` (${branchTips})` : ''}\n\${ago} (\${date})\n\n\${message}`,
this.commit,
{
dataFormat: Container.config.defaultDateFormat

Loading…
Cancel
Save