Browse Source

Adds tags node to the view

main
Eric Amodio 7 years ago
parent
commit
261b216ea8
16 changed files with 211 additions and 37 deletions
  1. +22
    -7
      CHANGELOG.md
  2. +10
    -2
      README.md
  3. +4
    -0
      images/dark/icon-tag.svg
  4. +4
    -0
      images/light/icon-tag.svg
  5. +10
    -0
      package.json
  6. +24
    -17
      src/git/git.ts
  7. +2
    -1
      src/git/models/models.ts
  8. +9
    -5
      src/git/models/repository.ts
  9. +9
    -0
      src/git/models/tag.ts
  10. +15
    -0
      src/git/parsers/tagParser.ts
  11. +10
    -1
      src/gitService.ts
  12. +3
    -1
      src/views/explorerNode.ts
  13. +3
    -1
      src/views/explorerNodes.ts
  14. +4
    -2
      src/views/repositoryNode.ts
  15. +46
    -0
      src/views/tagNode.ts
  16. +36
    -0
      src/views/tagsNode.ts

+ 22
- 7
CHANGELOG.md View File

@ -6,20 +6,27 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [7.0.0-beta2] - 2017-12-16 ## [7.0.0-beta2] - 2017-12-16
### Added ### Added
- Adds a new `Active Repository` node to `Repository View` of the `GitLens` view -- closes [#224](https://github.com/eamodio/vscode-gitlens/issues/224)
- Adds a new `Active Repository` node to the `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 - Automatically updates to track the repository of the active editor
- Only visible if there is more than 1 repository within the workspace - Only visible if there is more than 1 repository within the workspace
- Adds a new `Tags` node to the `Repository View` of the `GitLens` view
- Provides a list of tags
- Expand each tag to easily see its revision (commit) history
- Expand each revision (commit) to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
- Provides a context menu on each revision (commit) with `Open Commit in Remote`, `Open All Changes`, `Open All Changes with Working Tree`, `Open Files`, `Open Revisions`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Show Commit Details`, `Compare with Selected`, `Select for Compare`, `Rebase Commit (via Terminal)`, `Reset Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu on each changed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Open Revision in Remote`, `Apply Changes`, and `Show Commit File Details` commands
- Provides a context menu on each tag with `Compare with Selected`, `Select for Compare`, and `Refresh` commands
- Provides a context menu with a `Refresh` command
- Adds [Gravatar](https://en.gravatar.com/) support to the `GitLens` view - 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 - Adds `gitlens.gitExplorer.gravatars` setting to specify whether or not to show gravatar images instead of commit (or status) icons in the `GitLens` view
- Adds `gitlens.gitExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the `GitLens` view<br />`identicon` - a geometric pattern<br />`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)<br />`monsterid` - a monster with different colors, faces, etc<br />`retro` - 8-bit arcade-style pixelated faces<br />`robohash` - a robot with different colors, faces, etc<br />`wavatar` - faces with differing features and backgrounds - Adds `gitlens.gitExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the `GitLens` view<br />`identicon` - a geometric pattern<br />`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)<br />`monsterid` - a monster with different colors, faces, etc<br />`retro` - 8-bit arcade-style pixelated faces<br />`robohash` - a robot with different colors, faces, etc<br />`wavatar` - faces with differing features and backgrounds
- Adds `gitlens.resultsExplorer.gravatars` setting to specify whether or not to show gravatar images instead of commit (or status) icons in the `GitLens Results` view - Adds `gitlens.resultsExplorer.gravatars` setting to specify whether or not to show gravatar images instead of commit (or status) icons in the `GitLens Results` view
- Adds `gitlens.resultsExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the `GitLens Results` view<br />`identicon` - a geometric pattern<br />`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)<br />`monsterid` - a monster with different colors, faces, etc<br />`retro` - 8-bit arcade-style pixelated faces<br />`robohash` - a robot with different colors, faces, etc<br />`wavatar` - faces with differing features and backgrounds - Adds `gitlens.resultsExplorer.gravatarsDefault` setting to specify the style of the gravatar default (fallback) images in the `GitLens Results` view<br />`identicon` - a geometric pattern<br />`mm` - (mystery-man) a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)<br />`monsterid` - a monster with different colors, faces, etc<br />`retro` - 8-bit arcade-style pixelated faces<br />`robohash` - a robot with different colors, faces, etc<br />`wavatar` - faces with differing features and backgrounds
- Adds `Select for Compare` command (`gitlens.explorers.selectForCompare`) to branch and revision (commit) nodes in the `GitLens` view to mark the base revision of a comparision
- Adds `Compare with Selected` command (`gitlens.explorers.compareWithSelected`) to branch and revision (commit) nodes in the `GitLens` view once another branch or revision (commit) node within the same repository has been selected to compare the current selection with the previously selected revision (branch or commit)
- Adds `Apply Changes` option to the commit/stash file quick pick menu -- closes [#232](https://github.com/eamodio/vscode-gitlens/issues/232)
- Adds `Show All Commits` option to the commit search quick pick menu to show all the results, if there are more than the threshold
- Adds `Show in Results` option to the commit search quick pick menu to show the results in the `GitLens Results` view
- Adds `Show in Results` option to the file history quick pick menu to show the history in the `GitLens Results` view
- Adds `Select for Compare` command (`gitlens.explorers.selectForCompare`) to branch, remote branch, tag, and revision (commit) nodes in the `GitLens` view to mark the base reference of a comparision
- Adds `Compare with Selected` command (`gitlens.explorers.compareWithSelected`) to branch, remote branch, tag, and revision (commit) nodes in the `GitLens` view once another reference within the same repository has been selected to compare the current selection with the previously selected reference in the `GitLens Results` view
- Adds an all-new, on-demand `GitLens Results` view to the Explorer activity - Adds an all-new, on-demand `GitLens Results` view to the Explorer activity
@ -39,6 +46,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Provides toolbar commands to `Search Commits`, `Keep Results`, `Refresh`, `Show Files in Automatic View` or `Show Files in List View` or `Show Files in Tree View`, and `Close` - Provides toolbar commands to `Search Commits`, `Keep Results`, `Refresh`, `Show Files in Automatic View` or `Show Files in List View` or `Show Files in Tree View`, and `Close`
- Adds `Apply Changes` option to the commit/stash file quick pick menu -- closes [#232](https://github.com/eamodio/vscode-gitlens/issues/232)
- Adds `Show All Commits` option to the commit search quick pick menu to show all the results, if there are more than the threshold
- Adds `Show in Results` option to the commit search quick pick menu to show the results in the `GitLens Results` view
- Adds `Show in Results` option to the file history quick pick menu to show the history in the `GitLens Results` view
### Changed
- Improves startup performance a bit
### Fixed ### Fixed
- Fixes [#228](https://github.com/eamodio/vscode-gitlens/issues/228) - Gutter blame spills over heatmap - Fixes [#228](https://github.com/eamodio/vscode-gitlens/issues/228) - Gutter blame spills over heatmap
- Fixes incorrect blame highlighting -- thanks to [PR #231](https://github.com/eamodio/vscode-gitlens/pull/231) by Alexey Vasyukov ([@notmedia](https://github.com/notmedia))! - Fixes incorrect blame highlighting -- thanks to [PR #231](https://github.com/eamodio/vscode-gitlens/pull/231) by Alexey Vasyukov ([@notmedia](https://github.com/notmedia))!

+ 10
- 2
README.md View File

@ -160,7 +160,7 @@ While GitLens is highly customizable and provides many [configuration settings](
- Expand each revision (commit) to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes - Expand each revision (commit) to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
- Provides a context menu on each revision (commit) with `Open Commit in Remote`, `Open All Changes`, `Open All Changes with Working Tree`, `Open Files`, `Open Revisions`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Show Commit Details`, `Compare with Selected`, `Select for Compare`, `Rebase Commit (via Terminal)`, `Reset Commit (via Terminal)`, and `Refresh` commands - Provides a context menu on each revision (commit) with `Open Commit in Remote`, `Open All Changes`, `Open All Changes with Working Tree`, `Open Files`, `Open Revisions`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Show Commit Details`, `Compare with Selected`, `Select for Compare`, `Rebase Commit (via Terminal)`, `Reset Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu on each changed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Open Revision in Remote`, `Apply Changes`, and `Show Commit File Details` commands - Provides a context menu on each changed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Open Revision in Remote`, `Apply Changes`, and `Show Commit File Details` commands
- Provides a context menu on each branch with `Open Branch in Remote`, `Checkout Branch (via Terminal)`, `Create Branch (via Terminal)...`, `Delete Branch (via Terminal)`, `Rebase Branch to Remote (via Terminal)`, `Squash Branch into Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu on each branch with `Open Branch in Remote`, `Compare with Selected`, `Select for Compare`, `Checkout Branch (via Terminal)`, `Create Branch (via Terminal)...`, `Delete Branch (via Terminal)`, `Rebase Branch to Remote (via Terminal)`, `Squash Branch into Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu with `Open Branches in Remote`, and `Refresh` commands - Provides a context menu with `Open Branches in Remote`, and `Refresh` commands
- `Remotes` node — provides a list of remotes - `Remotes` node — provides a list of remotes
@ -170,7 +170,7 @@ While GitLens is highly customizable and provides many [configuration settings](
- Expand each revision (commit) to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes - Expand each revision (commit) to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
- Provides a context menu on each revision (commit) with `Open Commit in Remote`, `Open All Changes`, `Open All Changes with Working Tree`, `Open Files`, `Open Revisions`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`,`Show Commit Details`, `Compare with Selected`, `Select for Compare`, and `Refresh` commands - Provides a context menu on each revision (commit) with `Open Commit in Remote`, `Open All Changes`, `Open All Changes with Working Tree`, `Open Files`, `Open Revisions`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`,`Show Commit Details`, `Compare with Selected`, `Select for Compare`, and `Refresh` commands
- Provides a context menu on each changed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Open Revision in Remote`, `Apply Changes`, `Show File History`, and `Show Commit File Details` commands - Provides a context menu on each changed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Open Revision in Remote`, `Apply Changes`, `Show File History`, and `Show Commit File Details` commands
- Provides a context menu on each remote branch with `Open Branch in Remote`, `Checkout Branch (via Terminal)`, `Create Branch (via Terminal)...`, `Delete Branch (via Terminal)`, `Squash Branch into Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu on each remote branch with `Open Branch in Remote`, `Compare with Selected`, `Select for Compare`, `Checkout Branch (via Terminal)`, `Create Branch (via Terminal)...`, `Delete Branch (via Terminal)`, `Squash Branch into Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu on each remote with `Open Branches in Remote`, `Open Repository in Remote`, `Remove Remote (via Terminal)`, and `Refresh` commands - Provides a context menu on each remote with `Open Branches in Remote`, `Open Repository in Remote`, `Remove Remote (via Terminal)`, and `Refresh` commands
- Provides a context menu with a `Refresh` command - Provides a context menu with a `Refresh` command
@ -180,6 +180,14 @@ While GitLens is highly customizable and provides many [configuration settings](
- Provides a context menu on each stashed file with `Apply Changes`, `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, and `Show File History` commands - Provides a context menu on each stashed file with `Apply Changes`, `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, and `Show File History` commands
- Provides a context menu with `Stash Changes`, and `Refresh` commands - Provides a context menu with `Stash Changes`, and `Refresh` commands
- `Tags` node — provides a list of tags
- Expand each tag to easily see its revision (commit) history
- Expand each revision (commit) to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
- Provides a context menu on each revision (commit) with `Open Commit in Remote`, `Open All Changes`, `Open All Changes with Working Tree`, `Open Files`, `Open Revisions`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Show Commit Details`, `Compare with Selected`, `Select for Compare`, `Rebase Commit (via Terminal)`, `Reset Commit (via Terminal)`, and `Refresh` commands
- Provides a context menu on each changed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Open Revision in Remote`, `Apply Changes`, and `Show Commit File Details` commands
- Provides a context menu on each tag with `Compare with Selected`, `Select for Compare`, and `Refresh` commands
- Provides a context menu with a `Refresh` command
- `History View` - provides the revision history of the active file - `History View` - provides the revision history of the active file
![GitLens History view](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-git-custom-view-history.png) ![GitLens History view](https://raw.githubusercontent.com/eamodio/vscode-gitlens/master/images/screenshot-git-custom-view-history.png)

+ 4
- 0
images/dark/icon-tag.svg View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path fill="#C5C5C5" d="m8.18878,5.18375c-0.47,-0.47 -1.11,-0.73 -1.77,-0.73l-2.46,0c-1.37,0 -2.5,1.13 -2.5,2.5l0,2.47c0,0.66 0.27,1.3 0.73,1.77l6.06,6.06c0.39,0.39 1.02,0.39 1.41,0l4.59,-4.59a0.996,0.996 0 0 0 0,-1.41l-6.06,-6.07zm-5.35,5.36c-0.31,-0.3 -0.47,-0.7 -0.47,-1.13l0,-2.46c0,-0.88 0.72,-1.59 1.59,-1.59l2.47,0c0.42,0 0.83,0.16 1.13,0.47l6.14,6.13l-4.73,4.73l-6.13,-6.15zm0.63,-4.09l2,0l0,2l-2.01,0l0,-2l0.01,0z"></path>
</svg>

+ 4
- 0
images/light/icon-tag.svg View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path fill="#424242" d="m8.18878,5.18375c-0.47,-0.47 -1.11,-0.73 -1.77,-0.73l-2.46,0c-1.37,0 -2.5,1.13 -2.5,2.5l0,2.47c0,0.66 0.27,1.3 0.73,1.77l6.06,6.06c0.39,0.39 1.02,0.39 1.41,0l4.59,-4.59a0.996,0.996 0 0 0 0,-1.41l-6.06,-6.07zm-5.35,5.36c-0.31,-0.3 -0.47,-0.7 -0.47,-1.13l0,-2.46c0,-0.88 0.72,-1.59 1.59,-1.59l2.47,0c0.42,0 0.83,0.16 1.13,0.47l6.14,6.13l-4.73,4.73l-6.13,-6.15zm0.63,-4.09l2,0l0,2l-2.01,0l0,-2l0.01,0z"></path>
</svg>

+ 10
- 0
package.json View File

@ -2672,6 +2672,16 @@
"group": "8_gitlens@1" "group": "8_gitlens@1"
}, },
{ {
"command": "gitlens.explorers.compareWithSelected",
"when": "viewItem == gitlens:tag && gitlens:explorers:canCompare",
"group": "7_gitlens@1"
},
{
"command": "gitlens.explorers.selectForCompare",
"when": "viewItem == gitlens:tag",
"group": "7_gitlens@2"
},
{
"command": "gitlens.gitExplorer.refreshNode", "command": "gitlens.gitExplorer.refreshNode",
"when": "view == gitlens.gitExplorer && viewItem != gitlens:commit-file && viewItem != gitlens:stash-file && viewItem != gitlens:status-file", "when": "view == gitlens.gitExplorer && viewItem != gitlens:commit-file && viewItem != gitlens:stash-file && viewItem != gitlens:status-file",
"group": "9_gitlens@1" "group": "9_gitlens@1"

+ 24
- 17
src/git/git.ts View File

@ -19,6 +19,7 @@ export * from './parsers/logParser';
export * from './parsers/remoteParser'; export * from './parsers/remoteParser';
export * from './parsers/stashParser'; export * from './parsers/stashParser';
export * from './parsers/statusParser'; export * from './parsers/statusParser';
export * from './parsers/tagParser';
export * from './remotes/provider'; export * from './remotes/provider';
let git: IGit; let git: IGit;
@ -147,15 +148,15 @@ export class Git {
return git; return git;
} }
static async getVersionedFile(repoPath: string | undefined, fileName: string, branchOrSha: string) {
const data = await Git.show(repoPath, fileName, branchOrSha, { encoding: 'binary' });
static async getVersionedFile(repoPath: string | undefined, fileName: string, ref: string) {
const data = await Git.show(repoPath, fileName, ref, { encoding: 'binary' });
if (data === undefined) return undefined; if (data === undefined) return undefined;
if (Git.isStagedUncommitted(branchOrSha)) {
branchOrSha = '';
if (Git.isStagedUncommitted(ref)) {
ref = '';
} }
const suffix = Strings.truncate(Strings.sanitizeForFileSystem(Git.isSha(branchOrSha) ? Git.shortenSha(branchOrSha) : branchOrSha), 50, '');
const suffix = Strings.truncate(Strings.sanitizeForFileSystem(Git.isSha(ref) ? Git.shortenSha(ref) : ref), 50, '');
const ext = path.extname(fileName); const ext = path.extname(fileName);
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
tmp.file({ prefix: `${path.basename(fileName, ext)}-${suffix}__`, postfix: ext }, tmp.file({ prefix: `${path.basename(fileName, ext)}-${suffix}__`, postfix: ext },
@ -165,7 +166,7 @@ export class Git {
return; return;
} }
Logger.log(`getVersionedFile[${destination}]('${repoPath}', '${fileName}', ${branchOrSha})`);
Logger.log(`getVersionedFile[${destination}]('${repoPath}', '${fileName}', ${ref})`);
fs.appendFile(destination, data, { encoding: 'binary' }, err => { fs.appendFile(destination, data, { encoding: 'binary' }, err => {
if (err) { if (err) {
reject(err); reject(err);
@ -330,10 +331,10 @@ export class Git {
return gitCommand({ cwd: repoPath }, ...params); return gitCommand({ cwd: repoPath }, ...params);
} }
static difftool_dirDiff(repoPath: string, tool: string, sha1: string, sha2?: string) {
const params = [`difftool`, `--dir-diff`, `--tool=${tool}`, sha1];
if (sha2) {
params.push(sha2);
static difftool_dirDiff(repoPath: string, tool: string, ref1: string, ref2?: string) {
const params = [`difftool`, `--dir-diff`, `--tool=${tool}`, ref1];
if (ref2) {
params.push(ref2);
} }
return gitCommand({ cwd: repoPath }, ...params); return gitCommand({ cwd: repoPath }, ...params);
@ -503,18 +504,18 @@ export class Git {
} }
} }
static async show(repoPath: string | undefined, fileName: string, branchOrSha: string, options: { encoding?: string } = {}) {
static async show(repoPath: string | undefined, fileName: string, ref: string, options: { encoding?: string } = {}) {
const [file, root] = Git.splitPath(fileName, repoPath); const [file, root] = Git.splitPath(fileName, repoPath);
if (Git.isStagedUncommitted(branchOrSha)) {
branchOrSha = ':';
if (Git.isStagedUncommitted(ref)) {
ref = ':';
} }
if (Git.isUncommitted(branchOrSha)) throw new Error(`sha=${branchOrSha} is uncommitted`);
if (Git.isUncommitted(ref)) throw new Error(`sha=${ref} is uncommitted`);
const opts = { cwd: root, encoding: options.encoding || 'utf8', willHandleErrors: true } as GitCommandOptions; const opts = { cwd: root, encoding: options.encoding || 'utf8', willHandleErrors: true } as GitCommandOptions;
const args = branchOrSha.endsWith(':')
? `${branchOrSha}./${file}`
: `${branchOrSha}:./${file}`;
const args = ref.endsWith(':')
? `${ref}./${file}`
: `${ref}:./${file}`;
try { try {
const data = await gitCommand(opts, 'show', args); const data = await gitCommand(opts, 'show', args);
@ -573,4 +574,10 @@ export class Git {
const porcelain = porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain'; const porcelain = porcelainVersion >= 2 ? `--porcelain=v${porcelainVersion}` : '--porcelain';
return gitCommand({ cwd: root, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } }, 'status', porcelain, file); return gitCommand({ cwd: root, env: { ...process.env, GIT_OPTIONAL_LOCKS: '0' } }, 'status', porcelain, file);
} }
static tag(repoPath: string) {
const params = [`tag`, `-l`];
return gitCommand({ cwd: repoPath }, ...params);
}
} }

+ 2
- 1
src/git/models/models.ts View File

@ -10,4 +10,5 @@ export * from './remote';
export * from './repository'; export * from './repository';
export * from './stash'; export * from './stash';
export * from './stashCommit'; export * from './stashCommit';
export * from './status';
export * from './status';
export * from './tag';

+ 9
- 5
src/git/models/repository.ts View File

@ -2,7 +2,7 @@
import { Functions } from '../../system'; import { Functions } from '../../system';
import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode'; import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode';
import { configuration, IRemotesConfig } from '../../configuration'; import { configuration, IRemotesConfig } from '../../configuration';
import { GitBranch, GitDiffShortStat, GitRemote, GitStash, GitStatus } from '../git';
import { GitBranch, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git';
import { GitService, GitUri } from '../../gitService'; import { GitService, GitUri } from '../../gitService';
import { RemoteProviderFactory, RemoteProviderMap } from '../remotes/factory'; import { RemoteProviderFactory, RemoteProviderMap } from '../remotes/factory';
import * as _path from 'path'; import * as _path from 'path';
@ -237,11 +237,11 @@ export class Repository extends Disposable {
return this._branch; return this._branch;
} }
async getBranches(): Promise<GitBranch[]> {
getBranches(): Promise<GitBranch[]> {
return this.git.getBranches(this.path); return this.git.getBranches(this.path);
} }
async getChangedFilesCount(sha?: string): Promise<GitDiffShortStat | undefined> {
getChangedFilesCount(sha?: string): Promise<GitDiffShortStat | undefined> {
return this.git.getChangedFilesCount(this.path, sha); return this.git.getChangedFilesCount(this.path, sha);
} }
@ -258,14 +258,18 @@ export class Repository extends Disposable {
return this._remotes; return this._remotes;
} }
async getStashList(): Promise<GitStash | undefined> {
getStashList(): Promise<GitStash | undefined> {
return this.git.getStashList(this.path); return this.git.getStashList(this.path);
} }
async getStatus(): Promise<GitStatus | undefined> {
getStatus(): Promise<GitStatus | undefined> {
return this.git.getStatusForRepo(this.path); return this.git.getStatusForRepo(this.path);
} }
getTags(): Promise<GitTag[]> {
return this.git.getTags(this.path);
}
async hasRemote(): Promise<boolean> { async hasRemote(): Promise<boolean> {
const branch = await this.getBranch(); const branch = await this.getBranch();
return branch !== undefined && branch.tracking !== undefined; return branch !== undefined && branch.tracking !== undefined;

+ 9
- 0
src/git/models/tag.ts View File

@ -0,0 +1,9 @@
'use strict';
export class GitTag {
constructor(
public readonly repoPath: string,
public readonly name: string
) { }
}

+ 15
- 0
src/git/parsers/tagParser.ts View File

@ -0,0 +1,15 @@
'use strict';
import { Arrays } from '../../system';
import { GitTag } from './../git';
export class GitTagParser {
static parse(data: string, repoPath: string): GitTag[] | undefined {
if (!data) return undefined;
const tags = Arrays.filterMap(data.split('\n'), t => !!t ? new GitTag(repoPath, t) : undefined);
if (!tags.length) return undefined;
return tags;
}
}

+ 10
- 1
src/gitService.ts View File

@ -4,7 +4,7 @@ import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, Range, TextD
import { configuration, IConfig, IRemotesConfig } from './configuration'; import { configuration, IConfig, IRemotesConfig } from './configuration';
import { CommandContext, DocumentSchemes, setCommandContext } from './constants'; import { CommandContext, DocumentSchemes, setCommandContext } from './constants';
import { RemoteProviderFactory, RemoteProviderMap } from './git/remotes/factory'; import { RemoteProviderFactory, RemoteProviderMap } from './git/remotes/factory';
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitCommitType, GitDiff, GitDiffChunkLine, GitDiffParser, GitDiffShortStat, GitLog, GitLogCommit, GitLogParser, GitRemote, GitRemoteParser, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, IGit, Repository } from './git/git';
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitCommitType, GitDiff, GitDiffChunkLine, GitDiffParser, GitDiffShortStat, GitLog, GitLogCommit, GitLogParser, GitRemote, GitRemoteParser, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, GitTag, GitTagParser, IGit, Repository } from './git/git';
import { GitUri, IGitCommitInfo } from './git/gitUri'; import { GitUri, IGitCommitInfo } from './git/gitUri';
import { Logger } from './logger'; import { Logger } from './logger';
import * as fs from 'fs'; import * as fs from 'fs';
@ -1197,6 +1197,15 @@ export class GitService extends Disposable {
return status; return status;
} }
async getTags(repoPath: string | undefined): Promise<GitTag[]> {
if (repoPath === undefined) return [];
Logger.log(`getTags('${repoPath}')`);
const data = await Git.tag(repoPath);
return GitTagParser.parse(data, repoPath) || [];
}
async getVersionedFile(repoPath: string | undefined, fileName: string, sha: string | undefined) { async getVersionedFile(repoPath: string | undefined, fileName: string, sha: string | undefined) {
Logger.log(`getVersionedFile('${repoPath}', '${fileName}', '${sha}')`); Logger.log(`getVersionedFile('${repoPath}', '${fileName}', '${sha}')`);

+ 3
- 1
src/views/explorerNode.ts View File

@ -48,7 +48,9 @@ export enum ResourceType {
StatusFile = 'gitlens:status-file', StatusFile = 'gitlens:status-file',
StatusFiles = 'gitlens:status-files', StatusFiles = 'gitlens:status-files',
StatusFileCommits = 'gitlens:status-file-commits', StatusFileCommits = 'gitlens:status-file-commits',
StatusUpstream = 'gitlens:status-upstream'
StatusUpstream = 'gitlens:status-upstream',
Tag = 'gitlens:tag',
Tags = 'gitlens:tags'
} }
export type Explorer = GitExplorer | ResultsExplorer; export type Explorer = GitExplorer | ResultsExplorer;

+ 3
- 1
src/views/explorerNodes.ts View File

@ -23,4 +23,6 @@ export * from './statusFileNode';
export * from './statusFilesNode'; export * from './statusFilesNode';
export * from './statusFilesResultsNode'; export * from './statusFilesResultsNode';
export * from './statusNode'; export * from './statusNode';
export * from './statusUpstreamNode';
export * from './statusUpstreamNode';
export * from './tagsNode';
export * from './tagNode';

+ 4
- 2
src/views/repositoryNode.ts View File

@ -6,10 +6,11 @@ import { GlyphChars } from '../constants';
import { ExplorerNode, ResourceType } from './explorerNode'; import { ExplorerNode, ResourceType } from './explorerNode';
import { GitExplorer } from './gitExplorer'; import { GitExplorer } from './gitExplorer';
import { GitUri, Repository, RepositoryChange, RepositoryChangeEvent } from '../gitService'; import { GitUri, Repository, RepositoryChange, RepositoryChangeEvent } from '../gitService';
import { Logger } from '../logger';
import { RemotesNode } from './remotesNode'; import { RemotesNode } from './remotesNode';
import { StatusNode } from './statusNode'; import { StatusNode } from './statusNode';
import { StashesNode } from './stashesNode'; import { StashesNode } from './stashesNode';
import { Logger } from '../logger';
import { TagsNode } from './tagsNode';
export class RepositoryNode extends ExplorerNode { export class RepositoryNode extends ExplorerNode {
@ -30,7 +31,8 @@ export class RepositoryNode extends ExplorerNode {
new StatusNode(this.uri, this.repo, this.explorer, this.active), new StatusNode(this.uri, this.repo, this.explorer, this.active),
new BranchesNode(this.uri, this.repo, this.explorer, this.active), new BranchesNode(this.uri, this.repo, this.explorer, this.active),
new RemotesNode(this.uri, this.repo, this.explorer), new RemotesNode(this.uri, this.repo, this.explorer),
new StashesNode(this.uri, this.repo, this.explorer)
new StashesNode(this.uri, this.repo, this.explorer),
new TagsNode(this.uri, this.repo, this.explorer)
]; ];
return this.children; return this.children;
} }

+ 46
- 0
src/views/tagNode.ts View File

@ -0,0 +1,46 @@
'use strict';
import { Iterables } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { Explorer, ExplorerNode, ExplorerRefNode, MessageNode, ResourceType, ShowAllNode } from './explorerNode';
import { GitTag, GitUri } from '../gitService';
export class TagNode extends ExplorerRefNode {
readonly supportsPaging: boolean = true;
constructor(
public readonly tag: GitTag,
uri: GitUri,
private readonly explorer: Explorer
) {
super(uri);
}
get ref(): string {
return this.tag.name;
}
async getChildren(): Promise<ExplorerNode[]> {
const log = await this.explorer.git.getLogForRepo(this.uri.repoPath!, { maxCount: this.maxCount, ref: this.tag.name });
if (log === undefined) return [new MessageNode('No commits yet')];
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))];
if (log.truncated) {
children.push(new ShowAllNode('Show All Commits', this, this.explorer));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const item = new TreeItem(this.tag.name, TreeItemCollapsibleState.Collapsed);
item.contextValue = ResourceType.Tag;
item.iconPath = {
dark: this.explorer.context.asAbsolutePath(`images/dark/icon-tag.svg`),
light: this.explorer.context.asAbsolutePath(`images/light/icon-tag.svg`)
};
return item;
}
}

+ 36
- 0
src/views/tagsNode.ts View File

@ -0,0 +1,36 @@
'use strict';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Explorer, ExplorerNode, MessageNode, ResourceType } from './explorerNode';
import { GitUri, Repository } from '../gitService';
import { TagNode } from './tagNode';
export class TagsNode extends ExplorerNode {
constructor(
uri: GitUri,
private readonly repo: Repository,
private readonly explorer: Explorer
) {
super(uri);
}
async getChildren(): Promise<ExplorerNode[]> {
const tags = await this.repo.getTags();
if (tags.length === 0) return [new MessageNode('No tags yet')];
tags.sort((a, b) => a.name.localeCompare(b.name));
return [...tags.map(t => new TagNode(t, this.uri, this.explorer))];
}
async getTreeItem(): Promise<TreeItem> {
const item = new TreeItem(`Tags`, TreeItemCollapsibleState.Collapsed);
item.contextValue = ResourceType.Tags;
item.iconPath = {
dark: this.explorer.context.asAbsolutePath('images/dark/icon-tag.svg'),
light: this.explorer.context.asAbsolutePath('images/light/icon-tag.svg')
};
return item;
}
}

Loading…
Cancel
Save