Procházet zdrojové kódy

Closes #230 - adds gravatar support to view

main
Eric Amodio před 7 roky
rodič
revize
d91c598ce0
14 změnil soubory, kde provedl 87 přidání a 22 odebrání
  1. +2
    -0
      CHANGELOG.md
  2. +1
    -0
      README.md
  3. +6
    -0
      package.json
  4. +2
    -0
      src/configuration.ts
  5. +1
    -1
      src/git/git.ts
  6. +27
    -1
      src/git/models/logCommit.ts
  7. +1
    -0
      src/git/models/stashCommit.ts
  8. +6
    -0
      src/git/parsers/logParser.ts
  9. +2
    -2
      src/quickPicks/repoStatus.ts
  10. +5
    -0
      src/system/string.ts
  11. +17
    -8
      src/views/commitFileNode.ts
  12. +8
    -4
      src/views/commitNode.ts
  13. +5
    -2
      src/views/fileHistoryNode.ts
  14. +4
    -4
      src/views/statusFilesNode.ts

+ 2
- 0
CHANGELOG.md Zobrazit soubor

@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Adds a new `Active Repository` node to `Repository View` of the `GitLens` view -- closes [#224](https://github.com/eamodio/vscode-gitlens/issues/224)
- Automatically updates to track the repository of the active editor
- Only visible if there is more than 1 repository within the workspace
- Adds [Gravatar](https://en.gravatar.com/) support to the `GitLens` view
- Adds `gitlens.gitExplorer.gravatars` setting to specify whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view
### Fixed
- Fixes [#228](https://github.com/eamodio/vscode-gitlens/issues/228) - Gutter blame spills over heatmap

+ 1
- 0
README.md Zobrazit soubor

@ -424,6 +424,7 @@ GitLens is highly customizable and provides many configuration settings to allow
|`gitlens.gitExplorer.showTrackingBranch`|Specifies whether or not to show the tracking branch when displaying local branches in the `GitLens` view"
|`gitlens.gitExplorer.commitFormat`|Specifies the format of committed changes in the `GitLens` view<br />Available tokens<br /> ${id} - commit id<br /> ${author} - commit author<br /> ${message} - commit message<br /> ${ago} - relative commit date (e.g. 1 day ago)<br /> ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)<br /> ${authorAgo} - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|`gitlens.gitExplorer.commitFileFormat`|Specifies the format of a committed file in the `GitLens` view<br />Available tokens<br /> ${directory} - directory name<br /> ${file} - file name<br /> ${filePath} - formatted file name and path<br /> ${path} - full file path
|`gitlens.gitExplorer.gravatars`|Specifies whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view
|`gitlens.gitExplorer.stashFormat`|Specifies the format of stashed changes in the `GitLens` view<br />Available tokens<br /> ${id} - commit id<br /> ${author} - commit author<br /> ${message} - commit message<br /> ${ago} - relative commit date (e.g. 1 day ago)<br /> ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)<br /> ${authorAgo} - commit author, relative commit date<br />See https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting
|`gitlens.gitExplorer.stashFileFormat`|Specifies the format of a stashed file in the `GitLens` view<br />Available tokens<br /> ${directory} - directory name<br /> ${file} - file name<br /> ${filePath} - formatted file name and path<br /> ${path} - full file path
|`gitlens.gitExplorer.statusFileFormat`|Specifies the format of the status of a working or committed file in the `GitLens` view<br />Available tokens<br /> ${directory} - directory name<br /> ${file} - file name<br /> ${filePath} - formatted file name and path<br /> ${path} - full file path<br />${working} - optional indicator if the file is uncommitted

+ 6
- 0
package.json Zobrazit soubor

@ -522,6 +522,12 @@
"description": "Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the `GitLens` view\nOnly applies when displaying files as `auto`",
"scope": "window"
},
"gitlens.gitExplorer.gravatars": {
"type": "boolean",
"default": true,
"description": "Specifies whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view",
"scope": "window"
},
"gitlens.gitExplorer.includeWorkingTree": {
"type": "boolean",
"default": true,

+ 2
- 0
src/configuration.ts Zobrazit soubor

@ -150,6 +150,7 @@ export interface IGitExplorerConfig {
showTrackingBranch: boolean;
commitFormat: string;
commitFileFormat: string;
gravatars: boolean;
stashFormat: string;
stashFileFormat: string;
statusFileFormat: string;
@ -387,6 +388,7 @@ const emptyConfig: IConfig = {
showTrackingBranch: false,
commitFormat: '',
commitFileFormat: '',
gravatars: false,
stashFormat: '',
stashFileFormat: '',
statusFileFormat: ''

+ 1
- 1
src/git/git.ts Zobrazit soubor

@ -24,7 +24,7 @@ export * from './remotes/provider';
let git: IGit;
const defaultBlameParams = [`blame`, `--root`, `--incremental`];
const defaultLogParams = [`log`, `--name-status`, `--full-history`, `-M`, `--format=%H -%nauthor %an%nauthor-date %at%nparents %P%nsummary %B%nfilename ?`];
const defaultLogParams = [`log`, `--name-status`, `--full-history`, `-M`, `--format=%H -%nauthor %an%nauthor-email %ae%nauthor-date %at%nparents %P%nsummary %B%nfilename ?`];
const defaultStashParams = [`stash`, `list`, `--name-status`, `--full-history`, `-M`, `--format=%H -%nauthor-date %at%nreflog-selector %gd%nsummary %B%nfilename ?`];
const GitWarnings = [

+ 27
- 1
src/git/models/logCommit.ts Zobrazit soubor

@ -1,10 +1,13 @@
'use strict';
import { Strings } from '../../system';
import { Uri } from 'vscode';
import { GitCommit, GitCommitType } from './commit';
import { Git } from '../git';
import { GitStatusFileStatus, IGitStatusFile } from './status';
import * as path from 'path';
const gravatarCache: Map<string, Uri> = new Map();
export class GitLogCommit extends GitCommit {
nextSha?: string;
@ -15,6 +18,7 @@ export class GitLogCommit extends GitCommit {
repoPath: string,
sha: string,
author: string,
public readonly email: string | undefined,
date: Date,
message: string,
fileName: string,
@ -39,6 +43,27 @@ export class GitLogCommit extends GitCommit {
);
}
get gravatarUri(): Uri {
const key = this.email
? this.email.trim().toLowerCase()
: '';
let gravatar = gravatarCache.get(key);
if (gravatar !== undefined) return gravatar;
gravatar = Uri.parse(`https://www.gravatar.com/avatar/${this.email ? Strings.md5(this.email) : '00000000000000000000000000000000'}.jpg?s=22&d=retro`);
// HACK: Monkey patch Uri.toString to avoid the unwanted query string encoding
const originalToStringFn = gravatar.toString;
gravatar.toString = function(skipEncoding?: boolean | undefined) {
return originalToStringFn.call(gravatar, true);
};
gravatarCache.set(key, gravatar);
return gravatar;
}
get isMerge() {
return this.parentShas && this.parentShas.length > 1;
}
@ -111,12 +136,13 @@ export class GitLogCommit extends GitCommit {
});
}
with(changes: { type?: GitCommitType, sha?: string | null, fileName?: string, author?: string, date?: Date, message?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null, status?: GitStatusFileStatus, fileStatuses?: IGitStatusFile[] | null }): GitLogCommit {
with(changes: { type?: GitCommitType, sha?: string | null, fileName?: string, author?: string, email?: string, date?: Date, message?: string, originalFileName?: string | null, previousFileName?: string | null, previousSha?: string | null, status?: GitStatusFileStatus, fileStatuses?: IGitStatusFile[] | null }): GitLogCommit {
return new GitLogCommit(
changes.type || this.type,
this.repoPath,
this.getChangedValue(changes.sha, this.sha)!,
changes.author || this.author,
changes.email || this.email,
changes.date || this.date,
changes.message || this.message,
changes.fileName || this.fileName,

+ 1
- 0
src/git/models/stashCommit.ts Zobrazit soubor

@ -24,6 +24,7 @@ export class GitStashCommit extends GitLogCommit {
repoPath,
sha,
'You',
undefined,
date,
message,
fileName,

+ 6
- 0
src/git/parsers/logParser.ts Zobrazit soubor

@ -9,6 +9,7 @@ interface LogEntry {
sha: string;
author: string;
authorEmail?: string;
authorDate?: string;
parentShas?: string[];
@ -83,6 +84,10 @@ export class GitLogParser {
: lineParts.slice(1).join(' ').trim();
break;
case 'author-email':
entry.authorEmail = lineParts.slice(1).join(' ').trim();
break;
case 'author-date':
entry.authorDate = lineParts[1];
break;
@ -241,6 +246,7 @@ export class GitLogParser {
repoPath!,
entry.sha,
entry.author,
entry.authorEmail,
new Date(entry.authorDate! as any * 1000),
entry.summary!,
relativeFileName,

+ 2
- 2
src/quickPicks/repoStatus.ts Zobrazit soubor

@ -28,10 +28,10 @@ export class OpenStatusFileCommandQuickPickItem extends OpenFileCommandQuickPick
this.status = status;
if (status.indexStatus !== undefined) {
this.commit = new GitLogCommit(GitCommitType.File, status.repoPath, GitService.stagedUncommittedSha, 'You', new Date(), '', status.fileName, [status], status.status, status.originalFileName, 'HEAD', status.fileName);
this.commit = new GitLogCommit(GitCommitType.File, status.repoPath, GitService.stagedUncommittedSha, 'You', undefined, new Date(), '', status.fileName, [status], status.status, status.originalFileName, 'HEAD', status.fileName);
}
else {
this.commit = new GitLogCommit(GitCommitType.File, status.repoPath, GitService.uncommittedSha, 'You', new Date(), '', status.fileName, [status], status.status, status.originalFileName, realIndexStatus !== undefined ? GitService.stagedUncommittedSha : 'HEAD', status.fileName);
this.commit = new GitLogCommit(GitCommitType.File, status.repoPath, GitService.uncommittedSha, 'You', undefined, new Date(), '', status.fileName, [status], status.status, status.originalFileName, realIndexStatus !== undefined ? GitService.stagedUncommittedSha : 'HEAD', status.fileName);
}
}

+ 5
- 0
src/system/string.ts Zobrazit soubor

@ -1,5 +1,6 @@
'use strict';
const _escapeRegExp = require('lodash.escaperegexp');
import * as crypto from 'crypto';
export namespace Strings {
export function escapeRegExp(s: string): string {
@ -57,6 +58,10 @@ export namespace Strings {
}
}
export function md5(s: string): string {
return crypto.createHash('md5').update(s).digest('hex');
}
export function pad(s: string, before: number = 0, after: number = 0, padding: string = `\u00a0`) {
if (before === 0 && after === 0) return s;

+ 17
- 8
src/views/commitFileNode.ts Zobrazit soubor

@ -11,6 +11,7 @@ export enum CommitFileNodeDisplayAs {
CommitIcon = 1 << 1,
FileLabel = 1 << 2,
StatusIcon = 1 << 3,
Gravatar = 1 << 4,
Commit = CommitLabel | CommitIcon,
File = FileLabel | StatusIcon
@ -54,14 +55,22 @@ export class CommitFileNode extends ExplorerNode {
const item = new TreeItem(this.label, TreeItemCollapsibleState.None);
item.contextValue = this.resourceType;
const icon = (this.displayAs & CommitFileNodeDisplayAs.CommitIcon)
? 'icon-commit.svg'
: getGitStatusIcon(this.status.status);
item.iconPath = {
dark: this.explorer.context.asAbsolutePath(path.join('images', 'dark', icon)),
light: this.explorer.context.asAbsolutePath(path.join('images', 'light', icon))
};
if ((this.displayAs & CommitFileNodeDisplayAs.CommitIcon) === CommitFileNodeDisplayAs.CommitIcon) {
item.iconPath = {
dark: this.explorer.context.asAbsolutePath(path.join('images', 'dark', 'icon-commit.svg')),
light: this.explorer.context.asAbsolutePath(path.join('images', 'light', 'icon-commit.svg'))
};
}
else if ((this.displayAs & CommitFileNodeDisplayAs.StatusIcon) === CommitFileNodeDisplayAs.StatusIcon) {
const icon = getGitStatusIcon(this.status.status);
item.iconPath = {
dark: this.explorer.context.asAbsolutePath(path.join('images', 'dark', icon)),
light: this.explorer.context.asAbsolutePath(path.join('images', 'light', icon))
};
}
else if ((this.displayAs & CommitFileNodeDisplayAs.Gravatar) === CommitFileNodeDisplayAs.Gravatar) {
item.iconPath = this.commit.gravatarUri;
}
item.command = this.getCommand();

+ 8
- 4
src/views/commitNode.ts Zobrazit soubor

@ -59,10 +59,14 @@ export class CommitNode extends ExplorerNode {
? ResourceType.CommitOnCurrentBranch
: ResourceType.Commit;
item.iconPath = {
dark: this.explorer.context.asAbsolutePath('images/dark/icon-commit.svg'),
light: this.explorer.context.asAbsolutePath('images/light/icon-commit.svg')
};
if (this.explorer.config.gravatars) {
item.iconPath = this.commit.gravatarUri;
} else {
item.iconPath = {
dark: this.explorer.context.asAbsolutePath('images/dark/icon-commit.svg'),
light: this.explorer.context.asAbsolutePath('images/light/icon-commit.svg')
};
}
return item;
}

+ 5
- 2
src/views/fileHistoryNode.ts Zobrazit soubor

@ -22,6 +22,8 @@ export class FileHistoryNode extends ExplorerNode {
const children: ExplorerNode[] = [];
const displayAs = CommitFileNodeDisplayAs.CommitLabel | (this.explorer.config.gravatars ? CommitFileNodeDisplayAs.Gravatar : CommitFileNodeDisplayAs.StatusIcon);
const status = await this.explorer.git.getStatusForFile(this.uri.repoPath!, this.uri.fsPath);
if (status !== undefined && (status.indexStatus !== undefined || status.workTreeStatus !== undefined)) {
let sha;
@ -45,6 +47,7 @@ export class FileHistoryNode extends ExplorerNode {
this.uri.repoPath!,
sha,
'You',
undefined,
new Date(),
'',
status.fileName,
@ -53,12 +56,12 @@ export class FileHistoryNode extends ExplorerNode {
status.originalFileName,
previousSha,
status.originalFileName || status.fileName);
children.push(new CommitFileNode(status, commit, this.explorer, CommitFileNodeDisplayAs.CommitLabel | CommitFileNodeDisplayAs.StatusIcon));
children.push(new CommitFileNode(status, commit, this.explorer, displayAs));
}
const log = await this.explorer.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, this.uri.sha);
if (log !== undefined) {
children.push(...Iterables.map(log.commits.values(), c => new CommitFileNode(c.fileStatuses[0], c, this.explorer, CommitFileNodeDisplayAs.CommitLabel | CommitFileNodeDisplayAs.StatusIcon)));
children.push(...Iterables.map(log.commits.values(), c => new CommitFileNode(c.fileStatuses[0], c, this.explorer, displayAs)));
}
if (children.length === 0) return [new MessageNode('No file history')];

+ 4
- 4
src/views/statusFilesNode.ts Zobrazit soubor

@ -53,12 +53,12 @@ export class StatusFilesNode extends ExplorerNode {
{
...s,
status: s.status,
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.uncommittedSha, 'You', new Date(), '', s.fileName, [s], s.status, s.originalFileName, GitService.stagedUncommittedSha, s.fileName)
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.uncommittedSha, 'You', undefined, new Date(), '', s.fileName, [s], s.status, s.originalFileName, GitService.stagedUncommittedSha, s.fileName)
} as IGitStatusFileWithCommit,
{
...s,
status: s.status,
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.stagedUncommittedSha, 'You', older, '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName)
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.stagedUncommittedSha, 'You', undefined, older, '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName)
} as IGitStatusFileWithCommit
];
}
@ -67,7 +67,7 @@ export class StatusFilesNode extends ExplorerNode {
{
...s,
status: s.status,
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.stagedUncommittedSha, 'You', new Date(), '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName)
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.stagedUncommittedSha, 'You', undefined, new Date(), '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName)
} as IGitStatusFileWithCommit
];
}
@ -76,7 +76,7 @@ export class StatusFilesNode extends ExplorerNode {
{
...s,
status: s.status,
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.uncommittedSha, 'You', new Date(), '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName)
commit: new GitLogCommit(GitCommitType.File, repoPath, GitService.uncommittedSha, 'You', undefined, new Date(), '', s.fileName, [s], s.status, s.originalFileName, 'HEAD', s.fileName)
} as IGitStatusFileWithCommit
];
}

Načítá se…
Zrušit
Uložit