Compare commits
41 Commits
v4.4.0-bet
...
v5.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
821fa1cc3c | ||
|
|
3835193118 | ||
|
|
d161084ccd | ||
|
|
b9c4468cf7 | ||
|
|
4bacb6fbff | ||
|
|
c98755cc87 | ||
|
|
6d759daaad | ||
|
|
5a42ce4ed4 | ||
|
|
a5af318269 | ||
|
|
5a2bd02402 | ||
|
|
2bba14260f | ||
|
|
22378d5f25 | ||
|
|
d1d1db18e2 | ||
|
|
3dab90709b | ||
|
|
f58d085352 | ||
|
|
a77bb36ee3 | ||
|
|
5cc9365fa1 | ||
|
|
a587108cab | ||
|
|
1b4350e476 | ||
|
|
586785cfb8 | ||
|
|
04df931902 | ||
|
|
d31eb25451 | ||
|
|
35b16a78ba | ||
|
|
825b9661fb | ||
|
|
9782a81e46 | ||
|
|
ed58dc3b49 | ||
|
|
480dcb95fb | ||
|
|
ef41176ea7 | ||
|
|
bcd83566a1 | ||
|
|
ca089777db | ||
|
|
a255eea949 | ||
|
|
1ffb42a090 | ||
|
|
bc2f1b192a | ||
|
|
7d99624068 | ||
|
|
c258d04381 | ||
|
|
4c4926c8b5 | ||
|
|
6255b26fd2 | ||
|
|
4db2b116c2 | ||
|
|
b40579f4b2 | ||
|
|
15c981ba06 | ||
|
|
c2f78a7242 |
111
CHANGELOG.md
@@ -4,7 +4,102 @@ 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/).
|
The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [4.4.0-beta] - 2017-08-17
|
## [5.0.0-alpha.2] - 2017-09-03
|
||||||
|
### Added
|
||||||
|
- Adds an all-new `GitLens` custom view to the Explorer activity
|
||||||
|
|
||||||
|
- `Repository View` - provides a full repository explorer
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- `Repository Status` node — provides the status of the repository
|
||||||
|
- Provides the name of the current branch, its upstream tracking branch (if available), and its upstream status (if available)
|
||||||
|
- Provides indicator dots on the repository icon which denote the following:
|
||||||
|
- `None` - up-to-date with the upstream
|
||||||
|
- `Green` - ahead of the upstream
|
||||||
|
- `Red` - behind the upstream
|
||||||
|
- `Yellow` - both ahead of and behind the upstream
|
||||||
|
- Provides additional nodes, if the current branch is not synchronized with the upstream, to quickly see and explore the specific commits ahead and/or behind the upstream
|
||||||
|
- Provides a context menu with `Open Repository in Remote`, and `Refresh` commands
|
||||||
|
|
||||||
|
- `Branches` node — provides a list of the local branches
|
||||||
|
- Indicates which branch is the current branch and optionally shows the remote tracking branch
|
||||||
|
- Expand each branch 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 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 revision (commit) with `Open Commit in Remote`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Open Files`, `Open Revisions`, `Show Commit Details`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each branch with `Open Branch in Remote`, and `Refresh` commands
|
||||||
|
- Provides a context menu with `Open Branches in Remote`, and `Refresh` commands
|
||||||
|
|
||||||
|
- `Remotes` node — provides a list of remotes
|
||||||
|
- Expand each remote to see its list of branches
|
||||||
|
- Expand each branch 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 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 revision (commit) with `Open Commit in Remote`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Open Files`, `Open Revisions`, `Show Commit Details`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each remote with `Open Branches in Remote`, `Open Repository in Remote`, and `Refresh` commands
|
||||||
|
- Provides a context menu with a `Refresh` command
|
||||||
|
|
||||||
|
- `Stashes` node — provides a list of stashed changes
|
||||||
|
- Expand each stash to quickly see the set of files stashed, complete with status indicators for adds, changes, renames, and deletes
|
||||||
|
- Provides a context menu with `Stash Changes`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each stash with `Apply Stashed Changes` (confirmation required), `Delete Stashed Changes` (confirmation required), `Copy Commit Message to Clipboard`, `Open Files`, `Open Revisions`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each stashed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Apply Changes`, and `Show File History` commands
|
||||||
|
|
||||||
|
- `History View` - provides the revision history of the active file
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Automatically updates to track the active editor
|
||||||
|
- Provides a context menu with `Open File`, `Open File in Remote`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each revision (commit) 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
|
||||||
|
|
||||||
|
- Quickly switch between views using the `Switch to Repository View` or `Switch to History View` commands
|
||||||
|
- Provides toolbar commands to `Search Commits`, `Switch to Repository View` or `Switch to History View`, and `Refresh`
|
||||||
|
|
||||||
|
- Adds `Open Branches in Remote` command (`gitlens.openBranchesInRemote`) - opens the branches in the supported remote service
|
||||||
|
- Adds `Stash Changes` command (`gitlens.stashSave`) to the source control group context menu -- can now stash a group of files
|
||||||
|
- Adds `Stash Changes` command (`gitlens.stashSave`) to the source control resource context menu -- can now stash individual files (works with multi-select too!)
|
||||||
|
- Adds `gitlens.gitExplorer.view` setting to specify the starting view (mode) of the `GitLens` custom view
|
||||||
|
- Adds `gitlens.gitExplorer.showTrackingBranch` setting to specify whether or not to show the tracking branch when displaying local branches in the `GitLens` custom view
|
||||||
|
- Adds `gitlens.gitExplorer.commitFormat` setting to specify the format of committed changes in the `GitLens` custom view
|
||||||
|
- Adds `gitlens.gitExplorer.commitFileFormat` setting to specify the format of a committed file in the `GitLens` custom view
|
||||||
|
- Adds `gitlens.gitExplorer.stashFormat` setting to specify the format of stashed changes in the `GitLens` custom view
|
||||||
|
- Adds `gitlens.gitExplorer.stashFileFormat` setting to specify the format of a stashed file in the `GitLens` custom view
|
||||||
|
- Adds `${filePath}` token to file formatting settings
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Changes `Show Stashed Changes` option icon in repository status quick pick menu to match the `GitLens` custom view
|
||||||
|
- Changes `Stash Changes` option icon in stashed changes quick pick menu to a plus (+)
|
||||||
|
- Renames `Compare File with Previous` command (`gitlens.diffWithPrevious`) to `Compare File with Previous Revision`
|
||||||
|
- Renames `Compare File with Next Commit` command (`gitlens.diffWithNext`) to `Compare File with Next Revision`
|
||||||
|
- Renames `Compare File with Working Tree` command (`gitlens.diffWithWorking`) to `Compare File with Working Revision`
|
||||||
|
- Renames `Compare Line Commit with Previous` command (`gitlens.diffLineWithPrevious`) to `Compare Line Revision with Previous`
|
||||||
|
- Renames `Compare Line Commit with Working Tree` command (`gitlens.diffLineWithWorking`) to `Compare Line Revision with Working`
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- Removes `Git Stashes` custom view view - as it's functionality has been folded into the new `GitLens` custom view
|
||||||
|
- Removes `gitlens.stashExplorer.stashFormat` setting
|
||||||
|
- Removes `gitlens.stashExplorer.stashFileFormat` setting
|
||||||
|
- Removes `Stash Unstaged Changes` option from stashed changes quick pick menu -- didn't work as intended
|
||||||
|
- Removes the seeding of the commit search command from the clipboard
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixes an issue where remote branches couldn't be opened properly in their remote service
|
||||||
|
|
||||||
|
## [4.4.3] - 2017-08-30
|
||||||
|
## Fixed
|
||||||
|
- Fixes [#135](https://github.com/eamodio/vscode-gitlens/issues/135) - Full-width characters break gutter annotations (really this time)
|
||||||
|
|
||||||
|
## [4.4.2] - 2017-08-29
|
||||||
|
## Fixed
|
||||||
|
- Fixes [#135](https://github.com/eamodio/vscode-gitlens/issues/135) - Full-width characters break gutter annotations
|
||||||
|
|
||||||
|
## [4.4.1] - 2017-08-23
|
||||||
|
## Fixed
|
||||||
|
- Fixes [#114](https://github.com/eamodio/vscode-gitlens/issues/114) - Stylus files makes code lens freak out
|
||||||
|
|
||||||
|
## [4.4.0] - 2017-08-18
|
||||||
## Added
|
## Added
|
||||||
- Adds a progress indicator to the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) icon -- pulses while annotations are computed
|
- Adds a progress indicator to the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) icon -- pulses while annotations are computed
|
||||||
- Adds an active state to the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) icon -- turns orange while the annotations are visible
|
- Adds an active state to the `Toggle File Blame Annotations` command (`gitlens.toggleFileBlame`) icon -- turns orange while the annotations are visible
|
||||||
@@ -13,11 +108,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
|||||||
## Changed
|
## Changed
|
||||||
- Changes chat links from Gitter to [Slack](https://join.slack.com/t/vscode-gitlens/shared_invite/MjIxOTgxNDE3NzM0LTE1MDE2Nzk1MTgtMjkwMmZjMzcxNQ)
|
- Changes chat links from Gitter to [Slack](https://join.slack.com/t/vscode-gitlens/shared_invite/MjIxOTgxNDE3NzM0LTE1MDE2Nzk1MTgtMjkwMmZjMzcxNQ)
|
||||||
- Changes the look of the line separators on the gutter blame annotations
|
- Changes the look of the line separators on the gutter blame annotations
|
||||||
- Changes the `gitlens.advanced.toggleWhitespace.enabled` configuration setting to default to `false` -- as this should no longer be required
|
- Changes the `gitlens.advanced.toggleWhitespace.enabled` configuration setting to default to `false` -- thanks to the awesome work in vscode by Alexandru Dima ([@alexandrudima](https://github.com/alexandrudima)) this is no longer required!
|
||||||
|
|
||||||
## Removed
|
## Removed
|
||||||
- Removes unneeded `gitlens.stashExplorer.enabled` configuration setting since users can add or remove custom views natively now
|
- Removes unneeded `gitlens.stashExplorer.enabled` configuration setting since users can add or remove custom views natively now
|
||||||
- Removes unneeded `Toggle Git Stashed Explorer` command (`gitlens.stashExplorer.toggle`) since users can add or remove custom views natively now
|
- Removes unneeded `Toggle Git Stashes Explorer` command (`gitlens.stashExplorer.toggle`) since users can add or remove custom views natively now
|
||||||
- Removes the `gitlens.theme.annotations.file.hover.separateLines` configuration setting
|
- Removes the `gitlens.theme.annotations.file.hover.separateLines` configuration setting
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
@@ -39,20 +134,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
|||||||
|
|
||||||
## [4.3.1] - 2017-07-03
|
## [4.3.1] - 2017-07-03
|
||||||
## Added
|
## Added
|
||||||
- Adds `gitlens.stashExplorer.enabled` setting to specify whether or not to show the `Git Stashes` explorer
|
- Adds `gitlens.stashExplorer.enabled` setting to specify whether or not to show the `Git Stashes` custom view
|
||||||
- Adds `Toggle Git Stashed Explorer` command (`gitlens.stashExplorer.toggle`) - toggles the `Git Stashes` explorer on and off
|
- Adds `Toggle Git Stashes Explorer` command (`gitlens.stashExplorer.toggle`) - toggles the `Git Stashes` custom view on and off
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
- Hides the `Git Stashes` explorer by default
|
- Hides the `Git Stashes` custom view by default
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
- Fixes [#108](https://github.com/eamodio/vscode-gitlens/issues/108) - Option to remove stash explorer from the main explorer?
|
- Fixes [#108](https://github.com/eamodio/vscode-gitlens/issues/108) - Option to remove stash explorer from the main explorer?
|
||||||
|
|
||||||
## [4.3.0] - 2017-07-03
|
## [4.3.0] - 2017-07-03
|
||||||
## Added
|
## Added
|
||||||
- Adds `Git Stashes` view to the Explorer activity
|
- Adds `Git Stashes` custom view to the Explorer activity
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Shows all of the stashed changes in the repository
|
- Shows all of the stashed changes in the repository
|
||||||
- Provides toolbar buttons to `Stash Changes` and `Refresh`
|
- Provides toolbar buttons to `Stash Changes` and `Refresh`
|
||||||
|
|||||||
105
README.md
@@ -10,7 +10,7 @@ GitLens **supercharges** the built-in Visual Studio Code Git capabilities. It he
|
|||||||
GitLens provides an unobtrusive blame annotation at the end of the current line, a status bar item showing the commit information (author and date, by default) of the current line, code lens showing the most recent commit and # of authors of the file and/or code block, and many commands for exploring commits and histories, comparing and navigating revisions, stash access, repository status, and more. GitLens is also [highly customizable](#extension-settings) to meet your specific needs — find code lens intrusive or the current line blame annotation distracting — no problem, it is easy to [turn them off or change how they behave](#extension-settings).
|
GitLens provides an unobtrusive blame annotation at the end of the current line, a status bar item showing the commit information (author and date, by default) of the current line, code lens showing the most recent commit and # of authors of the file and/or code block, and many commands for exploring commits and histories, comparing and navigating revisions, stash access, repository status, and more. GitLens is also [highly customizable](#extension-settings) to meet your specific needs — find code lens intrusive or the current line blame annotation distracting — no problem, it is easy to [turn them off or change how they behave](#extension-settings).
|
||||||
|
|
||||||
### Preview — featuring blame annotations, code lens, status bar details, quick pick menus for navigation and exploration, compare with previous, and more
|
### Preview — featuring blame annotations, code lens, status bar details, quick pick menus for navigation and exploration, compare with previous, and more
|
||||||

|

|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -18,16 +18,16 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds an unobtrusive, highly [customizable](#line-blame-annotation-settings) and [themeable](#theme-settings), **Git blame annotation** to the end of the current line ([optional](#line-blame-annotation-settings), on by default)
|
- Adds an unobtrusive, highly [customizable](#line-blame-annotation-settings) and [themeable](#theme-settings), **Git blame annotation** to the end of the current line ([optional](#line-blame-annotation-settings), on by default)
|
||||||
|
|
||||||

|

|
||||||
- Contains the author, date, and message of the line's most recent commit, by [default](#line-blame-annotation-settings)
|
- Contains the author, date, and message of the line's most recent commit, by [default](#line-blame-annotation-settings)
|
||||||
- Adds a `details` hover annotation to the current line annotation, which provides more commit details ([optional](#line-blame-annotation-settings), on by default)
|
- Adds a `details` hover annotation to the current line annotation, which provides more commit details ([optional](#line-blame-annotation-settings), on by default)
|
||||||
- Adds a `changes` (diff) hover annotation to the current line annotation, which provides **instant** access to the line's previous version ([optional](#line-blame-annotation-settings), on by default)
|
- Adds a `changes` (diff) hover annotation to the current line annotation, which provides **instant** access to the line's previous version ([optional](#line-blame-annotation-settings), on by default)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Adds on-demand, beautiful, highly [customizable](#file-blame-annotation-settings) and [themeable](#theme-settings), **Git blame annotations** of the whole file
|
- Adds on-demand, beautiful, highly [customizable](#file-blame-annotation-settings) and [themeable](#theme-settings), **Git blame annotations** of the whole file
|
||||||
|
|
||||||

|

|
||||||
- Choose between `gutter` (default) and `hover` [annotation styles](#file-blame-annotation-settings)
|
- Choose between `gutter` (default) and `hover` [annotation styles](#file-blame-annotation-settings)
|
||||||
- Contains the commit message and date, by [default](#file-blame-annotation-settings)
|
- Contains the commit message and date, by [default](#file-blame-annotation-settings)
|
||||||
- Adds a `details` hover annotation to the line's annotation, which provides more commit details ([optional](#file-blame-annotation-settings), on by default)
|
- Adds a `details` hover annotation to the line's annotation, which provides more commit details ([optional](#file-blame-annotation-settings), on by default)
|
||||||
@@ -37,7 +37,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds [customizable](#status-bar-settings) **blame information** about the current line to the **status bar** ([optional](#status-bar-settings), on by default)
|
- Adds [customizable](#status-bar-settings) **blame information** about the current line to the **status bar** ([optional](#status-bar-settings), on by default)
|
||||||
|
|
||||||

|

|
||||||
- Contains the commit author and date, by [default](#status-bar-settings)
|
- Contains the commit author and date, by [default](#status-bar-settings)
|
||||||
- Clicking the status bar item will, by [default](#status-bar-settings), show a **commit details quick pick menu** with commands for comparing, navigating and exploring commits, and more
|
- Clicking the status bar item will, by [default](#status-bar-settings), show a **commit details quick pick menu** with commands for comparing, navigating and exploring commits, and more
|
||||||
- Provides [customizable](#status-bar-settings) click behavior — choose between one of the following
|
- Provides [customizable](#status-bar-settings) click behavior — choose between one of the following
|
||||||
@@ -70,7 +70,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds **code lens** to the top of the file and on code blocks ([optional](#code-lens-settings), on by default)
|
- Adds **code lens** to the top of the file and on code blocks ([optional](#code-lens-settings), on by default)
|
||||||
|
|
||||||

|

|
||||||
- **Recent Change** — author and date of the most recent commit for the file or code block
|
- **Recent Change** — author and date of the most recent commit for the file or code block
|
||||||
- Clicking the code lens will, by [default](#code-lens-settings), show a **commit file details quick pick menu** with commands for comparing, navigating and exploring commits, and more
|
- Clicking the code lens will, by [default](#code-lens-settings), show a **commit file details quick pick menu** with commands for comparing, navigating and exploring commits, and more
|
||||||
- **Authors** — number of authors of the file or code block and the most prominent author (if there is more than one)
|
- **Authors** — number of authors of the file or code block and the most prominent author (if there is more than one)
|
||||||
@@ -97,33 +97,75 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Compare File with Branch...` command (`gitlens.diffWithBranch`) to compare the active file with the same file on the selected branch
|
- Adds a `Compare File with Branch...` command (`gitlens.diffWithBranch`) to compare the active file with the same file on the selected branch
|
||||||
|
|
||||||
- Adds a `Compare File with Next Commit` command (`gitlens.diffWithNext`) with a shortcut of `alt+.` to compare the active file/diff with the next commit revision
|
- Adds a `Compare File with Next Revision` command (`gitlens.diffWithNext`) with a shortcut of `alt+.` to compare the active file/diff with the next commit revision
|
||||||
|
|
||||||
- Adds a `Compare File with Previous` command (`gitlens.diffWithPrevious`) with a shortcut of `alt+,` to compare the active file/diff with the previous commit revision
|
- Adds a `Compare File with Previous Revision` command (`gitlens.diffWithPrevious`) with a shortcut of `alt+,` to compare the active file/diff with the previous commit revision
|
||||||
|
|
||||||
- Adds a `Compare Line Commit with Previous` command (`gitlens.diffLineWithPrevious`) with a shortcut of `shift+alt+,` to compare the active file/diff with the previous line commit revision
|
- Adds a `Compare Line Revision with Previous` command (`gitlens.diffLineWithPrevious`) with a shortcut of `shift+alt+,` to compare the active file/diff with the previous line commit revision
|
||||||
|
|
||||||
- Adds a `Compare File with Revision...` command (`gitlens.diffWithRevision`) to compare the active file with the selected revision of the same file
|
- Adds a `Compare File with Revision...` command (`gitlens.diffWithRevision`) to compare the active file with the selected revision of the same file
|
||||||
|
|
||||||
- Adds a `Compare File with Working Tree` command (`gitlens.diffWithWorking`) with a shortcut of `shift+alt+w` to compare the most recent commit revision of the active file/diff with the working tree
|
- Adds a `Compare File with Working Revision` command (`gitlens.diffWithWorking`) with a shortcut of `shift+alt+w` to compare the most recent commit revision of the active file/diff with the working tree
|
||||||
|
|
||||||
- Adds a `Compare Line Commit with Working Tree` command (`gitlens.diffLineWithWorking`) with a shortcut of `alt+w` to compare the commit revision of the active line with the working tree
|
- Adds a `Compare Line Revision with Working` command (`gitlens.diffLineWithWorking`) with a shortcut of `alt+w` to compare the commit revision of the active line with the working tree
|
||||||
|
|
||||||
### Navigate and Explore
|
### Navigate and Explore
|
||||||
|
|
||||||
- Adds a `Git Stashes` explorer to the Explorer activity ([optional](#git-stashes-explorer-settings), off by default)
|
- Adds a [customizable](#gitlens-custom-view-settings) `GitLens` custom view to the Explorer activity
|
||||||
|
|
||||||

|
- `Repository View` - provides a full repository explorer
|
||||||
|
|
||||||
- Shows all of the stashed changes in the repository
|

|
||||||
- Provides toolbar buttons to `Stash Changes` and `Refresh`
|
|
||||||
- Provides a context menu with `Apply Stashed Changes` and `Delete Stashed Changes` commands — both require a confirmation
|
- `Repository Status` node — provides the status of the repository
|
||||||
- Expand each stash to quickly see the set of files changed, complete with status indicators for adds, changes, renames, and deletes
|
- Provides the name of the current branch, its upstream tracking branch (if available), and its upstream status (if available)
|
||||||
- Provides a context menu with `Open Changes`, `Open File`, `Open Stashed File`, `Open File in Remote`, and `Compare File with Working Tree` commands
|
- Provides indicator dots on the repository icon which denote the following:
|
||||||
|
- `None` - up-to-date with the upstream
|
||||||
|
- `Green` - ahead of the upstream
|
||||||
|
- `Red` - behind the upstream
|
||||||
|
- `Yellow` - both ahead of and behind the upstream
|
||||||
|
- Provides additional nodes, if the current branch is not synchronized with the upstream, to quickly see and explore the specific commits ahead and/or behind the upstream
|
||||||
|
- Provides a context menu with `Open Repository in Remote`, and `Refresh` commands
|
||||||
|
|
||||||
|
- `Branches` node — provides a list of the local branches
|
||||||
|
- Indicates which branch is the current branch and [optionally](#gitlens-custom-view-settings) shows the remote tracking branch
|
||||||
|
- Expand each branch 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 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 revision (commit) with `Open Commit in Remote`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Open Files`, `Open Revisions`, `Show Commit Details`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each branch with `Open Branch in Remote`, and `Refresh` commands
|
||||||
|
- Provides a context menu with `Open Branches in Remote`, and `Refresh` commands
|
||||||
|
|
||||||
|
- `Remotes` node — provides a list of remotes
|
||||||
|
- Expand each remote to see its list of branches
|
||||||
|
- Expand each branch 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 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 revision (commit) with `Open Commit in Remote`, `Copy Commit ID to Clipboard`, `Copy Commit Message to Clipboard`, `Open Files`, `Open Revisions`, `Show Commit Details`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each remote with `Open Branches in Remote`, `Open Repository in Remote`, and `Refresh` commands
|
||||||
|
- Provides a context menu with a `Refresh` command
|
||||||
|
|
||||||
|
- `Stashes` node — provides a list of stashed changes
|
||||||
|
- Expand each stash to quickly see the set of files stashed, complete with status indicators for adds, changes, renames, and deletes
|
||||||
|
- Provides a context menu with `Stash Changes`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each stash with `Apply Stashed Changes` (confirmation required), `Delete Stashed Changes` (confirmation required), `Copy Commit Message to Clipboard`, `Open Files`, `Open Revisions`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each stashed file with `Open Changes`, `Open Changes with Working Tree`, `Open File`, `Open Revision`, `Open File in Remote`, `Apply Changes`, and `Show File History` commands
|
||||||
|
|
||||||
|
- `History View` - provides the revision history of the active file
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Automatically updates to track the active editor
|
||||||
|
- Provides a context menu with `Open File`, `Open File in Remote`, and `Refresh` commands
|
||||||
|
- Provides a context menu on each revision (commit) 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
|
||||||
|
|
||||||
|
- Quickly switch between views using the `Switch to Repository View` or `Switch to History View` commands
|
||||||
|
- Provides toolbar commands to `Search Commits`, `Switch to Repository View` or `Switch to History View`, and `Refresh`
|
||||||
|
|
||||||
- Adds a `Search Commits` command (`gitlens.showCommitSearch`) with a shortcut of `alt+/` to search for commits by message, author, file(s), or commit id
|
- Adds a `Search Commits` command (`gitlens.showCommitSearch`) with a shortcut of `alt+/` to search for commits by message, author, file(s), or commit id
|
||||||
|
|
||||||
- Adds commands to open files, commits, branches, and the repository in the supported remote services, currently **BitBucket, GitHub, GitLab, and Visual Studio Team Services** — only available if a Git upstream service is configured in the repository
|
- Adds commands to open files, commits, branches, and the repository in the supported remote services, currently **BitBucket, GitHub, GitLab, and Visual Studio Team Services** — only available if a Git upstream service is configured in the repository
|
||||||
|
- `Open Branches in Remote` command (`gitlens.openBranchesInRemote`) — opens the branches in the supported remote service
|
||||||
- `Open Branch in Remote` command (`gitlens.openBranchInRemote`) — opens the current branch commits in the supported remote service
|
- `Open Branch in Remote` command (`gitlens.openBranchInRemote`) — opens the current branch commits in the supported remote service
|
||||||
- `Open Commit in Remote` command (`gitlens.openCommitInRemote`) — opens the commit revision of the active line in the supported remote service
|
- `Open Commit in Remote` command (`gitlens.openCommitInRemote`) — opens the commit revision of the active line in the supported remote service
|
||||||
- `Open File in Remote` command (`gitlens.openFileInRemote`) — opens the active file/revision in the supported remote service
|
- `Open File in Remote` command (`gitlens.openFileInRemote`) — opens the active file/revision in the supported remote service
|
||||||
@@ -131,7 +173,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Show Current Branch History` command (`gitlens.showQuickRepoHistory`) with a shortcut of `shift+alt+h` to show a paged **branch history quick pick menu** of the current branch for exploring its commit history
|
- Adds a `Show Current Branch History` command (`gitlens.showQuickRepoHistory`) with a shortcut of `shift+alt+h` to show a paged **branch history quick pick menu** of the current branch for exploring its commit history
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Provides entries to `Show Commit Search` and `Open Branch in <remote-service>` when available
|
- Provides entries to `Show Commit Search` and `Open Branch in <remote-service>` when available
|
||||||
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
||||||
@@ -142,7 +184,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Show File History` command (`gitlens.showQuickFileHistory`) to show a paged **file history quick pick menu** of the active file for exploring its commit history
|
- Adds a `Show File History` command (`gitlens.showQuickFileHistory`) to show a paged **file history quick pick menu** of the active file for exploring its commit history
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Provides entries to `Show Branch History` and `Open File in <remote-service>` when available
|
- Provides entries to `Show Branch History` and `Open File in <remote-service>` when available
|
||||||
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
||||||
@@ -150,7 +192,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Show Commit Details` command (`gitlens.showQuickCommitDetails`) to show a **commit details quick pick menu** of the most recent commit of the active file
|
- Adds a `Show Commit Details` command (`gitlens.showQuickCommitDetails`) to show a **commit details quick pick menu** of the most recent commit of the active file
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Quickly see the set of files changed in the commit, complete with status indicators for adds, changes, renames, and deletes
|
- Quickly see the set of files changed in the commit, complete with status indicators for adds, changes, renames, and deletes
|
||||||
- Provides entries to `Copy to Clipboard`, `Directory Compare`, `Open Changed Files`, `Open File in <remote-service>` when available, and more
|
- Provides entries to `Copy to Clipboard`, `Directory Compare`, `Open Changed Files`, `Open File in <remote-service>` when available, and more
|
||||||
@@ -160,7 +202,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Show Commit File Details` command (`gitlens.showQuickCommitFileDetails`) with a shortcut of `alt+c` to show a **file commit details quick pick menu** of the most recent commit of the active file
|
- Adds a `Show Commit File Details` command (`gitlens.showQuickCommitFileDetails`) with a shortcut of `alt+c` to show a **file commit details quick pick menu** of the most recent commit of the active file
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Provides entries to `Show Commit Details`, `Show File History`, `Compare File with...`, `Copy to Clipboard`, `Open File`, `Open File in <remote-service>` when available, and more
|
- Provides entries to `Show Commit Details`, `Show File History`, `Compare File with...`, `Copy to Clipboard`, `Open File`, `Open File in <remote-service>` when available, and more
|
||||||
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
||||||
@@ -168,7 +210,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Show Repository Status` command (`gitlens.showQuickRepoStatus`) with a shortcut of `alt+s` to show a **repository status quick pick menu** for visualizing the current repository status
|
- Adds a `Show Repository Status` command (`gitlens.showQuickRepoStatus`) with a shortcut of `alt+s` to show a **repository status quick pick menu** for visualizing the current repository status
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Quickly see upstream status (if an Git upstream is configured) — complete with ahead and behind information
|
- Quickly see upstream status (if an Git upstream is configured) — complete with ahead and behind information
|
||||||
- If you are ahead of the upstream, an entry will be shown with the number of commits ahead. Choosing it will show a limited **branch history quick pick menu** containing just the commits ahead of the upstream
|
- If you are ahead of the upstream, an entry will be shown with the number of commits ahead. Choosing it will show a limited **branch history quick pick menu** containing just the commits ahead of the upstream
|
||||||
@@ -180,14 +222,14 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
|
|
||||||
- Adds a `Show Stashed Changes` command (`gitlens.showQuickStashList`) to show a **stashed changes quick pick menu** for exploring your repository stash history
|
- Adds a `Show Stashed Changes` command (`gitlens.showQuickStashList`) to show a **stashed changes quick pick menu** for exploring your repository stash history
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Provides entries to `Stash Changes`
|
- Provides entries to `Stash Changes`
|
||||||
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
- Navigate back to the previous quick pick menu via `alt+left arrow`, if available
|
||||||
|
|
||||||
- Choosing a stash entry shows a **stash details quick pick menu** which is very similar to the **commit details quick pick menu** above
|
- Choosing a stash entry shows a **stash details quick pick menu** which is very similar to the **commit details quick pick menu** above
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
- Quickly see the set of files changed in the stash, complete with status indicators for adds, changes, renames, and deletes
|
- Quickly see the set of files changed in the stash, complete with status indicators for adds, changes, renames, and deletes
|
||||||
- Provides entries to `Copy Message to Clipboard`, `Directory Compare`, and `Open Changed Files`
|
- Provides entries to `Copy Message to Clipboard`, `Directory Compare`, and `Open Changed Files`
|
||||||
@@ -217,6 +259,7 @@ GitLens provides an unobtrusive blame annotation at the end of the current line,
|
|||||||
- Adds a `Apply Stashed Changes` command (`gitlens.stashApply`) to chose a stash entry to apply to the working tree from a quick pick menu
|
- Adds a `Apply Stashed Changes` command (`gitlens.stashApply`) to chose a stash entry to apply to the working tree from a quick pick menu
|
||||||
|
|
||||||
- Adds a `Stash Changes` command (`gitlens.stashSave`) to save any working tree changes to the stash — can optionally provide a stash message
|
- Adds a `Stash Changes` command (`gitlens.stashSave`) to save any working tree changes to the stash — can optionally provide a stash message
|
||||||
|
- Also adds the command to the Source Control items context menu to stash an individual or group of files, works with multi-select too!
|
||||||
|
|
||||||
## Insiders
|
## Insiders
|
||||||
|
|
||||||
@@ -289,12 +332,16 @@ GitLens is highly customizable and provides many configuration settings to allow
|
|||||||
|`gitlens.codeLens.customLocationSymbols`|Specifies the set of document symbols where Git code lens will be shown in the document
|
|`gitlens.codeLens.customLocationSymbols`|Specifies the set of document symbols where Git code lens will be shown in the document
|
||||||
|`gitlens.codeLens.perLanguageLocations`|Specifies where Git code lens will be shown in the document for the specified languages
|
|`gitlens.codeLens.perLanguageLocations`|Specifies where Git code lens will be shown in the document for the specified languages
|
||||||
|
|
||||||
### Git Stashes Explorer Settings
|
### GitLens Custom View Settings
|
||||||
|
|
||||||
|Name | Description
|
|Name | Description
|
||||||
|-----|------------
|
|-----|------------
|
||||||
|`gitlens.stashExplorer.stashFormat`|Specifies the format of stashed changes in the `Git Stashes` explorer <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.view`|Specifies the starting view (mode) of the `GitLens` custom view<br />`history` - shows the commit history of the active file<br />`repository` - shows a repository explorer"
|
||||||
|`gitlens.stashExplorer.stashFileFormat`|Specifies the format of a stashed file in the `Git Stashes` explorer <br />Available tokens<br /> ${file} - file name<br /> ${path} - file path
|
|`gitlens.gitExplorer.showTrackingBranch`|Specifies whether or not to show the tracking branch when displaying local branches in the `GitLens` custom view"
|
||||||
|
|`gitlens.gitExplorer.commitFormat`|Specifies the format of committed changes in the `GitLens` custom 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` custom view<br />Available tokens<br /> ${file} - file name<br /> ${filePath} - file name and path<br /> ${path} - file path
|
||||||
|
|`gitlens.gitExplorer.stashFormat`|Specifies the format of stashed changes in the `GitLens` custom 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` custom view<br />Available tokens<br /> ${file} - file name<br /> ${filePath} - file name and path<br /> ${path} - file path
|
||||||
|
|
||||||
### Status Bar Settings
|
### Status Bar Settings
|
||||||
|
|
||||||
@@ -338,7 +385,6 @@ GitLens is highly customizable and provides many configuration settings to allow
|
|||||||
|
|
||||||
|Name | Description
|
|Name | Description
|
||||||
|-----|------------
|
|-----|------------
|
||||||
|`gitlens.advanced.toggleWhitespace.enabled`|Specifies whether or not to toggle whitespace off then showing blame annotations (*may* be required by certain fonts/themes)
|
|
||||||
|`gitlens.advanced.telemetry.enabled`|Specifies whether or not to enable GitLens telemetry (even if enabled still abides by the overall `telemetry.enableTelemetry` setting
|
|`gitlens.advanced.telemetry.enabled`|Specifies whether or not to enable GitLens telemetry (even if enabled still abides by the overall `telemetry.enableTelemetry` setting
|
||||||
|`gitlens.advanced.menus`|Specifies which commands will be added to which menus
|
|`gitlens.advanced.menus`|Specifies which commands will be added to which menus
|
||||||
|`gitlens.advanced.caching.enabled`|Specifies whether git output will be cached
|
|`gitlens.advanced.caching.enabled`|Specifies whether git output will be cached
|
||||||
@@ -351,7 +397,6 @@ GitLens is highly customizable and provides many configuration settings to allow
|
|||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- If the `Copy to * clipboard` commands don't work on Linux -- `xclip` needs to be installed. You can install it via `sudo apt-get install xclip`
|
- If the `Copy to * clipboard` commands don't work on Linux -- `xclip` needs to be installed. You can install it via `sudo apt-get install xclip`
|
||||||
- Visible whitespace causes issues ([vscode issue #11485](https://github.com/Microsoft/vscode/issues/11485)) with the `expanded` and `compact` blame annotation styles when using a non-monospace font -- set `"gitlens.advanced.toggleWhitespace.enabled": true` if you are using a non-monospace font
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#C5C5C5"/><rect height="3" width="11" y="7" x="3" fill="#C5C5C5"/></svg>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect fill="#C5C5C5" x="6.5" y="5.5" width="3" height="11"/>
|
||||||
|
<rect fill="#C5C5C5" x="2.5" y="9.5" width="11" height="3"/>
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 253 B |
4
images/dark/icon-branch.svg
Normal 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="m13,8c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -2,0.89 -2,2c0,0.73 0.41,1.38 1,1.72l0,0.3c-0.02,0.52 -0.23,0.98 -0.63,1.38c-0.4,0.4 -0.86,0.61 -1.38,0.63c-0.83,0.02 -1.48,0.16 -2,0.45l0,-4.76c0.59,-0.34 1,-0.98 1,-1.72c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -1.99,0.89 -1.99,2c0,0.73 0.41,1.38 1,1.72l0,6.56c-0.59,0.35 -1,0.99 -1,1.72c0,1.11 0.89,2 2,2c1.11,0 2,-0.89 2,-2c0,-0.53 -0.2,-1 -0.53,-1.36c0.09,-0.06 0.48,-0.41 0.59,-0.47c0.25,-0.11 0.56,-0.17 0.94,-0.17c1.05,-0.05 1.95,-0.45 2.75,-1.25c0.8,-0.8 1.2,-1.98 1.25,-3.02l-0.02,0c0.61,-0.36 1.02,-1 1.02,-1.73l0,0zm-8,-3.2c0.66,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2c-0.65,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2l0,0zm0,12.41c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0zm6,-8c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve">
|
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="#C5C5C5" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path>
|
<path fill="#C5C5C5" d="m11.86,10c-0.45,-1.72 -2,-3 -3.86,-3c-1.86,0 -3.41,1.28 -3.86,3l-3.14,0l0,2l3.14,0c0.45,1.72 2,3 3.86,3c1.86,0 3.41,-1.28 3.86,-3l3.14,0l0,-2l-3.14,0zm-3.86,3.2c-1.22,0 -2.2,-0.98 -2.2,-2.2c0,-1.22 0.98,-2.2 2.2,-2.2c1.22,0 2.2,0.98 2.2,2.2c0,1.22 -0.98,2.2 -2.2,2.2z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 428 B |
4
images/dark/icon-download.svg
Normal 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="m9,15l2,0l-3,3l-3,-3l2,0l0,-5l2,0l0,5l0,0zm3,-8c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 557 B |
4
images/dark/icon-history.svg
Normal 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="m9,16l-2,0l0,-7l5,0l0,2l-3,0l0,5l0,0zm-1,-12c-2.19,0 -4.13,1.02 -5.41,2.59l-1.59,-1.59l0,4l4,0l-1.5,-1.5c1.05,-1.33 2.67,-2.2 4.5,-2.2c3.14,0 5.7,2.56 5.7,5.7c0,3.14 -2.56,5.7 -5.7,5.7c-3.14,0 -5.7,-2.56 -5.7,-5.7c0,-0.34 0.03,-0.67 0.09,-1l-1.31,0c-0.05,0.33 -0.08,0.66 -0.08,1c0,3.86 3.14,7 7,7c3.86,0 7,-3.14 7,-7c0,-3.86 -3.14,-7 -7,-7l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 500 B |
@@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16">
|
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3a2.98 2.98 0 0 1-2.107-.868 2.98 2.98 0 0 1-.873-2.111 3.004 3.004 0 0 1 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012L13.115 4.1 8.196 0H7.059v2.404A6.759 6.759 0 0 0 .938 9.125c0 1.809.707 3.508 1.986 4.782a6.707 6.707 0 0 0 4.784 1.988 6.758 6.758 0 0 0 6.75-6.75 6.741 6.741 0 0 0-1.007-3.536z" fill="#2D2D30"/>
|
<path fill="#C5C5C5" d="m12.901149,9.091851l-0.094,0.071c-0.269,0.333 -0.746,1.096 -0.91,2.375c0.057,0.277 0.092,0.495 0.092,0.545c0,2.206 -1.794,4 -4,4a3.986,3.986 0 0 1 -2.817,-1.164a3.987,3.987 0 0 1 -1.163,-2.815c0,-2.206 1.794,-4 4,-4l0.351,0.025l0,1.85s1.626,-1.342 1.631,-1.339l1.869,-1.577l-3.5,-2.917l0,2.218l-0.371,-0.03a5.75,5.75 0 0 0 -4.055,9.826a5.75,5.75 0 0 0 9.826,-4.056a5.725,5.725 0 0 0 -0.859,-3.012z" />
|
||||||
<path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4a3.986 3.986 0 0 1-2.817-1.164 3.987 3.987 0 0 1-1.163-2.815c0-2.206 1.794-4 4-4l.351.025v1.85S9.685 5.679 9.69 5.682l1.869-1.577-3.5-2.917v2.218l-.371-.03a5.75 5.75 0 0 0-4.055 9.826 5.75 5.75 0 0 0 9.826-4.056 5.725 5.725 0 0 0-.859-3.012z" fill="#C5C5C5"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 987 B After Width: | Height: | Size: 553 B |
4
images/dark/icon-remote.svg
Normal 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="m12.519592,15.157073l-9.039184,0c-1.367793,0 -2.480539,-1.112828 -2.480539,-2.480622s1.112746,-2.480539 2.480539,-2.480539l0.281314,0c0.349178,-0.47173 0.888523,-0.771191 1.476341,-0.815025c0.321917,-1.471535 1.619609,-2.537962 3.165139,-2.537962c1.221543,0 2.341663,0.699516 2.889377,1.772488c0.083027,-0.008618 0.166386,-0.012926 0.250076,-0.012926c1.190221,0 2.194667,0.874105 2.378785,2.027867c0.670514,0.460047 1.07869,1.225023 1.07869,2.046096c0,1.367793 -1.112828,2.480622 -2.480539,2.480622z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 655 B |
5
images/dark/icon-repo-green.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
<ellipse fill="#32cd32" stroke="#C5C5C5" stroke-width="0.5" rx="3" ry="3" cx="13" cy="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 586 B |
5
images/dark/icon-repo-red.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
<ellipse fill="#cd3131" stroke="#C5C5C5" stroke-width="0.5" rx="3" ry="3" cx="13" cy="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 586 B |
5
images/dark/icon-repo-yellow.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
<ellipse fill="#cdcd32" stroke="#C5C5C5" stroke-width="0.5" rx="3" ry="3" cx="13" cy="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 586 B |
4
images/dark/icon-repo.svg
Normal 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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 490 B |
4
images/dark/icon-search.svg
Normal 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="m14.414133,16.199437l-3.415492,-3.433421c0.627518,-0.878526 0.995065,-1.945307 0.995065,-3.110698c0,-2.967265 -2.411463,-5.378728 -5.378728,-5.378728c-2.967265,0 -5.378728,2.411463 -5.378728,5.378728c0,2.967265 2.411463,5.378728 5.378728,5.378728c1.165391,0 2.223207,-0.367546 3.110698,-0.995065l3.433421,3.415492c0.170326,0.179291 0.403405,0.268936 0.627518,0.268936c0.224114,0 0.466156,-0.080681 0.627518,-0.268936c0.349617,-0.349617 0.349617,-0.914384 0,-1.264001l0,0.008965zm-7.799155,-2.330782c-2.321817,0 -4.213337,-1.891519 -4.213337,-4.213337c0,-2.321817 1.891519,-4.213337 4.213337,-4.213337c2.321817,0 4.213337,1.891519 4.213337,4.213337c0,2.321817 -1.891519,4.213337 -4.213337,4.213337l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 857 B |
4
images/dark/icon-stash.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="22px">
|
||||||
|
<path fill="#C5C5C5" d="m14.687501,11.955358l-1.079554,-6.821251c-0.076429,-0.458572 -0.477679,-0.821607 -0.955357,-0.821607l-9.30518,0c-0.477679,0 -0.878929,0.363036 -0.955357,0.821607l-1.079554,6.821251l0,4.776787c0,0.525447 0.429911,0.955357 0.955357,0.955357l11.464288,0c0.525447,0 0.955357,-0.429911 0.955357,-0.955357l0,-4.776787l0,0zm-3.133572,0.525447l-0.420357,0.850268c-0.162411,0.324821 -0.496786,0.535 -0.869375,0.535l-4.547501,0c-0.363036,0 -0.687857,-0.210179 -0.850268,-0.525447l-0.420357,-0.869375c-0.162411,-0.315268 -0.496786,-0.525447 -0.850268,-0.525447l-1.327947,0l0.955357,-6.687501l9.553573,0l0.955357,6.687501l-1.318393,0c-0.372589,0 -0.697411,0.210179 -0.869375,0.525447l0.009554,0.009554z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 893 B |
4
images/dark/icon-upload.svg
Normal 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="m7,12l-2,0l3,-3l3,3l-2,0l0,5l-2,0l0,-5l0,0zm5,-4c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 558 B |
@@ -1 +1,5 @@
|
|||||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#424242"/><rect height="3" width="11" y="7" x="3" fill="#424242"/></svg>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect fill="#424242" x="6.5" y="5.5" width="3" height="11"/>
|
||||||
|
<rect fill="#424242" x="2.5" y="9.5" width="11" height="3"/>
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 253 B |
4
images/light/icon-branch.svg
Normal 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="m13,8c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -2,0.89 -2,2c0,0.73 0.41,1.38 1,1.72l0,0.3c-0.02,0.52 -0.23,0.98 -0.63,1.38c-0.4,0.4 -0.86,0.61 -1.38,0.63c-0.83,0.02 -1.48,0.16 -2,0.45l0,-4.76c0.59,-0.34 1,-0.98 1,-1.72c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -1.99,0.89 -1.99,2c0,0.73 0.41,1.38 1,1.72l0,6.56c-0.59,0.35 -1,0.99 -1,1.72c0,1.11 0.89,2 2,2c1.11,0 2,-0.89 2,-2c0,-0.53 -0.2,-1 -0.53,-1.36c0.09,-0.06 0.48,-0.41 0.59,-0.47c0.25,-0.11 0.56,-0.17 0.94,-0.17c1.05,-0.05 1.95,-0.45 2.75,-1.25c0.8,-0.8 1.2,-1.98 1.25,-3.02l-0.02,0c0.61,-0.36 1.02,-1 1.02,-1.73l0,0zm-8,-3.2c0.66,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2c-0.65,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2l0,0zm0,12.41c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0zm6,-8c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve">
|
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="#6c6c6c" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path>
|
<path fill="#424242" d="m11.86,10c-0.45,-1.72 -2,-3 -3.86,-3c-1.86,0 -3.41,1.28 -3.86,3l-3.14,0l0,2l3.14,0c0.45,1.72 2,3 3.86,3c1.86,0 3.41,-1.28 3.86,-3l3.14,0l0,-2l-3.14,0zm-3.86,3.2c-1.22,0 -2.2,-0.98 -2.2,-2.2c0,-1.22 0.98,-2.2 2.2,-2.2c1.22,0 2.2,0.98 2.2,2.2c0,1.22 -0.98,2.2 -2.2,2.2z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 480 B After Width: | Height: | Size: 428 B |
4
images/light/icon-download.svg
Normal 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="m9,15l2,0l-3,3l-3,-3l2,0l0,-5l2,0l0,5l0,0zm3,-8c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 557 B |
4
images/light/icon-history.svg
Normal 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="m9,16l-2,0l0,-7l5,0l0,2l-3,0l0,5l0,0zm-1,-12c-2.19,0 -4.13,1.02 -5.41,2.59l-1.59,-1.59l0,4l4,0l-1.5,-1.5c1.05,-1.33 2.67,-2.2 4.5,-2.2c3.14,0 5.7,2.56 5.7,5.7c0,3.14 -2.56,5.7 -5.7,5.7c-3.14,0 -5.7,-2.56 -5.7,-5.7c0,-0.34 0.03,-0.67 0.09,-1l-1.31,0c-0.05,0.33 -0.08,0.66 -0.08,1c0,3.86 3.14,7 7,7c3.86,0 7,-3.14 7,-7c0,-3.86 -3.14,-7 -7,-7l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 500 B |
@@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16">
|
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d='M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3a2.98 2.98 0 0 1-2.107-.868 2.98 2.98 0 0 1-.873-2.111 3.004 3.004 0 0 1 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012L13.115 4.1 8.196 0H7.059v2.404A6.759 6.759 0 0 0 .938 9.125c0 1.809.707 3.508 1.986 4.782a6.707 6.707 0 0 0 4.784 1.988 6.758 6.758 0 0 0 6.75-6.75 6.741 6.741 0 0 0-1.007-3.536z' fill='#F6F6F6'/>
|
<path fill="#424242" d="m12.901149,9.091851l-0.094,0.071c-0.269,0.333 -0.746,1.096 -0.91,2.375c0.057,0.277 0.092,0.495 0.092,0.545c0,2.206 -1.794,4 -4,4a3.986,3.986 0 0 1 -2.817,-1.164a3.987,3.987 0 0 1 -1.163,-2.815c0,-2.206 1.794,-4 4,-4l0.351,0.025l0,1.85s1.626,-1.342 1.631,-1.339l1.869,-1.577l-3.5,-2.917l0,2.218l-0.371,-0.03a5.75,5.75 0 0 0 -4.055,9.826a5.75,5.75 0 0 0 9.826,-4.056a5.725,5.725 0 0 0 -0.859,-3.012z" />
|
||||||
<path d='M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4a3.986 3.986 0 0 1-2.817-1.164 3.987 3.987 0 0 1-1.163-2.815c0-2.206 1.794-4 4-4l.351.025v1.85S9.685 5.679 9.69 5.682l1.869-1.577-3.5-2.917v2.218l-.371-.03a5.75 5.75 0 0 0-4.055 9.826 5.75 5.75 0 0 0 9.826-4.056 5.725 5.725 0 0 0-.859-3.012z' fill='#424242'/>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 987 B After Width: | Height: | Size: 553 B |
4
images/light/icon-remote.svg
Normal 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="m12.519592,15.157073l-9.039184,0c-1.367793,0 -2.480539,-1.112828 -2.480539,-2.480622s1.112746,-2.480539 2.480539,-2.480539l0.281314,0c0.349178,-0.47173 0.888523,-0.771191 1.476341,-0.815025c0.321917,-1.471535 1.619609,-2.537962 3.165139,-2.537962c1.221543,0 2.341663,0.699516 2.889377,1.772488c0.083027,-0.008618 0.166386,-0.012926 0.250076,-0.012926c1.190221,0 2.194667,0.874105 2.378785,2.027867c0.670514,0.460047 1.07869,1.225023 1.07869,2.046096c0,1.367793 -1.112828,2.480622 -2.480539,2.480622z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 655 B |
5
images/light/icon-repo-green.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
<ellipse fill="#32cd32" stroke="#424242" stroke-width="0.5" rx="3" ry="3" cx="13" cy="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 586 B |
5
images/light/icon-repo-red.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
<ellipse fill="#cd3131" stroke="#424242" stroke-width="0.5" rx="3" ry="3" cx="13" cy="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 586 B |
5
images/light/icon-repo-yellow.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
<ellipse fill="#cdcd32" stroke="#424242" stroke-width="0.5" rx="3" ry="3" cx="13" cy="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 586 B |
4
images/light/icon-repo.svg
Normal 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="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 490 B |
4
images/light/icon-search.svg
Normal 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="m14.414133,16.199437l-3.415492,-3.433421c0.627518,-0.878526 0.995065,-1.945307 0.995065,-3.110698c0,-2.967265 -2.411463,-5.378728 -5.378728,-5.378728c-2.967265,0 -5.378728,2.411463 -5.378728,5.378728c0,2.967265 2.411463,5.378728 5.378728,5.378728c1.165391,0 2.223207,-0.367546 3.110698,-0.995065l3.433421,3.415492c0.170326,0.179291 0.403405,0.268936 0.627518,0.268936c0.224114,0 0.466156,-0.080681 0.627518,-0.268936c0.349617,-0.349617 0.349617,-0.914384 0,-1.264001l0,0.008965zm-7.799155,-2.330782c-2.321817,0 -4.213337,-1.891519 -4.213337,-4.213337c0,-2.321817 1.891519,-4.213337 4.213337,-4.213337c2.321817,0 4.213337,1.891519 4.213337,4.213337c0,2.321817 -1.891519,4.213337 -4.213337,4.213337l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 857 B |
4
images/light/icon-stash.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="22px">
|
||||||
|
<path fill="#424242" d="m14.687501,11.955358l-1.079554,-6.821251c-0.076429,-0.458572 -0.477679,-0.821607 -0.955357,-0.821607l-9.30518,0c-0.477679,0 -0.878929,0.363036 -0.955357,0.821607l-1.079554,6.821251l0,4.776787c0,0.525447 0.429911,0.955357 0.955357,0.955357l11.464288,0c0.525447,0 0.955357,-0.429911 0.955357,-0.955357l0,-4.776787l0,0zm-3.133572,0.525447l-0.420357,0.850268c-0.162411,0.324821 -0.496786,0.535 -0.869375,0.535l-4.547501,0c-0.363036,0 -0.687857,-0.210179 -0.850268,-0.525447l-0.420357,-0.869375c-0.162411,-0.315268 -0.496786,-0.525447 -0.850268,-0.525447l-1.327947,0l0.955357,-6.687501l9.553573,0l0.955357,6.687501l-1.318393,0c-0.372589,0 -0.697411,0.210179 -0.869375,0.525447l0.009554,0.009554z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 893 B |
4
images/light/icon-upload.svg
Normal 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="m7,12l-2,0l3,-3l3,3l-2,0l0,5l-2,0l0,-5l0,0zm5,-4c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 558 B |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 64 KiB |
BIN
images/screenshot-git-custom-view-history.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
images/screenshot-git-custom-view-repository.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 12 KiB |
121
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gitlens",
|
"name": "gitlens",
|
||||||
"version": "4.3.3",
|
"version": "5.0.0-alpha.2",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -16,19 +16,19 @@
|
|||||||
"integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=",
|
"integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "8.0.22"
|
"@types/node": "8.0.26"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/mocha": {
|
"@types/mocha": {
|
||||||
"version": "2.2.41",
|
"version": "2.2.42",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.41.tgz",
|
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.42.tgz",
|
||||||
"integrity": "sha1-4nzwgXFT658nE7LT9saPHhw8pgg=",
|
"integrity": "sha512-b6gVDoxEbAQGwbV7gSzeFw/hy3/eEAokztktdzl4bHvGgb9K5zW4mVQDlVYch2w31m8t/J7L2iqhQvz3r5edCQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "8.0.22",
|
"version": "8.0.26",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.22.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.26.tgz",
|
||||||
"integrity": "sha512-+YQ5JLlvLP24teVUdUDep83mAWIFoAnOMosrH/2+xDeU9YMUpmMJtYOqVtbivs37h2PL9svz0R3r/MfVuEvEIA==",
|
"integrity": "sha512-wbKN0MB4XsjdnSE04HiCzLoBDirGCM6zXrqavSj44nZnPFYpnrTF64E9O6Xmf0ca/IuKK/BHUcXwMiwk92gW6Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/tmp": {
|
"@types/tmp": {
|
||||||
@@ -147,9 +147,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"babel-code-frame": {
|
"babel-code-frame": {
|
||||||
"version": "6.22.0",
|
"version": "6.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||||
"integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=",
|
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "1.1.3",
|
"chalk": "1.1.3",
|
||||||
@@ -660,7 +660,7 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"asynckit": "0.4.0",
|
"asynckit": "0.4.0",
|
||||||
"combined-stream": "1.0.5",
|
"combined-stream": "1.0.5",
|
||||||
"mime-types": "2.1.16"
|
"mime-types": "2.1.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"from": {
|
"from": {
|
||||||
@@ -999,7 +999,7 @@
|
|||||||
"is-typedarray": "1.0.0",
|
"is-typedarray": "1.0.0",
|
||||||
"isstream": "0.1.2",
|
"isstream": "0.1.2",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"mime-types": "2.1.16",
|
"mime-types": "2.1.17",
|
||||||
"oauth-sign": "0.8.2",
|
"oauth-sign": "0.8.2",
|
||||||
"qs": "6.3.2",
|
"qs": "6.3.2",
|
||||||
"stringstream": "0.0.5",
|
"stringstream": "0.0.5",
|
||||||
@@ -1019,7 +1019,7 @@
|
|||||||
"clone-stats": "1.0.0",
|
"clone-stats": "1.0.0",
|
||||||
"cloneable-readable": "1.0.0",
|
"cloneable-readable": "1.0.0",
|
||||||
"is-stream": "1.1.0",
|
"is-stream": "1.1.0",
|
||||||
"remove-trailing-separator": "1.0.2",
|
"remove-trailing-separator": "1.1.0",
|
||||||
"replace-ext": "1.0.0"
|
"replace-ext": "1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1200,7 +1200,7 @@
|
|||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "1.1.3",
|
"chalk": "1.1.3",
|
||||||
"commander": "2.9.0",
|
"commander": "2.9.0",
|
||||||
"is-my-json-valid": "2.16.0",
|
"is-my-json-valid": "2.16.1",
|
||||||
"pinkie-promise": "2.0.1"
|
"pinkie-promise": "2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1271,9 +1271,9 @@
|
|||||||
"integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA=="
|
"integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA=="
|
||||||
},
|
},
|
||||||
"ignore": {
|
"ignore": {
|
||||||
"version": "3.3.3",
|
"version": "3.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
|
||||||
"integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0="
|
"integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw=="
|
||||||
},
|
},
|
||||||
"inflight": {
|
"inflight": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
@@ -1345,9 +1345,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-my-json-valid": {
|
"is-my-json-valid": {
|
||||||
"version": "2.16.0",
|
"version": "2.16.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
|
||||||
"integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=",
|
"integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"generate-function": "2.0.0",
|
"generate-function": "2.0.0",
|
||||||
@@ -1728,7 +1728,7 @@
|
|||||||
"normalize-path": "2.1.1",
|
"normalize-path": "2.1.1",
|
||||||
"object.omit": "2.0.1",
|
"object.omit": "2.0.1",
|
||||||
"parse-glob": "3.0.4",
|
"parse-glob": "3.0.4",
|
||||||
"regex-cache": "0.4.3"
|
"regex-cache": "0.4.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-extglob": {
|
"is-extglob": {
|
||||||
@@ -1749,18 +1749,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mime-db": {
|
"mime-db": {
|
||||||
"version": "1.29.0",
|
"version": "1.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
|
||||||
"integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=",
|
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mime-types": {
|
"mime-types": {
|
||||||
"version": "2.1.16",
|
"version": "2.1.17",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
|
||||||
"integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=",
|
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"mime-db": "1.29.0"
|
"mime-db": "1.30.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
@@ -1852,7 +1852,7 @@
|
|||||||
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"remove-trailing-separator": "1.0.2"
|
"remove-trailing-separator": "1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth-sign": {
|
"oauth-sign": {
|
||||||
@@ -2080,19 +2080,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regex-cache": {
|
"regex-cache": {
|
||||||
"version": "0.4.3",
|
"version": "0.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
|
||||||
"integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=",
|
"integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-equal-shallow": "0.1.3",
|
"is-equal-shallow": "0.1.3"
|
||||||
"is-primitive": "2.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"remove-trailing-separator": {
|
"remove-trailing-separator": {
|
||||||
"version": "1.0.2",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
|
||||||
"integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=",
|
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"repeat-element": {
|
"repeat-element": {
|
||||||
@@ -2132,7 +2131,7 @@
|
|||||||
"is-typedarray": "1.0.0",
|
"is-typedarray": "1.0.0",
|
||||||
"isstream": "0.1.2",
|
"isstream": "0.1.2",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"mime-types": "2.1.16",
|
"mime-types": "2.1.17",
|
||||||
"oauth-sign": "0.8.2",
|
"oauth-sign": "0.8.2",
|
||||||
"performance-now": "0.2.0",
|
"performance-now": "0.2.0",
|
||||||
"qs": "6.4.0",
|
"qs": "6.4.0",
|
||||||
@@ -2229,18 +2228,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.5.6",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||||
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
|
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"source-map-support": {
|
"source-map-support": {
|
||||||
"version": "0.4.15",
|
"version": "0.4.16",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.16.tgz",
|
||||||
"integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=",
|
"integrity": "sha512-A6vlydY7H/ljr4L2UOhDSajQdZQ6dMD7cLH0pzwcmwLyc9u8PNI4WGtnfDDzX7uzGL6c/T+ORL97Zlh+S4iOrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"source-map": "0.5.6"
|
"source-map": "0.5.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sparkles": {
|
"sparkles": {
|
||||||
@@ -2475,12 +2474,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"tslint": {
|
"tslint": {
|
||||||
"version": "5.6.0",
|
"version": "5.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.7.0.tgz",
|
||||||
"integrity": "sha1-CIqmxgJmIzOGULKQCCirPt9Z9s8=",
|
"integrity": "sha1-wl4NDJL6EgHCvDDoROCOaCtPNVI=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"babel-code-frame": "6.22.0",
|
"babel-code-frame": "6.26.0",
|
||||||
"colors": "1.1.2",
|
"colors": "1.1.2",
|
||||||
"commander": "2.9.0",
|
"commander": "2.9.0",
|
||||||
"diff": "3.2.0",
|
"diff": "3.2.0",
|
||||||
@@ -2489,13 +2488,13 @@
|
|||||||
"resolve": "1.4.0",
|
"resolve": "1.4.0",
|
||||||
"semver": "5.4.1",
|
"semver": "5.4.1",
|
||||||
"tslib": "1.7.1",
|
"tslib": "1.7.1",
|
||||||
"tsutils": "2.8.0"
|
"tsutils": "2.8.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tsutils": {
|
"tsutils": {
|
||||||
"version": "2.8.0",
|
"version": "2.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.8.2.tgz",
|
||||||
"integrity": "sha1-AWAXNymzvxOGKN0UoVN+AIUdgUo=",
|
"integrity": "sha1-LBSGukMSYIRbCsb5Aq/Z1wio6mo=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "1.7.1"
|
"tslib": "1.7.1"
|
||||||
@@ -2515,9 +2514,9 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "2.4.2",
|
"version": "2.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz",
|
||||||
"integrity": "sha1-+DlfhdRZJ2BnyYiqQYN6j4KHCEQ=",
|
"integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"unique-stream": {
|
"unique-stream": {
|
||||||
@@ -2695,9 +2694,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.5.tgz",
|
||||||
"integrity": "sha1-Hx1NZi1VyaKLxGeqy2MikfcKaG0=",
|
"integrity": "sha1-EOsQQAGEDD3QgTgV/UoF+PyILRQ=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"glob": "7.1.1",
|
"glob": "7.1.1",
|
||||||
@@ -2711,7 +2710,7 @@
|
|||||||
"mocha": "3.5.0",
|
"mocha": "3.5.0",
|
||||||
"request": "2.81.0",
|
"request": "2.81.0",
|
||||||
"semver": "5.4.1",
|
"semver": "5.4.1",
|
||||||
"source-map-support": "0.4.15",
|
"source-map-support": "0.4.16",
|
||||||
"url-parse": "1.1.9",
|
"url-parse": "1.1.9",
|
||||||
"vinyl-source-stream": "1.1.0"
|
"vinyl-source-stream": "1.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
418
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gitlens",
|
"name": "gitlens",
|
||||||
"version": "4.4.0-beta",
|
"version": "5.0.0-alpha.2",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Eric Amodio",
|
"name": "Eric Amodio",
|
||||||
"email": "eamodio@gmail.com"
|
"email": "eamodio@gmail.com"
|
||||||
@@ -351,6 +351,12 @@
|
|||||||
"locations": [
|
"locations": [
|
||||||
"document"
|
"document"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language": "stylus",
|
||||||
|
"locations": [
|
||||||
|
"document"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"items": {
|
"items": {
|
||||||
@@ -407,15 +413,39 @@
|
|||||||
"default": null,
|
"default": null,
|
||||||
"description": "Specifies how all absolute dates will be formatted by default\nSee https://momentjs.com/docs/#/displaying/format/ for valid formats"
|
"description": "Specifies how all absolute dates will be formatted by default\nSee https://momentjs.com/docs/#/displaying/format/ for valid formats"
|
||||||
},
|
},
|
||||||
"gitlens.stashExplorer.stashFormat": {
|
"gitlens.gitExplorer.commitFormat": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "${message} \u00a0\u2022\u00a0 ${authorAgo} \u00a0\u2022\u00a0 ${id}",
|
||||||
|
"description": "Specifies the format of committed changes in the `GitLens` custom view\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)\n ${authorAgo} - commit author, relative commit date\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting"
|
||||||
|
},
|
||||||
|
"gitlens.gitExplorer.commitFileFormat": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "${filePath}",
|
||||||
|
"description": "Specifies the format of a committed file in the `GitLens` custom view\nAvailable tokens\n ${file} - file name\n ${filePath} - file name and path\n ${path} - file path"
|
||||||
|
},
|
||||||
|
"gitlens.gitExplorer.showTrackingBranch": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "Specifies whether or not to show the tracking branch when displaying local branches in the `GitLens` custom view"
|
||||||
|
},
|
||||||
|
"gitlens.gitExplorer.stashFormat": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "${message}",
|
"default": "${message}",
|
||||||
"description": "Specifies the format of stashed changes in the `Git Stashes` explorer\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)\n ${authorAgo} - commit author, relative commit date\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting"
|
"description": "Specifies the format of stashed changes in the `GitLens` custom view\nAvailable tokens\n ${id} - commit id\n ${author} - commit author\n ${message} - commit message\n ${ago} - relative commit date (e.g. 1 day ago)\n ${date} - formatted commit date (format specified by `gitlens.statusBar.dateFormat`)\n ${authorAgo} - commit author, relative commit date\nSee https://github.com/eamodio/vscode-gitlens/wiki/Advanced-Formatting for advanced formatting"
|
||||||
},
|
},
|
||||||
"gitlens.stashExplorer.stashFileFormat": {
|
"gitlens.gitExplorer.stashFileFormat": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "${file} \u00a0\u2022\u00a0 ${path}",
|
"default": "${filePath}",
|
||||||
"description": "Specifies the format of a stashed file in the `Git Stashes` explorer\nAvailable tokens\n ${file} - file name\n ${path} - file path"
|
"description": "Specifies the format of a stashed file in the `GitLens` custom view\nAvailable tokens\n ${file} - file name\n ${filePath} - file name and path\n ${path} - file path"
|
||||||
|
},
|
||||||
|
"gitlens.gitExplorer.view": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "repository",
|
||||||
|
"enum": [
|
||||||
|
"history",
|
||||||
|
"repository"
|
||||||
|
],
|
||||||
|
"description": "Specifies the starting view (mode) of the `GitLens` custom view\n `history` - shows the commit history of the active file\n `repository` - shows a repository explorer"
|
||||||
},
|
},
|
||||||
"gitlens.statusBar.enabled": {
|
"gitlens.statusBar.enabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -761,17 +791,17 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithNext",
|
"command": "gitlens.diffWithNext",
|
||||||
"title": "Compare File with Next Commit",
|
"title": "Compare File with Next Revision",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithPrevious",
|
"command": "gitlens.diffWithPrevious",
|
||||||
"title": "Compare File with Previous",
|
"title": "Compare File with Previous Revision",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffLineWithPrevious",
|
"command": "gitlens.diffLineWithPrevious",
|
||||||
"title": "Compare Line Commit with Previous",
|
"title": "Compare Line Revision with Previous",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -781,12 +811,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithWorking",
|
"command": "gitlens.diffWithWorking",
|
||||||
"title": "Compare File with Working Tree",
|
"title": "Compare File with Working Revision",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffLineWithWorking",
|
"command": "gitlens.diffLineWithWorking",
|
||||||
"title": "Compare Line Commit with Working Tree",
|
"title": "Compare Line Revision with Working",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -853,7 +883,11 @@
|
|||||||
{
|
{
|
||||||
"command": "gitlens.showCommitSearch",
|
"command": "gitlens.showCommitSearch",
|
||||||
"title": "Search Commits",
|
"title": "Search Commits",
|
||||||
"category": "GitLens"
|
"category": "GitLens",
|
||||||
|
"icon": {
|
||||||
|
"dark": "images/dark/icon-search.svg",
|
||||||
|
"light": "images/light/icon-search.svg"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.showFileHistory",
|
"command": "gitlens.showFileHistory",
|
||||||
@@ -920,6 +954,11 @@
|
|||||||
"title": "Open Changed Files",
|
"title": "Open Changed Files",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.openBranchesInRemote",
|
||||||
|
"title": "Open Branches in Remote",
|
||||||
|
"category": "GitLens"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.openBranchInRemote",
|
"command": "gitlens.openBranchInRemote",
|
||||||
"title": "Open Branch in Remote",
|
"title": "Open Branch in Remote",
|
||||||
@@ -974,32 +1013,61 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.refresh",
|
"command": "gitlens.gitExplorer.switchToHistoryView",
|
||||||
"title": "Refresh",
|
"title": "Switch to History View",
|
||||||
"category": "GitLens",
|
"category": "GitLens",
|
||||||
"icon": {
|
"icon": {
|
||||||
"dark": "images/dark/icon-refresh.svg",
|
"dark": "images/dark/icon-history.svg",
|
||||||
"light": "images/light/icon-refresh.svg"
|
"light": "images/light/icon-history.svg"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openChanges",
|
"command": "gitlens.gitExplorer.switchToRepositoryView",
|
||||||
|
"title": "Switch to Repository View",
|
||||||
|
"category": "GitLens",
|
||||||
|
"icon": {
|
||||||
|
"dark": "images/dark/icon-repo.svg",
|
||||||
|
"light": "images/light/icon-repo.svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChanges",
|
||||||
"title": "Open Changes",
|
"title": "Open Changes",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openFile",
|
"command": "gitlens.gitExplorer.openChangesWithWorking",
|
||||||
|
"title": "Open Changes with Working Tree",
|
||||||
|
"category": "GitLens"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFile",
|
||||||
"title": "Open File",
|
"title": "Open File",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openStashedFile",
|
"command": "gitlens.gitExplorer.openFileRevision",
|
||||||
"title": "Open Stashed File",
|
"title": "Open Revision",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openFileInRemote",
|
"command": "gitlens.gitExplorer.openFileRevisionInRemote",
|
||||||
"title": "Open File in Remote",
|
"title": "Open Revision in Remote",
|
||||||
|
"category": "GitLens"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFiles",
|
||||||
|
"title": "Open Files",
|
||||||
|
"category": "GitLens"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFileRevisions",
|
||||||
|
"title": "Open Revisions",
|
||||||
|
"category": "GitLens"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.applyChanges",
|
||||||
|
"title": "Apply Changes",
|
||||||
"category": "GitLens"
|
"category": "GitLens"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1125,6 +1193,10 @@
|
|||||||
"command": "gitlens.openChangedFiles",
|
"command": "gitlens.openChangedFiles",
|
||||||
"when": "gitlens:enabled"
|
"when": "gitlens:enabled"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.openBranchesInRemote",
|
||||||
|
"when": "gitlens:hasRemotes"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.openBranchInRemote",
|
"command": "gitlens.openBranchInRemote",
|
||||||
"when": "gitlens:hasRemotes"
|
"when": "gitlens:hasRemotes"
|
||||||
@@ -1155,26 +1227,46 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.gitExplorer.refresh",
|
"command": "gitlens.gitExplorer.refresh",
|
||||||
"when": "gitlens:enabled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashExplorer.refresh",
|
|
||||||
"when": "gitlens:enabled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashExplorer.openChanges",
|
|
||||||
"when": "false"
|
"when": "false"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openFile",
|
"command": "gitlens.gitExplorer.switchToHistoryView",
|
||||||
|
"when": "gitlens:gitExplorer:view == repository"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.switchToRepositoryView",
|
||||||
|
"when": "gitlens:gitExplorer:view == history"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChanges",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openStashedFile",
|
"command": "gitlens.gitExplorer.openChangesWithWorking",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openFileInRemote",
|
"command": "gitlens.gitExplorer.openFile",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFileRevision",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFileRevisionInRemote",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFiles",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFileRevisions",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.applyChanges",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1249,12 +1341,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.openFileInRemote",
|
"command": "gitlens.openFileInRemote",
|
||||||
"when": "gitlens:enabled && config.gitlens.advanced.menus.editorTitleContext.remote",
|
"when": "gitlens:enabled && gitlens:hasRemotes && config.gitlens.advanced.menus.editorTitleContext.remote",
|
||||||
"group": "1_gitlens"
|
"group": "1_gitlens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.openRepoInRemote",
|
"command": "gitlens.openRepoInRemote",
|
||||||
"when": "gitlens:enabled && config.gitlens.advanced.menus.editorTitleContext.remote",
|
"when": "gitlens:enabled && gitlens:hasRemotes && config.gitlens.advanced.menus.editorTitleContext.remote",
|
||||||
"group": "1_gitlens"
|
"group": "1_gitlens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1286,7 +1378,7 @@
|
|||||||
"editor/title/context": [
|
"editor/title/context": [
|
||||||
{
|
{
|
||||||
"command": "gitlens.openFileInRemote",
|
"command": "gitlens.openFileInRemote",
|
||||||
"when": "gitlens:enabled && config.gitlens.advanced.menus.editorTitleContext.remote",
|
"when": "gitlens:enabled && gitlens:hasRemotes && config.gitlens.advanced.menus.editorTitleContext.remote",
|
||||||
"group": "1_gitlens"
|
"group": "1_gitlens"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1313,7 +1405,7 @@
|
|||||||
"explorer/context": [
|
"explorer/context": [
|
||||||
{
|
{
|
||||||
"command": "gitlens.openFileInRemote",
|
"command": "gitlens.openFileInRemote",
|
||||||
"when": "gitlens:enabled && config.gitlens.advanced.menus.explorerContext.remote",
|
"when": "gitlens:enabled && gitlens:hasRemotes && config.gitlens.advanced.menus.explorerContext.remote",
|
||||||
"group": "navigation@100"
|
"group": "navigation@100"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1342,6 +1434,11 @@
|
|||||||
"command": "gitlens.closeUnchangedFiles",
|
"command": "gitlens.closeUnchangedFiles",
|
||||||
"when": "gitlens:enabled",
|
"when": "gitlens:enabled",
|
||||||
"group": "1_gitlens@2"
|
"group": "1_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.stashSave",
|
||||||
|
"when": "gitlens:enabled",
|
||||||
|
"group": "2_gitlens@1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scm/resourceState/context": [
|
"scm/resourceState/context": [
|
||||||
@@ -1359,80 +1456,215 @@
|
|||||||
"command": "gitlens.showQuickFileHistory",
|
"command": "gitlens.showQuickFileHistory",
|
||||||
"when": "gitlens:enabled",
|
"when": "gitlens:enabled",
|
||||||
"group": "1_gitlens_1@1"
|
"group": "1_gitlens_1@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.stashSave",
|
||||||
|
"when": "gitlens:enabled",
|
||||||
|
"group": "2_gitlens@1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"view/title": [
|
"view/title": [
|
||||||
{
|
{
|
||||||
"command": "gitlens.gitExplorer.refresh",
|
"command": "gitlens.showCommitSearch",
|
||||||
"when": "gitlens:enabled && view == gitlens.gitExplorer",
|
"when": "gitlens:enabled && view == gitlens.gitExplorer",
|
||||||
"group": "navigation"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashSave",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer",
|
|
||||||
"group": "navigation@1"
|
"group": "navigation@1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.refresh",
|
"command": "gitlens.gitExplorer.switchToHistoryView",
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer",
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && gitlens:gitExplorer:view == repository",
|
||||||
"group": "navigation@2"
|
"group": "navigation@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.switchToRepositoryView",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && gitlens:gitExplorer:view == history",
|
||||||
|
"group": "navigation@3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.refresh",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer",
|
||||||
|
"group": "navigation@4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"view/item/context": [
|
"view/item/context": [
|
||||||
|
{
|
||||||
|
"command": "gitlens.openBranchesInRemote",
|
||||||
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:branches",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.openBranchInRemote",
|
||||||
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:branch-history",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.openCommitInRemote",
|
"command": "gitlens.openCommitInRemote",
|
||||||
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == commit",
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:commit",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.copyShaToClipboard",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit",
|
||||||
|
"group": "2_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.copyMessageToClipboard",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit",
|
||||||
|
"group": "2_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFiles",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit",
|
||||||
|
"group": "3_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFileRevisions",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit",
|
||||||
|
"group": "3_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.showQuickCommitDetails",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit",
|
||||||
|
"group": "4_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChanges",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangesWithWorking",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "1_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFile",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "2_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFileRevision",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "2_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.openFileInRemote",
|
||||||
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "3_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFileRevisionInRemote",
|
||||||
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "3_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.applyChanges",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "4_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.showQuickFileHistory",
|
||||||
|
"when": "gitlens:isTracked && view == gitlens.gitExplorer && viewItem == gitlens:commit-file && gitlens:gitExplorer:view == repository",
|
||||||
|
"group": "5_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.showQuickCommitFileDetails",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:commit-file",
|
||||||
|
"group": "5_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFile",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:file-history",
|
||||||
"group": "1_gitlens@1"
|
"group": "1_gitlens@1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.openFileInRemote",
|
"command": "gitlens.openFileInRemote",
|
||||||
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == commit-file",
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:file-history",
|
||||||
"group": "1_gitlens@1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.diffWithPrevious",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == commit-file",
|
|
||||||
"group": "2_gitlens@1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.diffWithWorking",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == commit-file",
|
|
||||||
"group": "2_gitlens@2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashApply",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == stash-commit",
|
|
||||||
"group": "3_gitlens@1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashDelete",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == stash-commit",
|
|
||||||
"group": "3_gitlens@1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashExplorer.openChanges",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == commit-file",
|
|
||||||
"group": "1_gitlens@1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"command": "gitlens.stashExplorer.openFile",
|
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == commit-file",
|
|
||||||
"group": "1_gitlens@2"
|
"group": "1_gitlens@2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openStashedFile",
|
"command": "gitlens.openBranchesInRemote",
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == commit-file",
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:remote",
|
||||||
"group": "1_gitlens@3"
|
"group": "1_gitlens@1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.stashExplorer.openFileInRemote",
|
"command": "gitlens.openRepoInRemote",
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == commit-file",
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:remote",
|
||||||
"group": "1_gitlens@4"
|
"group": "1_gitlens@2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "gitlens.diffWithWorking",
|
"command": "gitlens.stashSave",
|
||||||
"when": "gitlens:enabled && view == gitlens.stashExplorer && viewItem == commit-file",
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stashes",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.stashApply",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.stashDelete",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash",
|
||||||
|
"group": "1_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.copyMessageToClipboard",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash",
|
||||||
|
"group": "2_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFiles",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash",
|
||||||
|
"group": "3_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangedFileRevisions",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash",
|
||||||
|
"group": "3_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChanges",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openChangesWithWorking",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
|
"group": "1_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFile",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
|
"group": "2_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.openFileRevision",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
"group": "2_gitlens@2"
|
"group": "2_gitlens@2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.openFileInRemote",
|
||||||
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
|
"group": "3_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.applyChanges",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
|
"group": "4_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.showQuickFileHistory",
|
||||||
|
"when": "gitlens:isTracked && view == gitlens.gitExplorer && viewItem == gitlens:stash-file",
|
||||||
|
"group": "5_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.openRepoInRemote",
|
||||||
|
"when": "gitlens:enabled && gitlens:hasRemotes && view == gitlens.gitExplorer && viewItem == gitlens:status",
|
||||||
|
"group": "1_gitlens@1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "gitlens.gitExplorer.refresh",
|
||||||
|
"when": "gitlens:enabled && view == gitlens.gitExplorer && viewItem != gitlens:commit-file && viewItem != gitlens:stash-file",
|
||||||
|
"group": "9_gitlens@1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1531,8 +1763,8 @@
|
|||||||
"views": {
|
"views": {
|
||||||
"explorer": [
|
"explorer": [
|
||||||
{
|
{
|
||||||
"id": "gitlens.stashExplorer",
|
"id": "gitlens.gitExplorer",
|
||||||
"name": "Git Stashes",
|
"name": "GitLens",
|
||||||
"when": "gitlens:enabled"
|
"when": "gitlens:enabled"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1556,7 +1788,7 @@
|
|||||||
"applicationinsights": "0.21.0",
|
"applicationinsights": "0.21.0",
|
||||||
"copy-paste": "1.3.0",
|
"copy-paste": "1.3.0",
|
||||||
"iconv-lite": "0.4.18",
|
"iconv-lite": "0.4.18",
|
||||||
"ignore": "3.3.3",
|
"ignore": "3.3.5",
|
||||||
"lodash.debounce": "4.0.8",
|
"lodash.debounce": "4.0.8",
|
||||||
"lodash.escaperegexp": "4.1.2",
|
"lodash.escaperegexp": "4.1.2",
|
||||||
"lodash.isequal": "4.5.0",
|
"lodash.isequal": "4.5.0",
|
||||||
@@ -1569,12 +1801,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/copy-paste": "1.1.30",
|
"@types/copy-paste": "1.1.30",
|
||||||
"@types/iconv-lite": "0.0.1",
|
"@types/iconv-lite": "0.0.1",
|
||||||
"@types/mocha": "2.2.41",
|
"@types/mocha": "2.2.42",
|
||||||
"@types/node": "8.0.22",
|
"@types/node": "8.0.26",
|
||||||
"@types/tmp": "0.0.33",
|
"@types/tmp": "0.0.33",
|
||||||
"mocha": "3.5.0",
|
"mocha": "3.5.0",
|
||||||
"tslint": "5.6.0",
|
"tslint": "5.7.0",
|
||||||
"typescript": "2.4.2",
|
"typescript": "2.5.2",
|
||||||
"vscode": "1.1.4"
|
"vscode": "1.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
|
|||||||
gutter.renderOptions = { ...gutter.renderOptions };
|
gutter.renderOptions = { ...gutter.renderOptions };
|
||||||
gutter.renderOptions.before = {
|
gutter.renderOptions.before = {
|
||||||
...gutter.renderOptions.before,
|
...gutter.renderOptions.before,
|
||||||
...{ contentText: GlyphChars.Space.repeat(gutter.renderOptions!.before!.contentText!.length) }
|
...{ contentText: GlyphChars.Space.repeat(Strings.getWidth(gutter.renderOptions!.before!.contentText!)) }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (separateLines) {
|
if (separateLines) {
|
||||||
|
|||||||
81
src/codeLensController.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
'use strict';
|
||||||
|
import { Objects } from './system';
|
||||||
|
import { Disposable, ExtensionContext, languages, TextEditor, workspace } from 'vscode';
|
||||||
|
import { IConfig } from './configuration';
|
||||||
|
import { CommandContext, ExtensionKey, setCommandContext } from './constants';
|
||||||
|
import { GitCodeLensProvider } from './gitCodeLensProvider';
|
||||||
|
import { GitService } from './gitService';
|
||||||
|
import { Logger } from './logger';
|
||||||
|
|
||||||
|
export class CodeLensController extends Disposable {
|
||||||
|
|
||||||
|
private _codeLensProvider: GitCodeLensProvider | undefined;
|
||||||
|
private _codeLensProviderDisposable: Disposable | undefined;
|
||||||
|
private _config: IConfig;
|
||||||
|
private _disposable: Disposable | undefined;
|
||||||
|
|
||||||
|
constructor(private context: ExtensionContext, private git: GitService) {
|
||||||
|
super(() => this.dispose());
|
||||||
|
|
||||||
|
this._onConfigurationChanged();
|
||||||
|
|
||||||
|
const subscriptions: Disposable[] = [];
|
||||||
|
|
||||||
|
subscriptions.push(workspace.onDidChangeConfiguration(this._onConfigurationChanged, this));
|
||||||
|
subscriptions.push(git.onDidChangeGitCache(this._onGitCacheChanged, this));
|
||||||
|
|
||||||
|
this._disposable = Disposable.from(...subscriptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
this._disposable && this._disposable.dispose();
|
||||||
|
|
||||||
|
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||||
|
this._codeLensProviderDisposable = undefined;
|
||||||
|
this._codeLensProvider = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onConfigurationChanged() {
|
||||||
|
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||||
|
|
||||||
|
if (!Objects.areEquivalent(cfg.codeLens, this._config && this._config.codeLens)) {
|
||||||
|
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
||||||
|
if (cfg.codeLens.enabled && (cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled)) {
|
||||||
|
if (this._codeLensProvider) {
|
||||||
|
this._codeLensProvider.reset();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._codeLensProvider = new GitCodeLensProvider(this.context, this.git);
|
||||||
|
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._codeLensProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
||||||
|
this._codeLensProviderDisposable = undefined;
|
||||||
|
this._codeLensProvider = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCommandContext(CommandContext.CanToggleCodeLens, cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._config = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onGitCacheChanged() {
|
||||||
|
Logger.log('Git cache changed; resetting CodeLens provider');
|
||||||
|
this._codeLensProvider && this._codeLensProvider.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleCodeLens(editor: TextEditor) {
|
||||||
|
if (!this._config.codeLens.recentChange.enabled && !this._config.codeLens.authors.enabled) return;
|
||||||
|
|
||||||
|
Logger.log(`toggleCodeLens()`);
|
||||||
|
if (this._codeLensProviderDisposable) {
|
||||||
|
this._codeLensProviderDisposable.dispose();
|
||||||
|
this._codeLensProviderDisposable = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, new GitCodeLensProvider(this.context, this.git));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ export * from './commands/diffWithPrevious';
|
|||||||
export * from './commands/diffWithRevision';
|
export * from './commands/diffWithRevision';
|
||||||
export * from './commands/diffWithWorking';
|
export * from './commands/diffWithWorking';
|
||||||
export * from './commands/openChangedFiles';
|
export * from './commands/openChangedFiles';
|
||||||
|
export * from './commands/openBranchesInRemote';
|
||||||
export * from './commands/openBranchInRemote';
|
export * from './commands/openBranchInRemote';
|
||||||
export * from './commands/openCommitInRemote';
|
export * from './commands/openCommitInRemote';
|
||||||
export * from './commands/openFileInRemote';
|
export * from './commands/openFileInRemote';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
|
import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
|
||||||
import { ExplorerNode } from '../views/explorerNodes';
|
import { ExplorerNode } from '../views/explorerNodes';
|
||||||
|
import { GitBranch, GitCommit, GitRemote } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { Telemetry } from '../telemetry';
|
import { Telemetry } from '../telemetry';
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ export type Commands =
|
|||||||
'gitlens.diffWithWorking' |
|
'gitlens.diffWithWorking' |
|
||||||
'gitlens.diffLineWithWorking' |
|
'gitlens.diffLineWithWorking' |
|
||||||
'gitlens.openChangedFiles' |
|
'gitlens.openChangedFiles' |
|
||||||
|
'gitlens.openBranchesInRemote' |
|
||||||
'gitlens.openBranchInRemote' |
|
'gitlens.openBranchInRemote' |
|
||||||
'gitlens.openCommitInRemote' |
|
'gitlens.openCommitInRemote' |
|
||||||
'gitlens.openFileInRemote' |
|
'gitlens.openFileInRemote' |
|
||||||
@@ -58,6 +60,7 @@ export const Commands = {
|
|||||||
DiffWithWorking: 'gitlens.diffWithWorking' as Commands,
|
DiffWithWorking: 'gitlens.diffWithWorking' as Commands,
|
||||||
DiffLineWithWorking: 'gitlens.diffLineWithWorking' as Commands,
|
DiffLineWithWorking: 'gitlens.diffLineWithWorking' as Commands,
|
||||||
OpenChangedFiles: 'gitlens.openChangedFiles' as Commands,
|
OpenChangedFiles: 'gitlens.openChangedFiles' as Commands,
|
||||||
|
OpenBranchesInRemote: 'gitlens.openBranchesInRemote' as Commands,
|
||||||
OpenBranchInRemote: 'gitlens.openBranchInRemote' as Commands,
|
OpenBranchInRemote: 'gitlens.openBranchInRemote' as Commands,
|
||||||
OpenCommitInRemote: 'gitlens.openCommitInRemote' as Commands,
|
OpenCommitInRemote: 'gitlens.openCommitInRemote' as Commands,
|
||||||
OpenFileInRemote: 'gitlens.openFileInRemote' as Commands,
|
OpenFileInRemote: 'gitlens.openFileInRemote' as Commands,
|
||||||
@@ -125,6 +128,22 @@ export interface CommandViewContext extends CommandBaseContext {
|
|||||||
node: ExplorerNode;
|
node: ExplorerNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isCommandViewContextWithBranch(context: CommandContext): context is CommandViewContext & { node: (ExplorerNode & { branch: GitBranch }) } {
|
||||||
|
return context.type === 'view' && (context.node as any).branch && (context.node as any).branch instanceof GitBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICommandViewContextWithCommit<T extends GitCommit> extends CommandViewContext {
|
||||||
|
node: (ExplorerNode & { commit: T });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCommandViewContextWithCommit<T extends GitCommit>(context: CommandContext): context is ICommandViewContextWithCommit<T> {
|
||||||
|
return context.type === 'view' && (context.node as any).commit && (context.node as any).commit instanceof GitCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isCommandViewContextWithRemote(context: CommandContext): context is CommandViewContext & { node: (ExplorerNode & { remote: GitRemote }) } {
|
||||||
|
return context.type === 'view' && (context.node as any).remote && (context.node as any).remote instanceof GitRemote;
|
||||||
|
}
|
||||||
|
|
||||||
export type CommandContext = CommandScmGroupsContext | CommandScmStatesContext | CommandUnknownContext | CommandUriContext | CommandViewContext;
|
export type CommandContext = CommandScmGroupsContext | CommandScmStatesContext | CommandUnknownContext | CommandUriContext | CommandViewContext;
|
||||||
|
|
||||||
function isScmResourceGroup(group: any): group is SourceControlResourceGroup {
|
function isScmResourceGroup(group: any): group is SourceControlResourceGroup {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { TextEditor, Uri, window } from 'vscode';
|
import { TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { copy } from 'copy-paste';
|
import { copy } from 'copy-paste';
|
||||||
@@ -17,6 +17,16 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
|
|||||||
super(Commands.CopyMessageToClipboard);
|
super(Commands.CopyMessageToClipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async preExecute(context: CommandContext, args: CopyMessageToClipboardCommandArgs = {}): Promise<any> {
|
||||||
|
if (isCommandViewContextWithCommit(context)) {
|
||||||
|
args = { ...args };
|
||||||
|
args.sha = context.node.commit.sha;
|
||||||
|
return this.execute(context.editor, context.node.commit.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri, args: CopyMessageToClipboardCommandArgs = {}): Promise<any> {
|
async execute(editor?: TextEditor, uri?: Uri, args: CopyMessageToClipboardCommandArgs = {}): Promise<any> {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
|
|
||||||
@@ -64,7 +74,7 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand {
|
|||||||
|
|
||||||
// Get the full commit message -- since blame only returns the summary
|
// Get the full commit message -- since blame only returns the summary
|
||||||
const commit = await this.git.getLogCommit(gitUri.repoPath, gitUri.fsPath, args.sha);
|
const commit = await this.git.getLogCommit(gitUri.repoPath, gitUri.fsPath, args.sha);
|
||||||
if (!commit) return undefined;
|
if (commit === undefined) return undefined;
|
||||||
|
|
||||||
args.message = commit.message;
|
args.message = commit.message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { TextEditor, Uri, window } from 'vscode';
|
import { TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { copy } from 'copy-paste';
|
import { copy } from 'copy-paste';
|
||||||
@@ -16,6 +16,16 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
|
|||||||
super(Commands.CopyShaToClipboard);
|
super(Commands.CopyShaToClipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async preExecute(context: CommandContext, args: CopyShaToClipboardCommandArgs = {}): Promise<any> {
|
||||||
|
if (isCommandViewContextWithCommit(context)) {
|
||||||
|
args = { ...args };
|
||||||
|
args.sha = context.node.commit.sha;
|
||||||
|
return this.execute(context.editor, context.node.commit.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri, args: CopyShaToClipboardCommandArgs = {}): Promise<any> {
|
async execute(editor?: TextEditor, uri?: Uri, args: CopyShaToClipboardCommandArgs = {}): Promise<any> {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
|
|
||||||
@@ -45,7 +55,7 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const blame = await this.git.getBlameForLine(gitUri, blameline);
|
const blame = await this.git.getBlameForLine(gitUri, blameline);
|
||||||
if (!blame) return undefined;
|
if (blame === undefined) return undefined;
|
||||||
|
|
||||||
args.sha = blame.commit.sha;
|
args.sha = blame.commit.sha;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
|
import { commands, Range, TextDocumentShowOptions, TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
||||||
import { BuiltInCommands, GlyphChars } from '../constants';
|
import { BuiltInCommands, FakeSha, GlyphChars } from '../constants';
|
||||||
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
|
import { DiffWithWorkingCommandArgs } from './diffWithWorking';
|
||||||
import { GitCommit, GitService, GitUri } from '../gitService';
|
import { GitCommit, GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
@@ -14,6 +14,10 @@ export interface DiffWithPreviousCommandArgs {
|
|||||||
line?: number;
|
line?: number;
|
||||||
range?: Range;
|
range?: Range;
|
||||||
showOptions?: TextDocumentShowOptions;
|
showOptions?: TextDocumentShowOptions;
|
||||||
|
|
||||||
|
allowMissingPrevious?: boolean;
|
||||||
|
leftTitlePrefix?: string;
|
||||||
|
rightTitlePrefix?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DiffWithPreviousCommand extends ActiveEditorCommand {
|
export class DiffWithPreviousCommand extends ActiveEditorCommand {
|
||||||
@@ -51,12 +55,12 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.commit.previousSha === undefined) return Messages.showCommitHasNoPreviousCommitWarningMessage(args.commit);
|
if (args.commit.previousSha === undefined && !args.allowMissingPrevious) return Messages.showCommitHasNoPreviousCommitWarningMessage(args.commit);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [rhs, lhs] = await Promise.all([
|
const [rhs, lhs] = await Promise.all([
|
||||||
this.git.getVersionedFile(args.commit.repoPath, args.commit.uri.fsPath, args.commit.sha),
|
this.git.getVersionedFile(args.commit.repoPath, args.commit.uri.fsPath, args.commit.sha),
|
||||||
this.git.getVersionedFile(args.commit.repoPath, args.commit.previousUri.fsPath, args.commit.previousSha)
|
this.git.getVersionedFile(args.commit.repoPath, args.commit.previousUri.fsPath, args.commit.previousSha === undefined ? FakeSha : args.commit.previousSha)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (args.line !== undefined && args.line !== 0) {
|
if (args.line !== undefined && args.line !== 0) {
|
||||||
@@ -69,7 +73,9 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
|
|||||||
await commands.executeCommand(BuiltInCommands.Diff,
|
await commands.executeCommand(BuiltInCommands.Diff,
|
||||||
Uri.file(lhs),
|
Uri.file(lhs),
|
||||||
Uri.file(rhs),
|
Uri.file(rhs),
|
||||||
`${path.basename(args.commit.previousUri.fsPath)} (${args.commit.previousShortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(args.commit.uri.fsPath)} (${args.commit.shortSha})`,
|
args.commit.previousShortSha === undefined
|
||||||
|
? `${path.basename(args.commit.uri.fsPath)} (${args.rightTitlePrefix || ''}${args.commit.shortSha})`
|
||||||
|
: `${path.basename(args.commit.previousUri.fsPath)} (${args.leftTitlePrefix || ''}${args.commit.previousShortSha}) ${GlyphChars.ArrowLeftRight} ${path.basename(args.commit.uri.fsPath)} (${args.rightTitlePrefix || ''}${args.commit.shortSha})`,
|
||||||
args.showOptions);
|
args.showOptions);
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Arrays } from '../system';
|
import { Arrays } from '../system';
|
||||||
import { commands, TextEditor, Uri, window } from 'vscode';
|
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithBranch } from './common';
|
||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
@@ -10,6 +10,7 @@ import { OpenInRemoteCommandArgs } from './openInRemote';
|
|||||||
|
|
||||||
export interface OpenBranchInRemoteCommandArgs {
|
export interface OpenBranchInRemoteCommandArgs {
|
||||||
branch?: string;
|
branch?: string;
|
||||||
|
remote?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
|
export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
|
||||||
@@ -18,6 +19,18 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
|
|||||||
super(Commands.OpenBranchInRemote);
|
super(Commands.OpenBranchInRemote);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async preExecute(context: CommandContext, args: OpenBranchInRemoteCommandArgs = {}): Promise<any> {
|
||||||
|
if (isCommandViewContextWithBranch(context)) {
|
||||||
|
args = { ...args };
|
||||||
|
|
||||||
|
args.branch = context.node.branch.name;
|
||||||
|
args.remote = context.node.branch.getRemote();
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri, args: OpenBranchInRemoteCommandArgs = {}) {
|
async execute(editor?: TextEditor, uri?: Uri, args: OpenBranchInRemoteCommandArgs = {}) {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
|
|
||||||
@@ -47,6 +60,7 @@ export class OpenBranchInRemoteCommand extends ActiveEditorCommand {
|
|||||||
type: 'branch',
|
type: 'branch',
|
||||||
branch: args.branch
|
branch: args.branch
|
||||||
},
|
},
|
||||||
|
remote: args.remote,
|
||||||
remotes
|
remotes
|
||||||
} as OpenInRemoteCommandArgs);
|
} as OpenInRemoteCommandArgs);
|
||||||
}
|
}
|
||||||
|
|||||||
53
src/commands/openBranchesInRemote.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
'use strict';
|
||||||
|
import { Arrays } from '../system';
|
||||||
|
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||||
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithRemote } from './common';
|
||||||
|
import { GitService, GitUri } from '../gitService';
|
||||||
|
import { Logger } from '../logger';
|
||||||
|
import { OpenInRemoteCommandArgs } from './openInRemote';
|
||||||
|
|
||||||
|
export interface OpenBranchesInRemoteCommandArgs {
|
||||||
|
remote?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OpenBranchesInRemoteCommand extends ActiveEditorCommand {
|
||||||
|
|
||||||
|
constructor(private git: GitService) {
|
||||||
|
super(Commands.OpenBranchesInRemote);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async preExecute(context: CommandContext, args: OpenBranchesInRemoteCommandArgs = {}): Promise<any> {
|
||||||
|
if (isCommandViewContextWithRemote(context)) {
|
||||||
|
args = { ...args };
|
||||||
|
args.remote = context.node.remote.name;
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(editor?: TextEditor, uri?: Uri, args: OpenBranchesInRemoteCommandArgs = {}) {
|
||||||
|
uri = getCommandUri(uri, editor);
|
||||||
|
|
||||||
|
const gitUri = uri && await GitUri.fromUri(uri, this.git);
|
||||||
|
|
||||||
|
const repoPath = gitUri === undefined ? this.git.repoPath : gitUri.repoPath;
|
||||||
|
if (!repoPath) return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const remotes = Arrays.uniqueBy(await this.git.getRemotes(repoPath), r => r.url, r => !!r.provider);
|
||||||
|
|
||||||
|
return commands.executeCommand(Commands.OpenInRemote, uri, {
|
||||||
|
resource: {
|
||||||
|
type: 'branches'
|
||||||
|
},
|
||||||
|
remote: args.remote,
|
||||||
|
remotes
|
||||||
|
} as OpenInRemoteCommandArgs);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
Logger.error(ex, 'OpenBranchesInRemoteCommand');
|
||||||
|
return window.showErrorMessage(`Unable to open branches in remote provider. See output channel for more details`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Arrays } from '../system';
|
import { Arrays } from '../system';
|
||||||
import { commands, TextEditor, Uri, window } from 'vscode';
|
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common';
|
||||||
import { GitBlameCommit, GitService, GitUri } from '../gitService';
|
import { GitBlameCommit, GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { Messages } from '../messages';
|
import { Messages } from '../messages';
|
||||||
import { OpenInRemoteCommandArgs } from './openInRemote';
|
import { OpenInRemoteCommandArgs } from './openInRemote';
|
||||||
import { CommitNode } from '../views/explorerNodes';
|
|
||||||
|
|
||||||
export interface OpenCommitInRemoteCommandArgs {
|
export interface OpenCommitInRemoteCommandArgs {
|
||||||
sha?: string;
|
sha?: string;
|
||||||
@@ -19,7 +18,7 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async preExecute(context: CommandContext, args: OpenCommitInRemoteCommandArgs = {}): Promise<any> {
|
protected async preExecute(context: CommandContext, args: OpenCommitInRemoteCommandArgs = {}): Promise<any> {
|
||||||
if (context.type === 'view' && context.node instanceof CommitNode) {
|
if (isCommandViewContextWithCommit(context)) {
|
||||||
args = { ...args };
|
args = { ...args };
|
||||||
args.sha = context.node.commit.sha;
|
args.sha = context.node.commit.sha;
|
||||||
return this.execute(context.editor, context.node.commit.uri, args);
|
return this.execute(context.editor, context.node.commit.uri, args);
|
||||||
|
|||||||
@@ -1,18 +1,32 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Arrays } from '../system';
|
import { Arrays } from '../system';
|
||||||
import { commands, Range, TextEditor, Uri, window } from 'vscode';
|
import { commands, Range, TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { OpenInRemoteCommandArgs } from './openInRemote';
|
import { OpenInRemoteCommandArgs } from './openInRemote';
|
||||||
|
|
||||||
|
export interface OpenFileInRemoteCommandArgs {
|
||||||
|
range?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class OpenFileInRemoteCommand extends ActiveEditorCommand {
|
export class OpenFileInRemoteCommand extends ActiveEditorCommand {
|
||||||
|
|
||||||
constructor(private git: GitService) {
|
constructor(private git: GitService) {
|
||||||
super(Commands.OpenFileInRemote);
|
super(Commands.OpenFileInRemote);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri) {
|
protected async preExecute(context: CommandContext, args: OpenFileInRemoteCommandArgs = {}): Promise<any> {
|
||||||
|
if (isCommandViewContextWithCommit(context)) {
|
||||||
|
args = { ...args };
|
||||||
|
args.range = false;
|
||||||
|
return this.execute(context.editor, context.node.commit.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(editor?: TextEditor, uri?: Uri, args: OpenFileInRemoteCommandArgs = { range: true }) {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
if (uri === undefined) return undefined;
|
if (uri === undefined) return undefined;
|
||||||
|
|
||||||
@@ -23,7 +37,9 @@ export class OpenFileInRemoteCommand extends ActiveEditorCommand {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
|
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
|
||||||
const range = editor === undefined ? undefined : new Range(editor.selection.start.with({ line: editor.selection.start.line + 1 }), editor.selection.end.with({ line: editor.selection.end.line + 1 }));
|
const range = (args.range && editor !== undefined)
|
||||||
|
? new Range(editor.selection.start.with({ line: editor.selection.start.line + 1 }), editor.selection.end.with({ line: editor.selection.end.line + 1 }))
|
||||||
|
: undefined;
|
||||||
|
|
||||||
return commands.executeCommand(Commands.OpenInRemote, uri, {
|
return commands.executeCommand(Commands.OpenInRemote, uri, {
|
||||||
resource: {
|
resource: {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Logger } from '../logger';
|
|||||||
import { CommandQuickPickItem, OpenRemoteCommandQuickPickItem, RemotesQuickPick } from '../quickPicks';
|
import { CommandQuickPickItem, OpenRemoteCommandQuickPickItem, RemotesQuickPick } from '../quickPicks';
|
||||||
|
|
||||||
export interface OpenInRemoteCommandArgs {
|
export interface OpenInRemoteCommandArgs {
|
||||||
|
remote?: string;
|
||||||
remotes?: GitRemote[];
|
remotes?: GitRemote[];
|
||||||
resource?: RemoteResource;
|
resource?: RemoteResource;
|
||||||
|
|
||||||
@@ -26,8 +27,17 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
|
|||||||
args = { ...args };
|
args = { ...args };
|
||||||
if (args.remotes === undefined || args.resource === undefined) return undefined;
|
if (args.remotes === undefined || args.resource === undefined) return undefined;
|
||||||
|
|
||||||
|
if (args.remote !== undefined) {
|
||||||
|
const remotes = args.remotes.filter(r => r.name === args.remote);
|
||||||
|
// Only filter if we get some results
|
||||||
|
if (remotes.length > 0) {
|
||||||
|
args.remotes = remotes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (args.remotes.length === 1) {
|
if (args.remotes.length === 1) {
|
||||||
|
this.ensureRemoteBranchName(args);
|
||||||
const command = new OpenRemoteCommandQuickPickItem(args.remotes[0], args.resource);
|
const command = new OpenRemoteCommandQuickPickItem(args.remotes[0], args.resource);
|
||||||
return command.execute();
|
return command.execute();
|
||||||
}
|
}
|
||||||
@@ -35,16 +45,7 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
|
|||||||
let placeHolder = '';
|
let placeHolder = '';
|
||||||
switch (args.resource.type) {
|
switch (args.resource.type) {
|
||||||
case 'branch':
|
case 'branch':
|
||||||
// Check to see if the remote is in the branch
|
this.ensureRemoteBranchName(args);
|
||||||
const index = args.resource.branch.indexOf('/');
|
|
||||||
if (index >= 0) {
|
|
||||||
const remoteName = args.resource.branch.substring(0, index);
|
|
||||||
const remote = args.remotes.find(r => r.name === remoteName);
|
|
||||||
if (remote !== undefined) {
|
|
||||||
args.resource.branch = args.resource.branch.substring(index + 1);
|
|
||||||
args.remotes = [remote];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
placeHolder = `open ${args.resource.branch} branch in${GlyphChars.Ellipsis}`;
|
placeHolder = `open ${args.resource.branch} branch in${GlyphChars.Ellipsis}`;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -54,6 +55,10 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'file':
|
case 'file':
|
||||||
|
placeHolder = `open ${args.resource.fileName} in${GlyphChars.Ellipsis}`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'revision':
|
||||||
if (args.resource.commit !== undefined && args.resource.commit instanceof GitLogCommit) {
|
if (args.resource.commit !== undefined && args.resource.commit instanceof GitLogCommit) {
|
||||||
if (args.resource.commit.status === 'D') {
|
if (args.resource.commit.status === 'D') {
|
||||||
args.resource.sha = args.resource.commit.previousSha;
|
args.resource.sha = args.resource.commit.previousSha;
|
||||||
@@ -71,10 +76,6 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
|
|||||||
placeHolder = `open ${args.resource.fileName}${shaSuffix} in${GlyphChars.Ellipsis}`;
|
placeHolder = `open ${args.resource.fileName}${shaSuffix} in${GlyphChars.Ellipsis}`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'working-file':
|
|
||||||
placeHolder = `open ${args.resource.fileName} in${GlyphChars.Ellipsis}`;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.remotes.length === 1) {
|
if (args.remotes.length === 1) {
|
||||||
@@ -93,4 +94,19 @@ export class OpenInRemoteCommand extends ActiveEditorCommand {
|
|||||||
return window.showErrorMessage(`Unable to open in remote provider. See output channel for more details`);
|
return window.showErrorMessage(`Unable to open in remote provider. See output channel for more details`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ensureRemoteBranchName(args: OpenInRemoteCommandArgs) {
|
||||||
|
if (args.remotes === undefined || args.resource === undefined || args.resource.type !== 'branch') return;
|
||||||
|
|
||||||
|
// Check to see if the remote is in the branch
|
||||||
|
const index = args.resource.branch.indexOf('/');
|
||||||
|
if (index >= 0) {
|
||||||
|
const remoteName = args.resource.branch.substring(0, index);
|
||||||
|
const remote = args.remotes.find(r => r.name === remoteName);
|
||||||
|
if (remote !== undefined) {
|
||||||
|
args.resource.branch = args.resource.branch.substring(index + 1);
|
||||||
|
args.remotes = [remote];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,32 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Arrays } from '../system';
|
import { Arrays } from '../system';
|
||||||
import { commands, TextEditor, Uri, window } from 'vscode';
|
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithRemote } from './common';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { OpenInRemoteCommandArgs } from './openInRemote';
|
import { OpenInRemoteCommandArgs } from './openInRemote';
|
||||||
|
|
||||||
|
export interface OpenRepoInRemoteCommandArgs {
|
||||||
|
remote?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class OpenRepoInRemoteCommand extends ActiveEditorCommand {
|
export class OpenRepoInRemoteCommand extends ActiveEditorCommand {
|
||||||
|
|
||||||
constructor(private git: GitService) {
|
constructor(private git: GitService) {
|
||||||
super(Commands.OpenRepoInRemote);
|
super(Commands.OpenRepoInRemote);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri) {
|
protected async preExecute(context: CommandContext, args: OpenRepoInRemoteCommandArgs = {}): Promise<any> {
|
||||||
|
if (isCommandViewContextWithRemote(context)) {
|
||||||
|
args = { ...args };
|
||||||
|
args.remote = context.node.remote.name;
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(context.editor, context.uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(editor?: TextEditor, uri?: Uri, args: OpenRepoInRemoteCommandArgs = {}) {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
|
|
||||||
const gitUri = uri && await GitUri.fromUri(uri, this.git);
|
const gitUri = uri && await GitUri.fromUri(uri, this.git);
|
||||||
@@ -21,11 +35,13 @@ export class OpenRepoInRemoteCommand extends ActiveEditorCommand {
|
|||||||
if (!repoPath) return undefined;
|
if (!repoPath) return undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const remotes = Arrays.uniqueBy(await this.git.getRemotes(repoPath), _ => _.url, _ => !!_.provider);
|
const remotes = Arrays.uniqueBy(await this.git.getRemotes(repoPath), r => r.url, r => !!r.provider);
|
||||||
|
|
||||||
return commands.executeCommand(Commands.OpenInRemote, uri, {
|
return commands.executeCommand(Commands.OpenInRemote, uri, {
|
||||||
resource: {
|
resource: {
|
||||||
type: 'repo'
|
type: 'repo'
|
||||||
},
|
},
|
||||||
|
remote: args.remote,
|
||||||
remotes
|
remotes
|
||||||
} as OpenInRemoteCommandArgs);
|
} as OpenInRemoteCommandArgs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { Logger } from '../logger';
|
|||||||
import { Messages } from '../messages';
|
import { Messages } from '../messages';
|
||||||
import { CommandQuickPickItem, CommitsQuickPick } from '../quickPicks';
|
import { CommandQuickPickItem, CommitsQuickPick } from '../quickPicks';
|
||||||
import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails';
|
import { ShowQuickCommitDetailsCommandArgs } from './showQuickCommitDetails';
|
||||||
import { paste } from 'copy-paste';
|
|
||||||
|
|
||||||
const searchByRegex = /^([@:#])/;
|
const searchByRegex = /^([@:#])/;
|
||||||
const searchByMap = new Map<string, GitRepoSearchBy>([
|
const searchByMap = new Map<string, GitRepoSearchBy>([
|
||||||
@@ -49,12 +48,6 @@ export class ShowCommitSearchCommand extends ActiveEditorCachedCommand {
|
|||||||
args.search = `#${blameLine.commit.shortSha}`;
|
args.search = `#${blameLine.commit.shortSha}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.search) {
|
|
||||||
args.search = await new Promise<string>((resolve, reject) => {
|
|
||||||
paste((err: Error, content: string) => resolve(err ? '' : content));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
|
import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
|
||||||
import { Commands, EditorCommand, getCommandUri } from './common';
|
import { Commands, EditorCommand, getCommandUri } from './common';
|
||||||
import { BuiltInCommands } from '../constants';
|
import { BuiltInCommands } from '../constants';
|
||||||
import { GitExplorer } from '../views/gitExplorer';
|
// import { GitExplorer } from '../views/gitExplorer';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
import { Messages } from '../messages';
|
import { Messages } from '../messages';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
@@ -15,7 +15,7 @@ export interface ShowFileHistoryCommandArgs {
|
|||||||
|
|
||||||
export class ShowFileHistoryCommand extends EditorCommand {
|
export class ShowFileHistoryCommand extends EditorCommand {
|
||||||
|
|
||||||
constructor(private git: GitService, private explorer?: GitExplorer) {
|
constructor(private git: GitService) {
|
||||||
super(Commands.ShowFileHistory);
|
super(Commands.ShowFileHistory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,10 +33,10 @@ export class ShowFileHistoryCommand extends EditorCommand {
|
|||||||
const gitUri = await GitUri.fromUri(uri, this.git);
|
const gitUri = await GitUri.fromUri(uri, this.git);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.explorer !== undefined) {
|
// if (this.explorer !== undefined) {
|
||||||
this.explorer.addHistory(gitUri);
|
// this.explorer.addHistory(gitUri);
|
||||||
return undefined;
|
// return undefined;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const locations = await this.git.getLogLocations(gitUri, args.sha, args.line);
|
const locations = await this.git.getLogLocations(gitUri, args.sha, args.line);
|
||||||
if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history');
|
if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Strings } from '../system';
|
import { Strings } from '../system';
|
||||||
import { commands, TextEditor, Uri, window } from 'vscode';
|
import { commands, TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCachedCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common';
|
||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
|
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
@@ -24,6 +24,18 @@ export class ShowQuickCommitDetailsCommand extends ActiveEditorCachedCommand {
|
|||||||
super(Commands.ShowQuickCommitDetails);
|
super(Commands.ShowQuickCommitDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async preExecute(context: CommandContext, ...args: any[]): Promise<any> {
|
||||||
|
if (context.type === 'view') {
|
||||||
|
if (isCommandViewContextWithCommit(context)) {
|
||||||
|
args = [{ sha: context.node.uri.sha, commit: context.node.commit }];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args = [{ sha: context.node.uri.sha }];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.execute(context.editor, context.uri, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitDetailsCommandArgs = {}) {
|
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitDetailsCommandArgs = {}) {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
if (uri === undefined) return undefined;
|
if (uri === undefined) return undefined;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Strings } from '../system';
|
import { Strings } from '../system';
|
||||||
import { TextEditor, Uri, window } from 'vscode';
|
import { TextEditor, Uri, window } from 'vscode';
|
||||||
import { ActiveEditorCachedCommand, Commands, getCommandUri } from './common';
|
import { ActiveEditorCachedCommand, CommandContext, Commands, getCommandUri, isCommandViewContextWithCommit } from './common';
|
||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
|
import { GitCommit, GitLog, GitLogCommit, GitService, GitUri } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
@@ -24,6 +24,18 @@ export class ShowQuickCommitFileDetailsCommand extends ActiveEditorCachedCommand
|
|||||||
super(Commands.ShowQuickCommitFileDetails);
|
super(Commands.ShowQuickCommitFileDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async preExecute(context: CommandContext, ...args: any[]): Promise<any> {
|
||||||
|
if (context.type === 'view') {
|
||||||
|
if (isCommandViewContextWithCommit(context)) {
|
||||||
|
args = [{ sha: context.node.uri.sha, commit: context.node.commit }];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args = [{ sha: context.node.uri.sha }];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.execute(context.editor, context.uri, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitFileDetailsCommandArgs = {}) {
|
async execute(editor?: TextEditor, uri?: Uri, args: ShowQuickCommitFileDetailsCommandArgs = {}) {
|
||||||
uri = getCommandUri(uri, editor);
|
uri = getCommandUri(uri, editor);
|
||||||
if (uri === undefined) return undefined;
|
if (uri === undefined) return undefined;
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Strings } from '../system';
|
import { Strings } from '../system';
|
||||||
import { MessageItem, window } from 'vscode';
|
import { MessageItem, window } from 'vscode';
|
||||||
import { GitService, GitStashCommit } from '../gitService';
|
import { Command, CommandContext, Commands, isCommandViewContextWithCommit } from './common';
|
||||||
import { Command, CommandContext, Commands } from './common';
|
|
||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { CommitQuickPickItem, StashListQuickPick } from '../quickPicks';
|
import { GitService, GitStashCommit } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { CommandQuickPickItem } from '../quickPicks';
|
import { CommandQuickPickItem, CommitQuickPickItem, StashListQuickPick } from '../quickPicks';
|
||||||
import { StashCommitNode } from '../views/stashCommitNode';
|
|
||||||
|
|
||||||
export interface StashApplyCommandArgs {
|
export interface StashApplyCommandArgs {
|
||||||
confirm?: boolean;
|
confirm?: boolean;
|
||||||
@@ -24,12 +22,9 @@ export class StashApplyCommand extends Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async preExecute(context: CommandContext, args: StashApplyCommandArgs = { confirm: true, deleteAfter: false }) {
|
protected async preExecute(context: CommandContext, args: StashApplyCommandArgs = { confirm: true, deleteAfter: false }) {
|
||||||
if (context.type === 'view' && context.node instanceof StashCommitNode) {
|
if (isCommandViewContextWithCommit<GitStashCommit>(context)) {
|
||||||
args = { ...args };
|
args = { ...args };
|
||||||
|
args.stashItem = { stashName: context.node.commit.stashName, message: context.node.commit.message };
|
||||||
const stash = context.node.commit;
|
|
||||||
args.stashItem = { stashName: stash.stashName, message: stash.message };
|
|
||||||
|
|
||||||
return this.execute(args);
|
return this.execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { MessageItem, window } from 'vscode';
|
import { MessageItem, window } from 'vscode';
|
||||||
import { Command, CommandContext, Commands } from './common';
|
import { Command, CommandContext, Commands, isCommandViewContextWithCommit } from './common';
|
||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { GitService } from '../gitService';
|
import { GitService, GitStashCommit } from '../gitService';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { CommandQuickPickItem } from '../quickPicks';
|
import { CommandQuickPickItem } from '../quickPicks';
|
||||||
import { StashCommitNode } from '../views/stashCommitNode';
|
|
||||||
|
|
||||||
export interface StashDeleteCommandArgs {
|
export interface StashDeleteCommandArgs {
|
||||||
confirm?: boolean;
|
confirm?: boolean;
|
||||||
@@ -21,12 +20,9 @@ export class StashDeleteCommand extends Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async preExecute(context: CommandContext, args: StashDeleteCommandArgs = { confirm: true }) {
|
protected async preExecute(context: CommandContext, args: StashDeleteCommandArgs = { confirm: true }) {
|
||||||
if (context.type === 'view' && context.node instanceof StashCommitNode) {
|
if (isCommandViewContextWithCommit<GitStashCommit>(context)) {
|
||||||
args = { ...args };
|
args = { ...args };
|
||||||
|
args.stashItem = { stashName: context.node.commit.stashName, message: context.node.commit.message };
|
||||||
const stash = context.node.commit;
|
|
||||||
args.stashItem = { stashName: stash.stashName, message: stash.message };
|
|
||||||
|
|
||||||
return this.execute(args);
|
return this.execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { InputBoxOptions, window } from 'vscode';
|
import { InputBoxOptions, Uri, window } from 'vscode';
|
||||||
import { GitService } from '../gitService';
|
import { GitService } from '../gitService';
|
||||||
|
import { CommandContext } from '../commands';
|
||||||
import { Command, Commands } from './common';
|
import { Command, Commands } from './common';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
import { CommandQuickPickItem } from '../quickPicks';
|
import { CommandQuickPickItem } from '../quickPicks';
|
||||||
|
|
||||||
export interface StashSaveCommandArgs {
|
export interface StashSaveCommandArgs {
|
||||||
message?: string;
|
message?: string;
|
||||||
unstagedOnly?: boolean;
|
uris?: Uri[];
|
||||||
|
|
||||||
goBackCommand?: CommandQuickPickItem;
|
goBackCommand?: CommandQuickPickItem;
|
||||||
}
|
}
|
||||||
@@ -18,16 +19,28 @@ export class StashSaveCommand extends Command {
|
|||||||
super(Commands.StashSave);
|
super(Commands.StashSave);
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(args: StashSaveCommandArgs = { unstagedOnly: false }) {
|
protected async preExecute(context: CommandContext, args: StashSaveCommandArgs = {}): Promise<any> {
|
||||||
if (!this.git.repoPath) return undefined;
|
if (context.type === 'scm-states') {
|
||||||
|
|
||||||
args = { ...args };
|
args = { ...args };
|
||||||
if (args.unstagedOnly === undefined) {
|
args.uris = context.scmResourceStates.map(s => s.resourceUri);
|
||||||
args.unstagedOnly = false;
|
return this.execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.type === 'scm-groups') {
|
||||||
|
args = { ...args };
|
||||||
|
args.uris = context.scmResourceGroups.reduce<Uri[]>((a, b) => a.concat(b.resourceStates.map(s => s.resourceUri)), []);
|
||||||
|
return this.execute(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.execute(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(args: StashSaveCommandArgs = { }) {
|
||||||
|
if (!this.git.repoPath) return undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (args.message == null) {
|
if (args.message == null) {
|
||||||
|
args = { ...args };
|
||||||
args.message = await window.showInputBox({
|
args.message = await window.showInputBox({
|
||||||
prompt: `Please provide a stash message`,
|
prompt: `Please provide a stash message`,
|
||||||
placeHolder: `Stash message`
|
placeHolder: `Stash message`
|
||||||
@@ -35,7 +48,7 @@ export class StashSaveCommand extends Command {
|
|||||||
if (args.message === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
|
if (args.message === undefined) return args.goBackCommand === undefined ? undefined : args.goBackCommand.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.git.stashSave(this.git.repoPath, args.message, args.unstagedOnly);
|
return await this.git.stashSave(this.git.repoPath, args.message, args.uris);
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
Logger.error(ex, 'StashSaveCommand');
|
Logger.error(ex, 'StashSaveCommand');
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { TextEditor, TextEditorEdit } from 'vscode';
|
import { TextEditor, TextEditorEdit } from 'vscode';
|
||||||
|
import { CodeLensController } from '../codeLensController';
|
||||||
import { Commands, EditorCommand } from './common';
|
import { Commands, EditorCommand } from './common';
|
||||||
import { GitService } from '../gitService';
|
|
||||||
|
|
||||||
export class ToggleCodeLensCommand extends EditorCommand {
|
export class ToggleCodeLensCommand extends EditorCommand {
|
||||||
|
|
||||||
constructor(private git: GitService) {
|
constructor(private codeLensController: CodeLensController) {
|
||||||
super(Commands.ToggleCodeLens);
|
super(Commands.ToggleCodeLens);
|
||||||
}
|
}
|
||||||
|
|
||||||
execute(editor: TextEditor, edit: TextEditorEdit) {
|
execute(editor: TextEditor, edit: TextEditorEdit) {
|
||||||
return this.git.toggleCodeLens(editor);
|
return this.codeLensController.toggleCodeLens(editor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
import { FileAnnotationType } from './annotations/annotationController';
|
import { FileAnnotationType } from './annotations/annotationController';
|
||||||
import { Commands } from './commands';
|
import { Commands } from './commands';
|
||||||
import { LineAnnotationType } from './currentLineController';
|
import { LineAnnotationType } from './currentLineController';
|
||||||
|
import { GitExplorerView } from './views/gitExplorer';
|
||||||
import { OutputLevel } from './logger';
|
import { OutputLevel } from './logger';
|
||||||
|
|
||||||
export { ExtensionKey } from './constants';
|
export { ExtensionKey } from './constants';
|
||||||
@@ -297,14 +298,10 @@ export interface IConfig {
|
|||||||
defaultDateFormat: string | null;
|
defaultDateFormat: string | null;
|
||||||
|
|
||||||
gitExplorer: {
|
gitExplorer: {
|
||||||
enabled: boolean;
|
view: GitExplorerView;
|
||||||
|
showTrackingBranch: boolean;
|
||||||
commitFormat: string;
|
commitFormat: string;
|
||||||
commitFileFormat: string;
|
commitFileFormat: string;
|
||||||
// dateFormat: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
stashExplorer: {
|
|
||||||
enabled: boolean;
|
|
||||||
stashFormat: string;
|
stashFormat: string;
|
||||||
stashFileFormat: string;
|
stashFileFormat: string;
|
||||||
// dateFormat: string | null;
|
// dateFormat: string | null;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export const QualifiedExtensionId = `eamodio.${ExtensionId}`;
|
|||||||
|
|
||||||
export const ApplicationInsightsKey = 'a9c302f8-6483-4d01-b92c-c159c799c679';
|
export const ApplicationInsightsKey = 'a9c302f8-6483-4d01-b92c-c159c799c679';
|
||||||
|
|
||||||
|
export const FakeSha = 'ffffffffffffffffffffffffffffffffffffffff';
|
||||||
|
|
||||||
export type BuiltInCommands = 'cursorMove' |
|
export type BuiltInCommands = 'cursorMove' |
|
||||||
'editor.action.showReferences' |
|
'editor.action.showReferences' |
|
||||||
'editor.action.toggleRenderWhitespace' |
|
'editor.action.toggleRenderWhitespace' |
|
||||||
@@ -40,23 +42,25 @@ export const BuiltInCommands = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type CommandContext =
|
export type CommandContext =
|
||||||
|
'gitlens:annotationStatus' |
|
||||||
'gitlens:canToggleCodeLens' |
|
'gitlens:canToggleCodeLens' |
|
||||||
'gitlens:enabled' |
|
'gitlens:enabled' |
|
||||||
'gitlens:hasRemotes' |
|
'gitlens:hasRemotes' |
|
||||||
|
'gitlens:gitExplorer:view' |
|
||||||
'gitlens:isBlameable' |
|
'gitlens:isBlameable' |
|
||||||
'gitlens:isRepository' |
|
'gitlens:isRepository' |
|
||||||
'gitlens:isTracked' |
|
'gitlens:isTracked' |
|
||||||
'gitlens:key' |
|
'gitlens:key';
|
||||||
'gitlens:annotationStatus';
|
|
||||||
export const CommandContext = {
|
export const CommandContext = {
|
||||||
|
AnnotationStatus: 'gitlens:annotationStatus' as CommandContext,
|
||||||
CanToggleCodeLens: 'gitlens:canToggleCodeLens' as CommandContext,
|
CanToggleCodeLens: 'gitlens:canToggleCodeLens' as CommandContext,
|
||||||
Enabled: 'gitlens:enabled' as CommandContext,
|
Enabled: 'gitlens:enabled' as CommandContext,
|
||||||
|
GitExplorerView: 'gitlens:gitExplorer:view' as CommandContext,
|
||||||
HasRemotes: 'gitlens:hasRemotes' as CommandContext,
|
HasRemotes: 'gitlens:hasRemotes' as CommandContext,
|
||||||
IsBlameable: 'gitlens:isBlameable' as CommandContext,
|
IsBlameable: 'gitlens:isBlameable' as CommandContext,
|
||||||
IsRepository: 'gitlens:isRepository' as CommandContext,
|
IsRepository: 'gitlens:isRepository' as CommandContext,
|
||||||
IsTracked: 'gitlens:isTracked' as CommandContext,
|
IsTracked: 'gitlens:isTracked' as CommandContext,
|
||||||
Key: 'gitlens:key' as CommandContext,
|
Key: 'gitlens:key' as CommandContext
|
||||||
AnnotationStatus: 'gitlens:annotationStatus' as CommandContext
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function setCommandContext(key: CommandContext | string, value: any) {
|
export function setCommandContext(key: CommandContext | string, value: any) {
|
||||||
@@ -77,6 +81,7 @@ export type GlyphChars = '\u21a9' |
|
|||||||
'\u2194' |
|
'\u2194' |
|
||||||
'\u21e8' |
|
'\u21e8' |
|
||||||
'\u2191' |
|
'\u2191' |
|
||||||
|
'\u2713' |
|
||||||
'\u2014' |
|
'\u2014' |
|
||||||
'\u2022' |
|
'\u2022' |
|
||||||
'\u2026' |
|
'\u2026' |
|
||||||
@@ -90,6 +95,7 @@ export const GlyphChars = {
|
|||||||
ArrowLeftRight: '\u2194' as GlyphChars,
|
ArrowLeftRight: '\u2194' as GlyphChars,
|
||||||
ArrowRightHollow: '\u21e8' as GlyphChars,
|
ArrowRightHollow: '\u21e8' as GlyphChars,
|
||||||
ArrowUp: '\u2191' as GlyphChars,
|
ArrowUp: '\u2191' as GlyphChars,
|
||||||
|
Check: '\u2713' as GlyphChars,
|
||||||
Dash: '\u2014' as GlyphChars,
|
Dash: '\u2014' as GlyphChars,
|
||||||
Dot: '\u2022' as GlyphChars,
|
Dot: '\u2022' as GlyphChars,
|
||||||
Ellipsis: '\u2026' as GlyphChars,
|
Ellipsis: '\u2026' as GlyphChars,
|
||||||
|
|||||||
@@ -476,11 +476,11 @@ export class CurrentLineController extends Disposable {
|
|||||||
break;
|
break;
|
||||||
case StatusBarCommand.DiffWithPrevious:
|
case StatusBarCommand.DiffWithPrevious:
|
||||||
this._statusBarItem.command = Commands.DiffLineWithPrevious;
|
this._statusBarItem.command = Commands.DiffLineWithPrevious;
|
||||||
this._statusBarItem.tooltip = 'Compare Line Commit with Previous';
|
this._statusBarItem.tooltip = 'Compare Line Revision with Previous';
|
||||||
break;
|
break;
|
||||||
case StatusBarCommand.DiffWithWorking:
|
case StatusBarCommand.DiffWithWorking:
|
||||||
this._statusBarItem.command = Commands.DiffLineWithWorking;
|
this._statusBarItem.command = Commands.DiffLineWithWorking;
|
||||||
this._statusBarItem.tooltip = 'Compare Line Commit with Working Tree';
|
this._statusBarItem.tooltip = 'Compare Line Revision with Working';
|
||||||
break;
|
break;
|
||||||
case StatusBarCommand.ToggleCodeLens:
|
case StatusBarCommand.ToggleCodeLens:
|
||||||
this._statusBarItem.tooltip = 'Toggle Git CodeLens';
|
this._statusBarItem.tooltip = 'Toggle Git CodeLens';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { commands, ExtensionContext, extensions, languages, window, workspace } from 'vscode';
|
import { commands, ExtensionContext, extensions, languages, window, workspace } from 'vscode';
|
||||||
import { AnnotationController } from './annotations/annotationController';
|
import { AnnotationController } from './annotations/annotationController';
|
||||||
import { CloseUnchangedFilesCommand, OpenChangedFilesCommand } from './commands';
|
import { CloseUnchangedFilesCommand, OpenChangedFilesCommand } from './commands';
|
||||||
import { OpenBranchInRemoteCommand, OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenInRemoteCommand, OpenRepoInRemoteCommand } from './commands';
|
import { OpenBranchesInRemoteCommand, OpenBranchInRemoteCommand, OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenInRemoteCommand, OpenRepoInRemoteCommand } from './commands';
|
||||||
import { CopyMessageToClipboardCommand, CopyShaToClipboardCommand } from './commands';
|
import { CopyMessageToClipboardCommand, CopyShaToClipboardCommand } from './commands';
|
||||||
import { DiffDirectoryCommand, DiffLineWithPreviousCommand, DiffLineWithWorkingCommand, DiffWithBranchCommand, DiffWithNextCommand, DiffWithPreviousCommand, DiffWithRevisionCommand, DiffWithWorkingCommand } from './commands';
|
import { DiffDirectoryCommand, DiffLineWithPreviousCommand, DiffLineWithWorkingCommand, DiffWithBranchCommand, DiffWithNextCommand, DiffWithPreviousCommand, DiffWithRevisionCommand, DiffWithWorkingCommand } from './commands';
|
||||||
import { ResetSuppressedWarningsCommand } from './commands';
|
import { ResetSuppressedWarningsCommand } from './commands';
|
||||||
@@ -17,10 +17,10 @@ import { StashApplyCommand, StashDeleteCommand, StashSaveCommand } from './comma
|
|||||||
import { ToggleCodeLensCommand } from './commands';
|
import { ToggleCodeLensCommand } from './commands';
|
||||||
import { CodeLensLocations, IConfig, LineHighlightLocations } from './configuration';
|
import { CodeLensLocations, IConfig, LineHighlightLocations } from './configuration';
|
||||||
import { ApplicationInsightsKey, CommandContext, ExtensionKey, QualifiedExtensionId, setCommandContext, WorkspaceState } from './constants';
|
import { ApplicationInsightsKey, CommandContext, ExtensionKey, QualifiedExtensionId, setCommandContext, WorkspaceState } from './constants';
|
||||||
|
import { CodeLensController } from './codeLensController';
|
||||||
import { CurrentLineController, LineAnnotationType } from './currentLineController';
|
import { CurrentLineController, LineAnnotationType } from './currentLineController';
|
||||||
import { GitContentProvider } from './gitContentProvider';
|
import { GitContentProvider } from './gitContentProvider';
|
||||||
// import { GitExplorer } from './views/gitExplorer';
|
import { GitExplorer } from './views/gitExplorer';
|
||||||
import { StashExplorer } from './views/stashExplorer';
|
|
||||||
import { GitRevisionCodeLensProvider } from './gitRevisionCodeLensProvider';
|
import { GitRevisionCodeLensProvider } from './gitRevisionCodeLensProvider';
|
||||||
import { GitContextTracker, GitService } from './gitService';
|
import { GitContextTracker, GitService } from './gitService';
|
||||||
import { Keyboard } from './keyboard';
|
import { Keyboard } from './keyboard';
|
||||||
@@ -71,7 +71,7 @@ export async function activate(context: ExtensionContext) {
|
|||||||
|
|
||||||
await context.globalState.update(WorkspaceState.GitLensVersion, gitlensVersion);
|
await context.globalState.update(WorkspaceState.GitLensVersion, gitlensVersion);
|
||||||
|
|
||||||
const git = new GitService(context, repoPath);
|
const git = new GitService(repoPath);
|
||||||
context.subscriptions.push(git);
|
context.subscriptions.push(git);
|
||||||
|
|
||||||
const gitContextTracker = new GitContextTracker(git);
|
const gitContextTracker = new GitContextTracker(git);
|
||||||
@@ -84,15 +84,15 @@ export async function activate(context: ExtensionContext) {
|
|||||||
const annotationController = new AnnotationController(context, git, gitContextTracker);
|
const annotationController = new AnnotationController(context, git, gitContextTracker);
|
||||||
context.subscriptions.push(annotationController);
|
context.subscriptions.push(annotationController);
|
||||||
|
|
||||||
|
const codeLensController = new CodeLensController(context, git);
|
||||||
|
context.subscriptions.push(codeLensController);
|
||||||
|
|
||||||
const currentLineController = new CurrentLineController(context, git, gitContextTracker, annotationController);
|
const currentLineController = new CurrentLineController(context, git, gitContextTracker, annotationController);
|
||||||
context.subscriptions.push(currentLineController);
|
context.subscriptions.push(currentLineController);
|
||||||
|
|
||||||
context.subscriptions.push(new Keyboard());
|
context.subscriptions.push(new Keyboard());
|
||||||
|
|
||||||
// const explorer = new GitExplorer(context, git);
|
context.subscriptions.push(window.registerTreeDataProvider('gitlens.gitExplorer', new GitExplorer(context, git)));
|
||||||
// context.subscriptions.push(window.registerTreeDataProvider('gitlens.gitExplorer', explorer));
|
|
||||||
|
|
||||||
context.subscriptions.push(window.registerTreeDataProvider('gitlens.stashExplorer', new StashExplorer(context, git)));
|
|
||||||
|
|
||||||
context.subscriptions.push(commands.registerTextEditorCommand('gitlens.computingFileAnnotations', () => { }));
|
context.subscriptions.push(commands.registerTextEditorCommand('gitlens.computingFileAnnotations', () => { }));
|
||||||
|
|
||||||
@@ -108,6 +108,7 @@ export async function activate(context: ExtensionContext) {
|
|||||||
context.subscriptions.push(new DiffWithPreviousCommand(git));
|
context.subscriptions.push(new DiffWithPreviousCommand(git));
|
||||||
context.subscriptions.push(new DiffWithRevisionCommand(git));
|
context.subscriptions.push(new DiffWithRevisionCommand(git));
|
||||||
context.subscriptions.push(new DiffWithWorkingCommand(git));
|
context.subscriptions.push(new DiffWithWorkingCommand(git));
|
||||||
|
context.subscriptions.push(new OpenBranchesInRemoteCommand(git));
|
||||||
context.subscriptions.push(new OpenBranchInRemoteCommand(git));
|
context.subscriptions.push(new OpenBranchInRemoteCommand(git));
|
||||||
context.subscriptions.push(new OpenCommitInRemoteCommand(git));
|
context.subscriptions.push(new OpenCommitInRemoteCommand(git));
|
||||||
context.subscriptions.push(new OpenFileInRemoteCommand(git));
|
context.subscriptions.push(new OpenFileInRemoteCommand(git));
|
||||||
@@ -134,7 +135,7 @@ export async function activate(context: ExtensionContext) {
|
|||||||
context.subscriptions.push(new StashApplyCommand(git));
|
context.subscriptions.push(new StashApplyCommand(git));
|
||||||
context.subscriptions.push(new StashDeleteCommand(git));
|
context.subscriptions.push(new StashDeleteCommand(git));
|
||||||
context.subscriptions.push(new StashSaveCommand(git));
|
context.subscriptions.push(new StashSaveCommand(git));
|
||||||
context.subscriptions.push(new ToggleCodeLensCommand(git));
|
context.subscriptions.push(new ToggleCodeLensCommand(codeLensController));
|
||||||
|
|
||||||
// Constantly over my data cap so stop collecting initialized event
|
// Constantly over my data cap so stop collecting initialized event
|
||||||
// Telemetry.trackEvent('initialized', Objects.flatten(cfg, 'config', true));
|
// Telemetry.trackEvent('initialized', Objects.flatten(cfg, 'config', true));
|
||||||
@@ -273,10 +274,13 @@ async function notifyOnNewGitLensVersion(context: ExtensionContext, version: str
|
|||||||
const previousVersion = context.globalState.get<string>(WorkspaceState.GitLensVersion);
|
const previousVersion = context.globalState.get<string>(WorkspaceState.GitLensVersion);
|
||||||
|
|
||||||
if (previousVersion === undefined) {
|
if (previousVersion === undefined) {
|
||||||
|
Logger.log(`GitLens first-time install`);
|
||||||
await Messages.showWelcomeMessage();
|
await Messages.showWelcomeMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.log(`GitLens upgraded from v${previousVersion} to v${version}`);
|
||||||
|
|
||||||
const [major, minor] = version.split('.');
|
const [major, minor] = version.split('.');
|
||||||
const [prevMajor, prevMinor] = previousVersion.split('.');
|
const [prevMajor, prevMinor] = previousVersion.split('.');
|
||||||
if (major === prevMajor && minor === prevMinor) return;
|
if (major === prevMajor && minor === prevMinor) return;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import * as path from 'path';
|
|||||||
export interface IStatusFormatOptions extends IFormatOptions {
|
export interface IStatusFormatOptions extends IFormatOptions {
|
||||||
tokenOptions?: {
|
tokenOptions?: {
|
||||||
file?: Strings.ITokenOptions;
|
file?: Strings.ITokenOptions;
|
||||||
|
filePath?: Strings.ITokenOptions;
|
||||||
path?: Strings.ITokenOptions;
|
path?: Strings.ITokenOptions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -18,6 +19,11 @@ export class StatusFileFormatter extends Formatter<IGitStatusFile, IStatusFormat
|
|||||||
return this._padOrTruncate(file, this._options.tokenOptions!.file);
|
return this._padOrTruncate(file, this._options.tokenOptions!.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get filePath() {
|
||||||
|
const filePath = GitStatusFile.getFormattedPath(this._item);
|
||||||
|
return this._padOrTruncate(filePath, this._options.tokenOptions!.filePath);
|
||||||
|
}
|
||||||
|
|
||||||
get path() {
|
get path() {
|
||||||
const directory = GitStatusFile.getFormattedDirectory(this._item, false);
|
const directory = GitStatusFile.getFormattedDirectory(this._item, false);
|
||||||
return this._padOrTruncate(directory, this._options.tokenOptions!.file);
|
return this._padOrTruncate(directory, this._options.tokenOptions!.file);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import * as iconv from 'iconv-lite';
|
|||||||
export { IGit };
|
export { IGit };
|
||||||
export * from './models/models';
|
export * from './models/models';
|
||||||
export * from './parsers/blameParser';
|
export * from './parsers/blameParser';
|
||||||
|
export * from './parsers/branchParser';
|
||||||
export * from './parsers/diffParser';
|
export * from './parsers/diffParser';
|
||||||
export * from './parsers/logParser';
|
export * from './parsers/logParser';
|
||||||
export * from './parsers/stashParser';
|
export * from './parsers/stashParser';
|
||||||
@@ -31,10 +32,13 @@ const GitWarnings = [
|
|||||||
/Not a git repository/,
|
/Not a git repository/,
|
||||||
/is outside repository/,
|
/is outside repository/,
|
||||||
/no such path/,
|
/no such path/,
|
||||||
/does not have any commits/
|
/does not have any commits/,
|
||||||
|
/Path \'.*?\' does not exist in/,
|
||||||
|
/Path \'.*?\' exists on disk, but not in/,
|
||||||
|
/no upstream configured for branch/
|
||||||
];
|
];
|
||||||
|
|
||||||
async function gitCommand(options: { cwd: string, encoding?: string }, ...args: any[]) {
|
async function gitCommand(options: { cwd: string, encoding?: string, onError?: (ex: Error) => string | undefined }, ...args: any[]) {
|
||||||
try {
|
try {
|
||||||
// Fixes https://github.com/eamodio/vscode-gitlens/issues/73
|
// Fixes https://github.com/eamodio/vscode-gitlens/issues/73
|
||||||
// See https://stackoverflow.com/questions/4144417/how-to-handle-asian-characters-in-file-names-in-git-on-os-x
|
// See https://stackoverflow.com/questions/4144417/how-to-handle-asian-characters-in-file-names-in-git-on-os-x
|
||||||
@@ -48,6 +52,11 @@ async function gitCommand(options: { cwd: string, encoding?: string }, ...args:
|
|||||||
return iconv.decode(Buffer.from(s, 'binary'), opts.encoding);
|
return iconv.decode(Buffer.from(s, 'binary'), opts.encoding);
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
|
if (options.onError !== undefined) {
|
||||||
|
const result = options.onError(ex);
|
||||||
|
if (result !== undefined) return result;
|
||||||
|
}
|
||||||
|
|
||||||
const msg = ex && ex.toString();
|
const msg = ex && ex.toString();
|
||||||
if (msg) {
|
if (msg) {
|
||||||
for (const warning of GitWarnings) {
|
for (const warning of GitWarnings) {
|
||||||
@@ -166,15 +175,33 @@ export class Git {
|
|||||||
return gitCommand({ cwd: root }, ...params, `--`, file);
|
return gitCommand({ cwd: root }, ...params, `--`, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static branch(repoPath: string, all: boolean) {
|
static branch(repoPath: string, options: { all: boolean } = { all: false }) {
|
||||||
const params = [`branch`];
|
const params = [`branch`, `-vv`];
|
||||||
if (all) {
|
if (options.all) {
|
||||||
params.push(`-a`);
|
params.push(`-a`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return gitCommand({ cwd: repoPath }, ...params);
|
return gitCommand({ cwd: repoPath }, ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static branch_current(repoPath: string) {
|
||||||
|
const params = [`rev-parse`, `--abbrev-ref`, `--symbolic-full-name`, `@`, `@{u}`];
|
||||||
|
const onError = (ex: Error) => {
|
||||||
|
if (/no upstream configured for branch/.test(ex && ex.toString())) {
|
||||||
|
return ex.message.split('\n')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
return gitCommand({ cwd: repoPath, onError: onError }, ...params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static checkout(repoPath: string, fileName: string, sha: string) {
|
||||||
|
const [file, root] = Git.splitPath(fileName, repoPath);
|
||||||
|
|
||||||
|
return gitCommand({ cwd: root }, `checkout`, sha, `--`, file);
|
||||||
|
}
|
||||||
|
|
||||||
static async config_get(key: string, repoPath?: string) {
|
static async config_get(key: string, repoPath?: string) {
|
||||||
try {
|
try {
|
||||||
return await gitCommand({ cwd: repoPath || '' }, `config`, `--get`, key);
|
return await gitCommand({ cwd: repoPath || '' }, `config`, `--get`, key);
|
||||||
@@ -320,11 +347,18 @@ export class Git {
|
|||||||
return gitCommand({ cwd: repoPath }, ...defaultStashParams);
|
return gitCommand({ cwd: repoPath }, ...defaultStashParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
static stash_save(repoPath: string, message?: string, unstagedOnly: boolean = false) {
|
static stash_push(repoPath: string, pathspecs: string[], message?: string) {
|
||||||
const params = [`stash`, `save`, `--include-untracked`];
|
const params = [`stash`, `push`, `-u`];
|
||||||
if (unstagedOnly) {
|
if (message) {
|
||||||
params.push(`--keep-index`);
|
params.push(`-m`);
|
||||||
|
params.push(message);
|
||||||
}
|
}
|
||||||
|
params.splice(params.length, 0, `--`, ...pathspecs);
|
||||||
|
return gitCommand({ cwd: repoPath }, ...params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static stash_save(repoPath: string, message?: string) {
|
||||||
|
const params = [`stash`, `save`, `-u`];
|
||||||
if (message) {
|
if (message) {
|
||||||
params.push(message);
|
params.push(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,9 @@ export class GitBranch {
|
|||||||
current: boolean;
|
current: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
remote: boolean;
|
remote: boolean;
|
||||||
|
tracking?: string;
|
||||||
|
|
||||||
constructor(branch: string) {
|
constructor(public readonly repoPath: string, branch: string, current: boolean = false, tracking?: string) {
|
||||||
branch = branch.trim();
|
|
||||||
|
|
||||||
if (branch.startsWith('* ')) {
|
|
||||||
branch = branch.substring(2);
|
|
||||||
this.current = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (branch.startsWith('remotes/')) {
|
if (branch.startsWith('remotes/')) {
|
||||||
branch = branch.substring(8);
|
branch = branch.substring(8);
|
||||||
this.remote = true;
|
this.remote = true;
|
||||||
@@ -24,6 +18,24 @@ export class GitBranch {
|
|||||||
branch = branch.substring(0, index);
|
branch = branch.substring(0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.current = current;
|
||||||
this.name = branch;
|
this.name = branch;
|
||||||
|
this.tracking = tracking;
|
||||||
|
}
|
||||||
|
|
||||||
|
getName(): string {
|
||||||
|
return this.remote
|
||||||
|
? this.name.substring(this.name.indexOf('/') + 1)
|
||||||
|
: this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRemote(): string | undefined {
|
||||||
|
if (this.remote) return GitBranch.getRemote(this.name);
|
||||||
|
if (this.tracking !== undefined) return GitBranch.getRemote(this.tracking);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRemote(branch: string): string {
|
||||||
|
return branch.substring(0, branch.indexOf('/'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ export class GitStatusFile implements IGitStatusFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFormattedPath(separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
|
getFormattedPath(separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
|
||||||
return GitUri.getFormattedPath(this.fileName, separator);
|
return GitStatusFile.getFormattedPath(this, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
getOcticon() {
|
getOcticon() {
|
||||||
@@ -57,6 +57,10 @@ export class GitStatusFile implements IGitStatusFile {
|
|||||||
? `${directory} ${Strings.pad(GlyphChars.ArrowLeft, 1, 1)} ${status.originalFileName}`
|
? `${directory} ${Strings.pad(GlyphChars.ArrowLeft, 1, 1)} ${status.originalFileName}`
|
||||||
: directory;
|
: directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getFormattedPath(status: IGitStatusFile, separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
|
||||||
|
return GitUri.getFormattedPath(status.fileName, separator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusOcticonsMap = {
|
const statusOcticonsMap = {
|
||||||
|
|||||||
24
src/git/parsers/branchParser.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
'use strict';
|
||||||
|
import { GitBranch } from './../git';
|
||||||
|
const branchWithTrackingRegex = /^(\*?)\s+(.+?)\s+([0-9,a-f]+)\s+(?:\[(.*?\/.*?)(?:\:|\]))?/gm;
|
||||||
|
|
||||||
|
export class GitBranchParser {
|
||||||
|
|
||||||
|
static parse(data: string, repoPath: string): GitBranch[] | undefined {
|
||||||
|
if (!data) return undefined;
|
||||||
|
|
||||||
|
const branches: GitBranch[] = [];
|
||||||
|
|
||||||
|
let match: RegExpExecArray | null = null;
|
||||||
|
do {
|
||||||
|
match = branchWithTrackingRegex.exec(data);
|
||||||
|
if (match == null) break;
|
||||||
|
|
||||||
|
branches.push(new GitBranch(repoPath, match[2], match[1] === '*', match[4]));
|
||||||
|
} while (match != null);
|
||||||
|
|
||||||
|
if (!branches.length) return undefined;
|
||||||
|
|
||||||
|
return branches;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,10 @@ export class BitbucketService extends RemoteProvider {
|
|||||||
return 'Bitbucket';
|
return 'Bitbucket';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getUrlForBranches(): string {
|
||||||
|
return `${this.baseUrl}/branches`;
|
||||||
|
}
|
||||||
|
|
||||||
protected getUrlForBranch(branch: string): string {
|
protected getUrlForBranch(branch: string): string {
|
||||||
return `${this.baseUrl}/commits/branch/${branch}`;
|
return `${this.baseUrl}/commits/branch/${branch}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ export class GitHubService extends RemoteProvider {
|
|||||||
return 'GitHub';
|
return 'GitHub';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getUrlForBranches(): string {
|
||||||
|
return `${this.baseUrl}/branches`;
|
||||||
|
}
|
||||||
|
|
||||||
protected getUrlForBranch(branch: string): string {
|
protected getUrlForBranch(branch: string): string {
|
||||||
return `${this.baseUrl}/commits/${branch}`;
|
return `${this.baseUrl}/commits/${branch}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,20 +3,23 @@ import { commands, Range, Uri } from 'vscode';
|
|||||||
import { BuiltInCommands } from '../../constants';
|
import { BuiltInCommands } from '../../constants';
|
||||||
import { GitLogCommit } from '../../gitService';
|
import { GitLogCommit } from '../../gitService';
|
||||||
|
|
||||||
export type RemoteResourceType = 'branch' | 'commit' | 'file' | 'repo' | 'working-file';
|
export type RemoteResourceType = 'branch' | 'branches' | 'commit' | 'file' | 'repo' | 'revision';
|
||||||
export type RemoteResource = { type: 'branch', branch: string } |
|
export type RemoteResource =
|
||||||
|
{ type: 'branch', branch: string } |
|
||||||
|
{ type: 'branches' } |
|
||||||
{ type: 'commit', sha: string } |
|
{ type: 'commit', sha: string } |
|
||||||
{ type: 'file', branch?: string, commit?: GitLogCommit, fileName: string, range?: Range, sha?: string } |
|
{ type: 'file', branch?: string, fileName: string, range?: Range } |
|
||||||
{ type: 'repo' } |
|
{ type: 'repo' } |
|
||||||
{ type: 'working-file', branch?: string, fileName: string, range?: Range };
|
{ type: 'revision', branch?: string, commit?: GitLogCommit, fileName: string, range?: Range, sha?: string };
|
||||||
|
|
||||||
export function getNameFromRemoteResource(resource: RemoteResource) {
|
export function getNameFromRemoteResource(resource: RemoteResource) {
|
||||||
switch (resource.type) {
|
switch (resource.type) {
|
||||||
case 'branch': return 'Branch';
|
case 'branch': return 'Branch';
|
||||||
|
case 'branches': return 'Branches';
|
||||||
case 'commit': return 'Commit';
|
case 'commit': return 'Commit';
|
||||||
case 'file': return 'File';
|
case 'file': return 'File';
|
||||||
case 'repo': return 'Repository';
|
case 'repo': return 'Repository';
|
||||||
case 'working-file': return 'Working File';
|
case 'revision': return 'Revision';
|
||||||
default: return '';
|
default: return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,6 +34,7 @@ export abstract class RemoteProvider {
|
|||||||
return `https://${this.domain}/${this.path}`;
|
return `https://${this.domain}/${this.path}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract getUrlForBranches(): string;
|
||||||
protected abstract getUrlForBranch(branch: string): string;
|
protected abstract getUrlForBranch(branch: string): string;
|
||||||
protected abstract getUrlForCommit(sha: string): string;
|
protected abstract getUrlForCommit(sha: string): string;
|
||||||
protected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string;
|
protected abstract getUrlForFile(fileName: string, branch?: string, sha?: string, range?: Range): string;
|
||||||
@@ -43,16 +47,12 @@ export abstract class RemoteProvider {
|
|||||||
|
|
||||||
open(resource: RemoteResource): Promise<{} | undefined> {
|
open(resource: RemoteResource): Promise<{} | undefined> {
|
||||||
switch (resource.type) {
|
switch (resource.type) {
|
||||||
case 'branch':
|
case 'branch': return this.openBranch(resource.branch);
|
||||||
return this.openBranch(resource.branch);
|
case 'branches': return this.openBranches();
|
||||||
case 'commit':
|
case 'commit': return this.openCommit(resource.sha);
|
||||||
return this.openCommit(resource.sha);
|
case 'file': return this.openFile(resource.fileName, resource.branch, undefined, resource.range);
|
||||||
case 'file':
|
case 'repo': return this.openRepo();
|
||||||
return this.openFile(resource.fileName, resource.branch, resource.sha, resource.range);
|
case 'revision': return this.openFile(resource.fileName, resource.branch, resource.sha, resource.range);
|
||||||
case 'repo':
|
|
||||||
return this.openRepo();
|
|
||||||
case 'working-file':
|
|
||||||
return this.openFile(resource.fileName, resource.branch, undefined, resource.range);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,6 +60,10 @@ export abstract class RemoteProvider {
|
|||||||
return this._openUrl(this.baseUrl);
|
return this._openUrl(this.baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openBranches() {
|
||||||
|
return this._openUrl(this.getUrlForBranches());
|
||||||
|
}
|
||||||
|
|
||||||
openBranch(branch: string) {
|
openBranch(branch: string) {
|
||||||
return this._openUrl(this.getUrlForBranch(branch));
|
return this._openUrl(this.getUrlForBranch(branch));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ export class VisualStudioService extends RemoteProvider {
|
|||||||
return 'Visual Studio Team Services';
|
return 'Visual Studio Team Services';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getUrlForBranches(): string {
|
||||||
|
return `${this.baseUrl}/branches`;
|
||||||
|
}
|
||||||
|
|
||||||
protected getUrlForBranch(branch: string): string {
|
protected getUrlForBranch(branch: string): string {
|
||||||
return `${this.baseUrl}/?version=GB${branch}&_a=history`;
|
return `${this.baseUrl}/?version=GB${branch}&_a=history`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { ExtensionContext, TextDocumentContentProvider, Uri, window } from 'vscode';
|
import { CancellationToken, ExtensionContext, TextDocumentContentProvider, Uri, window } from 'vscode';
|
||||||
import { DocumentSchemes } from './constants';
|
import { DocumentSchemes } from './constants';
|
||||||
import { GitService } from './gitService';
|
import { GitService } from './gitService';
|
||||||
import { Logger } from './logger';
|
import { Logger } from './logger';
|
||||||
@@ -11,7 +11,7 @@ export class GitContentProvider implements TextDocumentContentProvider {
|
|||||||
|
|
||||||
constructor(context: ExtensionContext, private git: GitService) { }
|
constructor(context: ExtensionContext, private git: GitService) { }
|
||||||
|
|
||||||
async provideTextDocumentContent(uri: Uri): Promise<string> {
|
async provideTextDocumentContent(uri: Uri, token: CancellationToken): Promise<string | undefined> {
|
||||||
const data = GitService.fromGitContentUri(uri);
|
const data = GitService.fromGitContentUri(uri);
|
||||||
const fileName = data.originalFileName || data.fileName;
|
const fileName = data.originalFileName || data.fileName;
|
||||||
try {
|
try {
|
||||||
@@ -23,8 +23,8 @@ export class GitContentProvider implements TextDocumentContentProvider {
|
|||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
Logger.error(ex, 'GitContentProvider', 'getVersionedFileText');
|
Logger.error(ex, 'GitContentProvider', 'getVersionedFileText');
|
||||||
await window.showErrorMessage(`Unable to show Git revision ${data.sha.substring(0, 8)} of '${path.relative(data.repoPath, fileName)}'`);
|
window.showErrorMessage(`Unable to show Git revision ${data.sha.substring(0, 8)} of '${path.relative(data.repoPath, fileName)}'`);
|
||||||
return '';
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,13 +32,12 @@ export class GitRevisionCodeLensProvider implements CodeLensProvider {
|
|||||||
const lenses: CodeLens[] = [];
|
const lenses: CodeLens[] = [];
|
||||||
|
|
||||||
const commit = await this.git.getLogCommit(gitUri.repoPath, gitUri.fsPath, gitUri.sha, { firstIfMissing: true, previous: true });
|
const commit = await this.git.getLogCommit(gitUri.repoPath, gitUri.fsPath, gitUri.sha, { firstIfMissing: true, previous: true });
|
||||||
if (!commit) return lenses;
|
if (commit === undefined) return lenses;
|
||||||
|
|
||||||
lenses.push(new GitDiffWithWorkingCodeLens(this.git, commit.uri.fsPath, commit, new Range(0, 0, 0, 1)));
|
|
||||||
|
|
||||||
if (commit.previousSha) {
|
if (commit.previousSha) {
|
||||||
lenses.push(new GitDiffWithPreviousCodeLens(this.git, commit.previousUri.fsPath, commit, new Range(0, 1, 0, 2)));
|
lenses.push(new GitDiffWithPreviousCodeLens(this.git, commit.previousUri.fsPath, commit, new Range(0, 0, 0, 1)));
|
||||||
}
|
}
|
||||||
|
lenses.push(new GitDiffWithWorkingCodeLens(this.git, commit.uri.fsPath, commit, new Range(0, 1, 0, 2)));
|
||||||
|
|
||||||
return lenses;
|
return lenses;
|
||||||
}
|
}
|
||||||
@@ -51,7 +50,7 @@ export class GitRevisionCodeLensProvider implements CodeLensProvider {
|
|||||||
|
|
||||||
_resolveDiffWithWorkingTreeCodeLens(lens: GitDiffWithWorkingCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
_resolveDiffWithWorkingTreeCodeLens(lens: GitDiffWithWorkingCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
||||||
lens.command = {
|
lens.command = {
|
||||||
title: `Compare ${lens.commit.shortSha} with Working Tree`,
|
title: `Compare Revision (${lens.commit.shortSha}) with Working`,
|
||||||
command: Commands.DiffWithWorking,
|
command: Commands.DiffWithWorking,
|
||||||
arguments: [
|
arguments: [
|
||||||
Uri.file(lens.fileName),
|
Uri.file(lens.fileName),
|
||||||
@@ -66,7 +65,7 @@ export class GitRevisionCodeLensProvider implements CodeLensProvider {
|
|||||||
|
|
||||||
_resolveGitDiffWithPreviousCodeLens(lens: GitDiffWithPreviousCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
_resolveGitDiffWithPreviousCodeLens(lens: GitDiffWithPreviousCodeLens, token: CancellationToken): Thenable<CodeLens> {
|
||||||
lens.command = {
|
lens.command = {
|
||||||
title: `Compare ${lens.commit.shortSha} with Previous ${lens.commit.previousShortSha}`,
|
title: `Compare Revision (${lens.commit.shortSha}) with Previous (${lens.commit.previousShortSha})`,
|
||||||
command: Commands.DiffWithPrevious,
|
command: Commands.DiffWithPrevious,
|
||||||
arguments: [
|
arguments: [
|
||||||
Uri.file(lens.fileName),
|
Uri.file(lens.fileName),
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Functions, Iterables, Objects } from './system';
|
import { Functions, Iterables, Objects } from './system';
|
||||||
import { Disposable, Event, EventEmitter, ExtensionContext, FileSystemWatcher, languages, Location, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, workspace } from 'vscode';
|
import { Disposable, Event, EventEmitter, FileSystemWatcher, Location, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, workspace } from 'vscode';
|
||||||
import { IConfig } from './configuration';
|
import { IConfig } from './configuration';
|
||||||
import { CommandContext, DocumentSchemes, ExtensionKey, GlyphChars, setCommandContext } from './constants';
|
import { DocumentSchemes, ExtensionKey, GlyphChars } from './constants';
|
||||||
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitCommit, GitDiff, GitDiffChunkLine, GitDiffParser, GitLog, GitLogCommit, GitLogParser, GitRemote, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, IGit, setDefaultEncoding } from './git/git';
|
import { Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitDiff, GitDiffChunkLine, GitDiffParser, GitLog, GitLogCommit, GitLogParser, GitRemote, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, IGit, setDefaultEncoding } from './git/git';
|
||||||
import { GitUri, IGitCommitInfo, IGitUriData } from './git/gitUri';
|
import { GitUri, IGitCommitInfo, IGitUriData } from './git/gitUri';
|
||||||
import { GitCodeLensProvider } from './gitCodeLensProvider';
|
|
||||||
import { Logger } from './logger';
|
import { Logger } from './logger';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as ignore from 'ignore';
|
import * as ignore from 'ignore';
|
||||||
@@ -65,7 +64,11 @@ export const GitRepoSearchBy = {
|
|||||||
Sha: 'sha' as GitRepoSearchBy
|
Sha: 'sha' as GitRepoSearchBy
|
||||||
};
|
};
|
||||||
|
|
||||||
type RepoChangedReasons = 'stash' | 'unknown';
|
export type RepoChangedReasons = 'stash' | 'unknown';
|
||||||
|
export const RepoChangedReasons = {
|
||||||
|
Stash: 'stash' as RepoChangedReasons,
|
||||||
|
Unknown: 'unknown' as RepoChangedReasons
|
||||||
|
};
|
||||||
|
|
||||||
export class GitService extends Disposable {
|
export class GitService extends Disposable {
|
||||||
|
|
||||||
@@ -90,8 +93,6 @@ export class GitService extends Disposable {
|
|||||||
private _uriCache: Map<string, UriCacheEntry>;
|
private _uriCache: Map<string, UriCacheEntry>;
|
||||||
|
|
||||||
config: IConfig;
|
config: IConfig;
|
||||||
private _codeLensProvider: GitCodeLensProvider | undefined;
|
|
||||||
private _codeLensProviderDisposable: Disposable | undefined;
|
|
||||||
private _disposable: Disposable | undefined;
|
private _disposable: Disposable | undefined;
|
||||||
private _gitignore: Promise<ignore.Ignore | undefined>;
|
private _gitignore: Promise<ignore.Ignore | undefined>;
|
||||||
private _repoWatcher: FileSystemWatcher | undefined;
|
private _repoWatcher: FileSystemWatcher | undefined;
|
||||||
@@ -99,7 +100,7 @@ export class GitService extends Disposable {
|
|||||||
|
|
||||||
static EmptyPromise: Promise<GitBlame | GitDiff | GitLog | undefined> = Promise.resolve(undefined);
|
static EmptyPromise: Promise<GitBlame | GitDiff | GitLog | undefined> = Promise.resolve(undefined);
|
||||||
|
|
||||||
constructor(private context: ExtensionContext, public repoPath: string) {
|
constructor(public repoPath: string) {
|
||||||
super(() => this.dispose());
|
super(() => this.dispose());
|
||||||
|
|
||||||
this._gitCache = new Map();
|
this._gitCache = new Map();
|
||||||
@@ -118,10 +119,6 @@ export class GitService extends Disposable {
|
|||||||
dispose() {
|
dispose() {
|
||||||
this._disposable && this._disposable.dispose();
|
this._disposable && this._disposable.dispose();
|
||||||
|
|
||||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
|
||||||
this._codeLensProviderDisposable = undefined;
|
|
||||||
this._codeLensProvider = undefined;
|
|
||||||
|
|
||||||
this._cacheDisposable && this._cacheDisposable.dispose();
|
this._cacheDisposable && this._cacheDisposable.dispose();
|
||||||
this._cacheDisposable = undefined;
|
this._cacheDisposable = undefined;
|
||||||
|
|
||||||
@@ -146,30 +143,7 @@ export class GitService extends Disposable {
|
|||||||
|
|
||||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||||
|
|
||||||
const codeLensChanged = !Objects.areEquivalent(cfg.codeLens, this.config && this.config.codeLens);
|
if (!Objects.areEquivalent(cfg.advanced, this.config && this.config.advanced)) {
|
||||||
const advancedChanged = !Objects.areEquivalent(cfg.advanced, this.config && this.config.advanced);
|
|
||||||
|
|
||||||
if (codeLensChanged) {
|
|
||||||
Logger.log('CodeLens config changed; resetting CodeLens provider');
|
|
||||||
if (cfg.codeLens.enabled && (cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled)) {
|
|
||||||
if (this._codeLensProvider) {
|
|
||||||
this._codeLensProvider.reset();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._codeLensProvider = new GitCodeLensProvider(this.context, this);
|
|
||||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._codeLensProvider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._codeLensProviderDisposable && this._codeLensProviderDisposable.dispose();
|
|
||||||
this._codeLensProviderDisposable = undefined;
|
|
||||||
this._codeLensProvider = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCommandContext(CommandContext.CanToggleCodeLens, cfg.codeLens.recentChange.enabled || cfg.codeLens.authors.enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (advancedChanged) {
|
|
||||||
if (cfg.advanced.caching.enabled) {
|
if (cfg.advanced.caching.enabled) {
|
||||||
this._cacheDisposable && this._cacheDisposable.dispose();
|
this._cacheDisposable && this._cacheDisposable.dispose();
|
||||||
|
|
||||||
@@ -264,9 +238,6 @@ export class GitService extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _fireGitCacheChangeCore() {
|
private _fireGitCacheChangeCore() {
|
||||||
// Refresh the code lenses
|
|
||||||
this._codeLensProvider && this._codeLensProvider.reset();
|
|
||||||
|
|
||||||
this._onDidChangeGitCache.fire();
|
this._onDidChangeGitCache.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +281,13 @@ export class GitService extends Disposable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkoutFile(uri: GitUri, sha?: string) {
|
||||||
|
sha = sha || uri.sha;
|
||||||
|
Logger.log(`checkoutFile('${uri.repoPath}', '${uri.fsPath}', ${sha})`);
|
||||||
|
|
||||||
|
return Git.checkout(uri.repoPath!, uri.fsPath, sha!);
|
||||||
|
}
|
||||||
|
|
||||||
private async _fileExists(repoPath: string, fileName: string): Promise<boolean> {
|
private async _fileExists(repoPath: string, fileName: string): Promise<boolean> {
|
||||||
return await new Promise<boolean>((resolve, reject) => fs.exists(path.resolve(repoPath, fileName), resolve));
|
return await new Promise<boolean>((resolve, reject) => fs.exists(path.resolve(repoPath, fileName), resolve));
|
||||||
}
|
}
|
||||||
@@ -594,17 +572,16 @@ export class GitService extends Disposable {
|
|||||||
async getBranch(repoPath: string): Promise<GitBranch | undefined> {
|
async getBranch(repoPath: string): Promise<GitBranch | undefined> {
|
||||||
Logger.log(`getBranch('${repoPath}')`);
|
Logger.log(`getBranch('${repoPath}')`);
|
||||||
|
|
||||||
const data = await Git.branch(repoPath, false);
|
const data = await Git.branch_current(repoPath);
|
||||||
const branches = data.split('\n').filter(_ => !!_).map(_ => new GitBranch(_));
|
const branch = data.split('\n');
|
||||||
return branches.find(_ => _.current);
|
return new GitBranch(repoPath, branch[0], true, branch[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBranches(repoPath: string): Promise<GitBranch[]> {
|
async getBranches(repoPath: string): Promise<GitBranch[]> {
|
||||||
Logger.log(`getBranches('${repoPath}')`);
|
Logger.log(`getBranches('${repoPath}')`);
|
||||||
|
|
||||||
const data = await Git.branch(repoPath, true);
|
const data = await Git.branch(repoPath, { all: true });
|
||||||
const branches = data.split('\n').filter(_ => !!_).map(_ => new GitBranch(_));
|
return GitBranchParser.parse(data, repoPath) || [];
|
||||||
return branches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCacheEntryKey(fileName: string): string;
|
getCacheEntryKey(fileName: string): string;
|
||||||
@@ -1047,23 +1024,12 @@ export class GitService extends Disposable {
|
|||||||
return Git.stash_delete(repoPath, stashName);
|
return Git.stash_delete(repoPath, stashName);
|
||||||
}
|
}
|
||||||
|
|
||||||
stashSave(repoPath: string, message?: string, unstagedOnly: boolean = false) {
|
stashSave(repoPath: string, message?: string, uris?: Uri[]) {
|
||||||
Logger.log(`stashSave('${repoPath}', ${message}, ${unstagedOnly})`);
|
Logger.log(`stashSave('${repoPath}', ${message}, ${uris})`);
|
||||||
|
|
||||||
return Git.stash_save(repoPath, message, unstagedOnly);
|
if (uris === undefined) return Git.stash_save(repoPath, message);
|
||||||
}
|
const pathspecs = uris.map(u => Git.splitPath(u.fsPath, repoPath)[0]);
|
||||||
|
return Git.stash_push(repoPath, pathspecs, message);
|
||||||
toggleCodeLens(editor: TextEditor) {
|
|
||||||
if (!this.config.codeLens.recentChange.enabled && !this.config.codeLens.authors.enabled) return;
|
|
||||||
|
|
||||||
Logger.log(`toggleCodeLens()`);
|
|
||||||
if (this._codeLensProviderDisposable) {
|
|
||||||
this._codeLensProviderDisposable.dispose();
|
|
||||||
this._codeLensProviderDisposable = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._codeLensProviderDisposable = languages.registerCodeLensProvider(GitCodeLensProvider.selector, new GitCodeLensProvider(this.context, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static getGitPath(gitPath?: string): Promise<IGit> {
|
static getGitPath(gitPath?: string): Promise<IGit> {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { commands, ExtensionContext, Uri, window } from 'vscode';
|
import { commands, ExtensionContext, Uri, window } from 'vscode';
|
||||||
import { BuiltInCommands } from './constants';
|
import { BuiltInCommands } from './constants';
|
||||||
import { GitCommit } from './gitService';
|
import { GitCommit } from './gitService';
|
||||||
|
import { Logger } from './logger';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
export type SuppressedKeys = 'suppressCommitHasNoPreviousCommitWarning' |
|
export type SuppressedKeys = 'suppressCommitHasNoPreviousCommitWarning' |
|
||||||
@@ -10,7 +11,8 @@ export type SuppressedKeys = 'suppressCommitHasNoPreviousCommitWarning' |
|
|||||||
'suppressGitVersionWarning' |
|
'suppressGitVersionWarning' |
|
||||||
'suppressLineUncommittedWarning' |
|
'suppressLineUncommittedWarning' |
|
||||||
'suppressNoRepositoryWarning' |
|
'suppressNoRepositoryWarning' |
|
||||||
'suppressUpdateNotice';
|
'suppressUpdateNotice' |
|
||||||
|
'suppressWelcomeNotice';
|
||||||
export const SuppressedKeys = {
|
export const SuppressedKeys = {
|
||||||
CommitHasNoPreviousCommitWarning: 'suppressCommitHasNoPreviousCommitWarning' as SuppressedKeys,
|
CommitHasNoPreviousCommitWarning: 'suppressCommitHasNoPreviousCommitWarning' as SuppressedKeys,
|
||||||
CommitNotFoundWarning: 'suppressCommitNotFoundWarning' as SuppressedKeys,
|
CommitNotFoundWarning: 'suppressCommitNotFoundWarning' as SuppressedKeys,
|
||||||
@@ -18,7 +20,8 @@ export const SuppressedKeys = {
|
|||||||
GitVersionWarning: 'suppressGitVersionWarning' as SuppressedKeys,
|
GitVersionWarning: 'suppressGitVersionWarning' as SuppressedKeys,
|
||||||
LineUncommittedWarning: 'suppressLineUncommittedWarning' as SuppressedKeys,
|
LineUncommittedWarning: 'suppressLineUncommittedWarning' as SuppressedKeys,
|
||||||
NoRepositoryWarning: 'suppressNoRepositoryWarning' as SuppressedKeys,
|
NoRepositoryWarning: 'suppressNoRepositoryWarning' as SuppressedKeys,
|
||||||
UpdateNotice: 'suppressUpdateNotice' as SuppressedKeys
|
UpdateNotice: 'suppressUpdateNotice' as SuppressedKeys,
|
||||||
|
WelcomeNotice: 'suppressWelcomeNotice' as SuppressedKeys
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Messages {
|
export class Messages {
|
||||||
@@ -64,7 +67,7 @@ export class Messages {
|
|||||||
|
|
||||||
static async showWelcomeMessage(): Promise<string | undefined> {
|
static async showWelcomeMessage(): Promise<string | undefined> {
|
||||||
const viewDocs = 'View Docs';
|
const viewDocs = 'View Docs';
|
||||||
const result = await window.showInformationMessage(`Thank you for choosing GitLens! GitLens is powerful, feature rich, and highly configurable, so please be sure to view the docs and tailor it to suit your needs.`, viewDocs);
|
const result = await Messages._showMessage('info', `Thank you for choosing GitLens! GitLens is powerful, feature rich, and highly configurable, so please be sure to view the docs and tailor it to suit your needs.`, SuppressedKeys.WelcomeNotice, null, viewDocs);
|
||||||
if (result === viewDocs) {
|
if (result === viewDocs) {
|
||||||
commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://marketplace.visualstudio.com/items/eamodio.gitlens'));
|
commands.executeCommand(BuiltInCommands.Open, Uri.parse('https://marketplace.visualstudio.com/items/eamodio.gitlens'));
|
||||||
}
|
}
|
||||||
@@ -72,7 +75,12 @@ export class Messages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async _showMessage(type: 'info' | 'warn' | 'error', message: string, suppressionKey: SuppressedKeys, dontShowAgain: string | null = 'Don\'t Show Again', ...actions: any[]): Promise<string | undefined> {
|
private static async _showMessage(type: 'info' | 'warn' | 'error', message: string, suppressionKey: SuppressedKeys, dontShowAgain: string | null = 'Don\'t Show Again', ...actions: any[]): Promise<string | undefined> {
|
||||||
if (Messages.context.globalState.get(suppressionKey, false)) return undefined;
|
Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain})`);
|
||||||
|
|
||||||
|
if (Messages.context.globalState.get(suppressionKey, false)) {
|
||||||
|
Logger.log(`ShowMessage(${type}, ${message}, ${suppressionKey}, ${dontShowAgain}) skipped`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (dontShowAgain !== null) {
|
if (dontShowAgain !== null) {
|
||||||
actions.push(dontShowAgain);
|
actions.push(dontShowAgain);
|
||||||
@@ -94,10 +102,13 @@ export class Messages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dontShowAgain === null || result === dontShowAgain) {
|
if (dontShowAgain === null || result === dontShowAgain) {
|
||||||
|
Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain}) don't show again requested`);
|
||||||
await Messages.context.globalState.update(suppressionKey, true);
|
await Messages.context.globalState.update(suppressionKey, true);
|
||||||
return undefined;
|
|
||||||
|
if (result === dontShowAgain) return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain}) returned ${result}`);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,28 +69,31 @@ export class CommitWithFileStatusQuickPickItem extends OpenFileCommandQuickPickI
|
|||||||
|
|
||||||
export class OpenCommitFilesCommandQuickPickItem extends OpenFilesCommandQuickPickItem {
|
export class OpenCommitFilesCommandQuickPickItem extends OpenFilesCommandQuickPickItem {
|
||||||
|
|
||||||
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
constructor(commit: GitLogCommit, versioned: boolean = false, item?: QuickPickItem) {
|
||||||
const uris = commit.fileStatuses.map(s => (s.status === 'D')
|
const repoPath = commit.repoPath;
|
||||||
? GitService.toGitContentUri(commit.previousSha!, commit.previousShortSha!, s.fileName, commit.repoPath, s.originalFileName)
|
const uris = commit.fileStatuses
|
||||||
: GitService.toGitContentUri(commit.sha, commit.shortSha, s.fileName, commit.repoPath, s.originalFileName));
|
.filter(s => s.status !== 'D')
|
||||||
|
.map(s => GitUri.fromFileStatus(s, repoPath));
|
||||||
|
|
||||||
super(uris, item || {
|
super(uris, item || {
|
||||||
label: `$(file-symlink-file) Open Changed Files`,
|
label: `$(file-symlink-file) Open Changed Files`,
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}`
|
description: ''
|
||||||
// detail: `Opens all of the changed files in $(git-commit) ${commit.shortSha}`
|
// detail: `Opens all of the changed file in the working tree`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OpenCommitWorkingTreeFilesCommandQuickPickItem extends OpenFilesCommandQuickPickItem {
|
export class OpenCommitFileRevisionsCommandQuickPickItem extends OpenFilesCommandQuickPickItem {
|
||||||
|
|
||||||
|
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
||||||
|
const uris = commit.fileStatuses
|
||||||
|
.filter(s => s.status !== 'D')
|
||||||
|
.map(s => GitService.toGitContentUri(commit.sha, commit.shortSha, s.fileName, commit.repoPath, s.originalFileName));
|
||||||
|
|
||||||
constructor(commit: GitLogCommit, versioned: boolean = false, item?: QuickPickItem) {
|
|
||||||
const repoPath = commit.repoPath;
|
|
||||||
const uris = commit.fileStatuses.filter(_ => _.status !== 'D').map(_ => GitUri.fromFileStatus(_, repoPath));
|
|
||||||
super(uris, item || {
|
super(uris, item || {
|
||||||
label: `$(file-symlink-file) Open Changed Working Files`,
|
label: `$(file-symlink-file) Open Changed Revisions`,
|
||||||
description: ''
|
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}`
|
||||||
// detail: `Opens all of the changed file in the working tree`
|
// detail: `Opens all of the changed files in $(git-commit) ${commit.shortSha}`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +200,7 @@ export class CommitDetailsQuickPick {
|
|||||||
]));
|
]));
|
||||||
|
|
||||||
items.push(new OpenCommitFilesCommandQuickPickItem(commit));
|
items.push(new OpenCommitFilesCommandQuickPickItem(commit));
|
||||||
items.push(new OpenCommitWorkingTreeFilesCommandQuickPickItem(commit));
|
items.push(new OpenCommitFileRevisionsCommandQuickPickItem(commit));
|
||||||
|
|
||||||
if (goBackCommand) {
|
if (goBackCommand) {
|
||||||
items.splice(0, 0, goBackCommand);
|
items.splice(0, 0, goBackCommand);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { QuickPickItem, QuickPickOptions, Uri, window } from 'vscode';
|
|||||||
import { Commands, CopyMessageToClipboardCommandArgs, CopyShaToClipboardCommandArgs, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, ShowQuickCommitDetailsCommandArgs, ShowQuickCommitFileDetailsCommandArgs, ShowQuickFileHistoryCommandArgs } from '../commands';
|
import { Commands, CopyMessageToClipboardCommandArgs, CopyShaToClipboardCommandArgs, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, ShowQuickCommitDetailsCommandArgs, ShowQuickCommitFileDetailsCommandArgs, ShowQuickFileHistoryCommandArgs } from '../commands';
|
||||||
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, OpenFileCommandQuickPickItem } from './common';
|
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, KeyCommandQuickPickItem, OpenFileCommandQuickPickItem } from './common';
|
||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { GitBranch, GitLog, GitLogCommit, GitService, GitUri, RemoteResource } from '../gitService';
|
import { GitLog, GitLogCommit, GitService, GitUri, RemoteResource } from '../gitService';
|
||||||
import { Keyboard, KeyCommand, KeyNoopCommand } from '../keyboard';
|
import { Keyboard, KeyCommand, KeyNoopCommand } from '../keyboard';
|
||||||
import { OpenRemotesCommandQuickPickItem } from './remotes';
|
import { OpenRemotesCommandQuickPickItem } from './remotes';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
@@ -12,6 +12,17 @@ import * as path from 'path';
|
|||||||
|
|
||||||
export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPickItem {
|
export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPickItem {
|
||||||
|
|
||||||
|
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
||||||
|
const uri = Uri.file(path.resolve(commit.repoPath, commit.fileName));
|
||||||
|
super(uri, item || {
|
||||||
|
label: `$(file-symlink-file) Open File`,
|
||||||
|
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class OpenCommitFileRevisionCommandQuickPickItem extends OpenFileCommandQuickPickItem {
|
||||||
|
|
||||||
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
||||||
let description: string;
|
let description: string;
|
||||||
let uri: Uri;
|
let uri: Uri;
|
||||||
@@ -24,23 +35,12 @@ export class OpenCommitFileCommandQuickPickItem extends OpenFileCommandQuickPick
|
|||||||
description = `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}`;
|
description = `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)} in ${GlyphChars.Space}$(git-commit) ${commit.shortSha}`;
|
||||||
}
|
}
|
||||||
super(uri, item || {
|
super(uri, item || {
|
||||||
label: `$(file-symlink-file) Open File`,
|
label: `$(file-symlink-file) Open Revision`,
|
||||||
description: description
|
description: description
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class OpenCommitWorkingTreeFileCommandQuickPickItem extends OpenFileCommandQuickPickItem {
|
|
||||||
|
|
||||||
constructor(commit: GitLogCommit, item?: QuickPickItem) {
|
|
||||||
const uri = Uri.file(path.resolve(commit.repoPath, commit.fileName));
|
|
||||||
super(uri, item || {
|
|
||||||
label: `$(file-symlink-file) Open Working File`,
|
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} ${path.basename(commit.fileName)}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CommitFileDetailsQuickPick {
|
export class CommitFileDetailsQuickPick {
|
||||||
|
|
||||||
static async show(git: GitService, commit: GitLogCommit, uri: Uri, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem, fileLog?: GitLog): Promise<CommandQuickPickItem | undefined> {
|
static async show(git: GitService, commit: GitLogCommit, uri: Uri, goBackCommand?: CommandQuickPickItem, currentCommand?: CommandQuickPickItem, fileLog?: GitLog): Promise<CommandQuickPickItem | undefined> {
|
||||||
@@ -74,7 +74,7 @@ export class CommitFileDetailsQuickPick {
|
|||||||
|
|
||||||
if (commit.previousSha) {
|
if (commit.previousSha) {
|
||||||
items.push(new CommandQuickPickItem({
|
items.push(new CommandQuickPickItem({
|
||||||
label: `$(git-compare) Compare File with Previous`,
|
label: `$(git-compare) Compare File with Previous Revision`,
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.previousShortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}`
|
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.previousShortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(git-commit) ${commit.shortSha}`
|
||||||
}, Commands.DiffWithPrevious, [
|
}, Commands.DiffWithPrevious, [
|
||||||
commit.uri,
|
commit.uri,
|
||||||
@@ -87,7 +87,7 @@ export class CommitFileDetailsQuickPick {
|
|||||||
|
|
||||||
if (commit.workingFileName) {
|
if (commit.workingFileName) {
|
||||||
items.push(new CommandQuickPickItem({
|
items.push(new CommandQuickPickItem({
|
||||||
label: `$(git-compare) Compare File with Working Tree`,
|
label: `$(git-compare) Compare File with Working Revision`,
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(file-text) ${workingName}`
|
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} $(git-commit) ${commit.shortSha} ${GlyphChars.Space} $(git-compare) ${GlyphChars.Space} $(file-text) ${workingName}`
|
||||||
}, Commands.DiffWithWorking, [
|
}, Commands.DiffWithWorking, [
|
||||||
Uri.file(path.resolve(commit.repoPath, commit.workingFileName)),
|
Uri.file(path.resolve(commit.repoPath, commit.workingFileName)),
|
||||||
@@ -120,26 +120,26 @@ export class CommitFileDetailsQuickPick {
|
|||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push(new OpenCommitFileCommandQuickPickItem(commit));
|
|
||||||
if (commit.workingFileName && commit.status !== 'D') {
|
if (commit.workingFileName && commit.status !== 'D') {
|
||||||
items.push(new OpenCommitWorkingTreeFileCommandQuickPickItem(commit));
|
items.push(new OpenCommitFileCommandQuickPickItem(commit));
|
||||||
}
|
}
|
||||||
|
items.push(new OpenCommitFileRevisionCommandQuickPickItem(commit));
|
||||||
|
|
||||||
const remotes = Arrays.uniqueBy(await git.getRemotes(commit.repoPath), _ => _.url, _ => !!_.provider);
|
const remotes = Arrays.uniqueBy(await git.getRemotes(commit.repoPath), _ => _.url, _ => !!_.provider);
|
||||||
if (remotes.length) {
|
if (remotes.length) {
|
||||||
if (!stash) {
|
if (commit.workingFileName && commit.status !== 'D') {
|
||||||
|
const branch = await git.getBranch(commit.repoPath || git.repoPath);
|
||||||
items.push(new OpenRemotesCommandQuickPickItem(remotes, {
|
items.push(new OpenRemotesCommandQuickPickItem(remotes, {
|
||||||
type: 'file',
|
type: 'file',
|
||||||
fileName: commit.fileName,
|
fileName: commit.workingFileName,
|
||||||
commit
|
branch: branch!.name
|
||||||
} as RemoteResource, currentCommand));
|
} as RemoteResource, currentCommand));
|
||||||
}
|
}
|
||||||
if (commit.workingFileName && commit.status !== 'D') {
|
if (!stash) {
|
||||||
const branch = await git.getBranch(commit.repoPath || git.repoPath) as GitBranch;
|
|
||||||
items.push(new OpenRemotesCommandQuickPickItem(remotes, {
|
items.push(new OpenRemotesCommandQuickPickItem(remotes, {
|
||||||
type: 'working-file',
|
type: 'revision',
|
||||||
fileName: commit.workingFileName,
|
fileName: commit.fileName,
|
||||||
branch: branch.name
|
commit
|
||||||
} as RemoteResource, currentCommand));
|
} as RemoteResource, currentCommand));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ export class FileHistoryQuickPick {
|
|||||||
const remotes = Arrays.uniqueBy(await git.getRemotes(uri.repoPath!), _ => _.url, _ => !!_.provider);
|
const remotes = Arrays.uniqueBy(await git.getRemotes(uri.repoPath!), _ => _.url, _ => !!_.provider);
|
||||||
if (remotes.length) {
|
if (remotes.length) {
|
||||||
items.splice(index++, 0, new OpenRemotesCommandQuickPickItem(remotes, {
|
items.splice(index++, 0, new OpenRemotesCommandQuickPickItem(remotes, {
|
||||||
type: 'file',
|
type: 'revision',
|
||||||
branch: branch!.name,
|
branch: branch!.name,
|
||||||
fileName: uri.getRelativePath(),
|
fileName: uri.getRelativePath(),
|
||||||
sha: uri.sha
|
sha: uri.sha
|
||||||
|
|||||||
@@ -38,12 +38,24 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem {
|
|||||||
description = `$(git-branch) ${resource.branch}`;
|
description = `$(git-branch) ${resource.branch}`;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'branches':
|
||||||
|
description = `$(git-branch) Branches`;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'commit':
|
case 'commit':
|
||||||
const shortSha = resource.sha.substring(0, 8);
|
const shortSha = resource.sha.substring(0, 8);
|
||||||
description = `$(git-commit) ${shortSha}`;
|
description = `$(git-commit) ${shortSha}`;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'file':
|
case 'file':
|
||||||
|
description = `$(file-text) ${path.basename(resource.fileName)}`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'repo':
|
||||||
|
description = `$(repo) Repository`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'revision':
|
||||||
if (resource.commit !== undefined && resource.commit instanceof GitLogCommit) {
|
if (resource.commit !== undefined && resource.commit instanceof GitLogCommit) {
|
||||||
if (resource.commit.status === 'D') {
|
if (resource.commit.status === 'D') {
|
||||||
resource.sha = resource.commit.previousSha;
|
resource.sha = resource.commit.previousSha;
|
||||||
@@ -59,14 +71,6 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem {
|
|||||||
description = `$(file-text) ${path.basename(resource.fileName)}${shortFileSha ? ` in ${GlyphChars.Space}$(git-commit) ${shortFileSha}` : ''}`;
|
description = `$(file-text) ${path.basename(resource.fileName)}${shortFileSha ? ` in ${GlyphChars.Space}$(git-commit) ${shortFileSha}` : ''}`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'repo':
|
|
||||||
description = `$(repo) Repository`;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'working-file':
|
|
||||||
description = `$(file-text) ${path.basename(resource.fileName)}`;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const remote = remotes[0];
|
const remote = remotes[0];
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export class RepoStatusQuickPick {
|
|||||||
}
|
}
|
||||||
|
|
||||||
items.splice(0, 0, new CommandQuickPickItem({
|
items.splice(0, 0, new CommandQuickPickItem({
|
||||||
label: `$(repo) Show Stashed Changes`,
|
label: `$(inbox) Show Stashed Changes`,
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows stashed changes in the repository`
|
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} shows stashed changes in the repository`
|
||||||
}, Commands.ShowQuickStashList, [
|
}, Commands.ShowQuickStashList, [
|
||||||
new GitUri(Uri.file(status.repoPath), { fileName: '', repoPath: status.repoPath }),
|
new GitUri(Uri.file(status.repoPath), { fileName: '', repoPath: status.repoPath }),
|
||||||
|
|||||||
@@ -14,21 +14,10 @@ export class StashListQuickPick {
|
|||||||
|
|
||||||
if (mode === 'list') {
|
if (mode === 'list') {
|
||||||
items.splice(0, 0, new CommandQuickPickItem({
|
items.splice(0, 0, new CommandQuickPickItem({
|
||||||
label: `$(repo-push) Stash Unstaged Changes`,
|
label: `$(plus) Stash Changes`,
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} stashes only unstaged changes`
|
|
||||||
}, Commands.StashSave, [
|
|
||||||
{
|
|
||||||
unstagedOnly: true,
|
|
||||||
goBackCommand: currentCommand
|
|
||||||
} as StashSaveCommandArgs
|
|
||||||
]));
|
|
||||||
|
|
||||||
items.splice(0, 0, new CommandQuickPickItem({
|
|
||||||
label: `$(repo-force-push) Stash Changes`,
|
|
||||||
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} stashes all changes`
|
description: `${Strings.pad(GlyphChars.Dash, 2, 3)} stashes all changes`
|
||||||
}, Commands.StashSave, [
|
}, Commands.StashSave, [
|
||||||
{
|
{
|
||||||
unstagedOnly: false,
|
|
||||||
goBackCommand: currentCommand
|
goBackCommand: currentCommand
|
||||||
} as StashSaveCommandArgs
|
} as StashSaveCommandArgs
|
||||||
]));
|
]));
|
||||||
|
|||||||
@@ -102,7 +102,23 @@ export namespace Strings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function truncate(s: string, truncateTo?: number) {
|
export function truncate(s: string, truncateTo?: number) {
|
||||||
if (!s || truncateTo === undefined || getWidth(s) <= truncateTo) return s;
|
if (!s || truncateTo === undefined) return s;
|
||||||
return `${s.substring(0, truncateTo - 1)}\u2026`;
|
|
||||||
|
const len = getWidth(s);
|
||||||
|
if (len <= truncateTo) return s;
|
||||||
|
if (len === s.length) return `${s.substring(0, truncateTo - 1)}\u2026`;
|
||||||
|
|
||||||
|
// Skip ahead to start as far as we can by assuming all the double-width characters won't be truncated
|
||||||
|
let chars = Math.floor(truncateTo / (len / s.length));
|
||||||
|
let count = getWidth(s.substring(0, chars));
|
||||||
|
while (count < truncateTo) {
|
||||||
|
count += getWidth(s[chars++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count >= truncateTo) {
|
||||||
|
chars--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${s.substring(0, chars)}\u2026`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,22 +8,32 @@ import { GitBranch, GitService, GitUri } from '../gitService';
|
|||||||
|
|
||||||
export class BranchHistoryNode extends ExplorerNode {
|
export class BranchHistoryNode extends ExplorerNode {
|
||||||
|
|
||||||
readonly resourceType: ResourceType = 'branch-history';
|
readonly resourceType: ResourceType = 'gitlens:branch-history';
|
||||||
|
|
||||||
constructor(public readonly branch: GitBranch, uri: GitUri, context: ExtensionContext, git: GitService) {
|
constructor(public readonly branch: GitBranch, uri: GitUri, private readonly template: string, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
super(uri, context, git);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(): Promise<CommitNode[]> {
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
const log = await this.git.getLogForRepo(this.uri.repoPath!, this.branch.name);
|
const log = await this.git.getLogForRepo(this.uri.repoPath!, this.branch.name);
|
||||||
if (log === undefined) return [];
|
if (log === undefined) return [];
|
||||||
|
|
||||||
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.context, this.git))];
|
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.template, this.context, this.git))];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTreeItem(): TreeItem {
|
async getTreeItem(): Promise<TreeItem> {
|
||||||
const item = new TreeItem(`${this.branch.name}${this.branch.current ? ` ${GlyphChars.Dash} current` : ''}`, TreeItemCollapsibleState.Collapsed);
|
let name = this.branch.getName();
|
||||||
|
if (!this.branch.remote && this.branch.tracking !== undefined && this.git.config.gitExplorer.showTrackingBranch) {
|
||||||
|
name += ` ${GlyphChars.Space}${GlyphChars.ArrowLeftRight}${GlyphChars.Space} ${this.branch.tracking}`;
|
||||||
|
}
|
||||||
|
const item = new TreeItem(`${this.branch!.current ? `${GlyphChars.Check} ${GlyphChars.Space}` : ''}${name}`, TreeItemCollapsibleState.Collapsed);
|
||||||
item.contextValue = this.resourceType;
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
|
item.iconPath = {
|
||||||
|
dark: this.context.asAbsolutePath('images/dark/icon-branch.svg'),
|
||||||
|
light: this.context.asAbsolutePath('images/light/icon-branch.svg')
|
||||||
|
};
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,29 @@ import { GitService, GitUri } from '../gitService';
|
|||||||
|
|
||||||
export class BranchesNode extends ExplorerNode {
|
export class BranchesNode extends ExplorerNode {
|
||||||
|
|
||||||
readonly resourceType: ResourceType = 'branches';
|
readonly resourceType: ResourceType = 'gitlens:branches';
|
||||||
|
|
||||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
super(uri, context, git);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(): Promise<BranchHistoryNode[]> {
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
const branches = await this.git.getBranches(this.uri.repoPath!);
|
const branches = await this.git.getBranches(this.uri.repoPath!);
|
||||||
if (branches === undefined) return [];
|
if (branches === undefined) return [];
|
||||||
|
|
||||||
return [...Iterables.filterMap(branches.sort(_ => _.current ? 0 : 1), b => b.remote ? undefined : new BranchHistoryNode(b, this.uri, this.context, this.git))];
|
branches.sort((a, b) => (a.current ? -1 : 1) - (b.current ? -1 : 1) || a.name.localeCompare(b.name));
|
||||||
|
return [...Iterables.filterMap(branches, b => b.remote ? undefined : new BranchHistoryNode(b, this.uri, this.git.config.gitExplorer.commitFormat, this.context, this.git))];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTreeItem(): TreeItem {
|
getTreeItem(): TreeItem {
|
||||||
const item = new TreeItem(`Branches`, TreeItemCollapsibleState.Collapsed);
|
const item = new TreeItem(`Branches`, TreeItemCollapsibleState.Expanded);
|
||||||
item.contextValue = this.resourceType;
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
|
item.iconPath = {
|
||||||
|
dark: this.context.asAbsolutePath('images/dark/icon-branch.svg'),
|
||||||
|
light: this.context.asAbsolutePath('images/light/icon-branch.svg')
|
||||||
|
};
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import * as path from 'path';
|
|||||||
|
|
||||||
export class CommitFileNode extends ExplorerNode {
|
export class CommitFileNode extends ExplorerNode {
|
||||||
|
|
||||||
readonly resourceType: ResourceType = 'commit-file';
|
readonly resourceType: ResourceType = 'gitlens:commit-file';
|
||||||
|
|
||||||
constructor(public readonly status: IGitStatusFile, public commit: GitCommit, private template: string, context: ExtensionContext, git: GitService) {
|
constructor(public readonly status: IGitStatusFile, public commit: GitCommit, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
super(new GitUri(Uri.file(path.resolve(commit.repoPath, status.fileName)), { repoPath: commit.repoPath, fileName: status.fileName, sha: commit.sha }), context, git);
|
super(new GitUri(Uri.file(path.resolve(commit.repoPath, status.fileName)), { repoPath: commit.repoPath, fileName: status.fileName, sha: commit.sha }));
|
||||||
}
|
}
|
||||||
|
|
||||||
getChildren(): Promise<ExplorerNode[]> {
|
getChildren(): Promise<ExplorerNode[]> {
|
||||||
@@ -25,7 +25,7 @@ export class CommitFileNode extends ExplorerNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = new TreeItem(StatusFileFormatter.fromTemplate(this.template, this.status), TreeItemCollapsibleState.None);
|
const item = new TreeItem(StatusFileFormatter.fromTemplate(this.git.config.gitExplorer.commitFileFormat, this.status), TreeItemCollapsibleState.None);
|
||||||
item.contextValue = this.resourceType;
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
const icon = getGitStatusIcon(this.status.status);
|
const icon = getGitStatusIcon(this.status.status);
|
||||||
@@ -40,8 +40,18 @@ export class CommitFileNode extends ExplorerNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCommand(): Command | undefined {
|
getCommand(): Command | undefined {
|
||||||
|
let allowMissingPrevious = false;
|
||||||
|
let prefix = undefined;
|
||||||
|
if (this.status.status === 'A') {
|
||||||
|
allowMissingPrevious = true;
|
||||||
|
prefix = 'added in ';
|
||||||
|
}
|
||||||
|
else if (this.status.status === 'D') {
|
||||||
|
prefix = 'deleted in ';
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: 'Compare File with Previous',
|
title: 'Compare File with Previous Revision',
|
||||||
command: Commands.DiffWithPrevious,
|
command: Commands.DiffWithPrevious,
|
||||||
arguments: [
|
arguments: [
|
||||||
GitUri.fromFileStatus(this.status, this.commit.repoPath),
|
GitUri.fromFileStatus(this.status, this.commit.repoPath),
|
||||||
@@ -51,7 +61,9 @@ export class CommitFileNode extends ExplorerNode {
|
|||||||
showOptions: {
|
showOptions: {
|
||||||
preserveFocus: true,
|
preserveFocus: true,
|
||||||
preview: true
|
preview: true
|
||||||
}
|
},
|
||||||
|
allowMissingPrevious: allowMissingPrevious,
|
||||||
|
rightTitlePrefix: prefix
|
||||||
} as DiffWithPreviousCommandArgs
|
} as DiffWithPreviousCommandArgs
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,38 +1,87 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
import { Command, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||||
|
import { Commands, DiffWithPreviousCommandArgs } from '../commands';
|
||||||
import { CommitFileNode } from './commitFileNode';
|
import { CommitFileNode } from './commitFileNode';
|
||||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||||
import { CommitFormatter, GitCommit, GitService, GitUri } from '../gitService';
|
import { CommitFormatter, getGitStatusIcon, GitLogCommit, GitService, GitUri } from '../gitService';
|
||||||
|
import * as path from 'path';
|
||||||
|
|
||||||
export class CommitNode extends ExplorerNode {
|
export class CommitNode extends ExplorerNode {
|
||||||
|
|
||||||
readonly resourceType: ResourceType = 'commit';
|
readonly resourceType: ResourceType = 'gitlens:commit';
|
||||||
|
|
||||||
constructor(public readonly commit: GitCommit, context: ExtensionContext, git: GitService) {
|
constructor(public readonly commit: GitLogCommit, private readonly template: string, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
super(new GitUri(commit.uri, commit), context, git);
|
super(new GitUri(commit.uri, commit));
|
||||||
this.commit = commit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(): Promise<ExplorerNode[]> {
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
|
if (this.commit.type === 'file') Promise.resolve([]);
|
||||||
|
|
||||||
const log = await this.git.getLogForRepo(this.commit.repoPath, this.commit.sha, 1);
|
const log = await this.git.getLogForRepo(this.commit.repoPath, this.commit.sha, 1);
|
||||||
if (log === undefined) return [];
|
if (log === undefined) return [];
|
||||||
|
|
||||||
const commit = Iterables.first(log.commits.values());
|
const commit = Iterables.first(log.commits.values());
|
||||||
if (commit === undefined) return [];
|
if (commit === undefined) return [];
|
||||||
|
|
||||||
return [...Iterables.map(commit.fileStatuses, s => new CommitFileNode(s, commit, this.git.config.gitExplorer.commitFileFormat, this.context, this.git))];
|
return [...Iterables.map(commit.fileStatuses, s => new CommitFileNode(s, commit, this.context, this.git))];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTreeItem(): TreeItem {
|
getTreeItem(): TreeItem {
|
||||||
const label = CommitFormatter.fromTemplate(this.git.config.gitExplorer.commitFormat, this.commit, this.git.config.defaultDateFormat);
|
const item = new TreeItem(CommitFormatter.fromTemplate(this.template, this.commit, this.git.config.defaultDateFormat));
|
||||||
|
if (this.commit.type === 'file') {
|
||||||
|
item.collapsibleState = TreeItemCollapsibleState.None;
|
||||||
|
item.command = this.getCommand();
|
||||||
|
const resourceType: ResourceType = 'gitlens:commit-file';
|
||||||
|
item.contextValue = resourceType;
|
||||||
|
|
||||||
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
|
const icon = getGitStatusIcon(this.commit.status!);
|
||||||
|
item.iconPath = {
|
||||||
|
dark: this.context.asAbsolutePath(path.join('images', 'dark', icon)),
|
||||||
|
light: this.context.asAbsolutePath(path.join('images', 'light', icon))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.collapsibleState = TreeItemCollapsibleState.Collapsed;
|
||||||
item.contextValue = this.resourceType;
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
item.iconPath = {
|
item.iconPath = {
|
||||||
dark: this.context.asAbsolutePath('images/dark/icon-commit.svg'),
|
dark: this.context.asAbsolutePath('images/dark/icon-commit.svg'),
|
||||||
light: this.context.asAbsolutePath('images/light/icon-commit.svg')
|
light: this.context.asAbsolutePath('images/light/icon-commit.svg')
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCommand(): Command | undefined {
|
||||||
|
let allowMissingPrevious = false;
|
||||||
|
let prefix = undefined;
|
||||||
|
const status = this.commit.fileStatuses[0];
|
||||||
|
if (status.status === 'A') {
|
||||||
|
allowMissingPrevious = true;
|
||||||
|
prefix = 'added in ';
|
||||||
|
}
|
||||||
|
else if (status.status === 'D') {
|
||||||
|
prefix = 'deleted in ';
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: 'Compare File with Previous Revision',
|
||||||
|
command: Commands.DiffWithPrevious,
|
||||||
|
arguments: [
|
||||||
|
new GitUri(this.uri, this.commit),
|
||||||
|
{
|
||||||
|
commit: this.commit,
|
||||||
|
line: 0,
|
||||||
|
showOptions: {
|
||||||
|
preserveFocus: true,
|
||||||
|
preview: true
|
||||||
|
},
|
||||||
|
allowMissingPrevious: allowMissingPrevious,
|
||||||
|
rightTitlePrefix: prefix
|
||||||
|
} as DiffWithPreviousCommandArgs
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,29 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { Command, Event, ExtensionContext, TreeItem } from 'vscode';
|
import { Command, Event, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitUri } from '../gitService';
|
||||||
|
|
||||||
export declare type ResourceType = 'status' | 'branches' | 'repository' | 'branch-history' | 'file-history' | 'stash-history' | 'commit' | 'stash-commit' | 'commit-file';
|
export declare type ResourceType =
|
||||||
|
'gitlens:branches' |
|
||||||
|
'gitlens:branch-history' |
|
||||||
|
'gitlens:commit' |
|
||||||
|
'gitlens:commit-file' |
|
||||||
|
'gitlens:file-history' |
|
||||||
|
'gitlens:history' |
|
||||||
|
'gitlens:message' |
|
||||||
|
'gitlens:remote' |
|
||||||
|
'gitlens:remotes' |
|
||||||
|
'gitlens:repository' |
|
||||||
|
'gitlens:stash' |
|
||||||
|
'gitlens:stash-file' |
|
||||||
|
'gitlens:stashes' |
|
||||||
|
'gitlens:status' |
|
||||||
|
'gitlens:status-upstream';
|
||||||
|
|
||||||
export abstract class ExplorerNode {
|
export abstract class ExplorerNode {
|
||||||
|
|
||||||
abstract readonly resourceType: ResourceType;
|
abstract readonly resourceType: ResourceType;
|
||||||
|
|
||||||
constructor(public readonly uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { }
|
constructor(public readonly uri: GitUri) { }
|
||||||
|
|
||||||
abstract getChildren(): ExplorerNode[] | Promise<ExplorerNode[]>;
|
abstract getChildren(): ExplorerNode[] | Promise<ExplorerNode[]>;
|
||||||
abstract getTreeItem(): TreeItem | Promise<TreeItem>;
|
abstract getTreeItem(): TreeItem | Promise<TreeItem>;
|
||||||
@@ -21,3 +36,22 @@ export abstract class ExplorerNode {
|
|||||||
|
|
||||||
refresh?(): void;
|
refresh?(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class MessageNode extends ExplorerNode {
|
||||||
|
|
||||||
|
readonly resourceType: ResourceType = 'gitlens:message';
|
||||||
|
|
||||||
|
constructor(private message: string) {
|
||||||
|
super(new GitUri());
|
||||||
|
}
|
||||||
|
|
||||||
|
getChildren(): ExplorerNode[] | Promise<ExplorerNode[]> {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getTreeItem(): TreeItem | Promise<TreeItem> {
|
||||||
|
const item = new TreeItem(this.message, TreeItemCollapsibleState.None);
|
||||||
|
item.contextValue = this.resourceType;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,12 @@ export * from './branchHistoryNode';
|
|||||||
export * from './commitFileNode';
|
export * from './commitFileNode';
|
||||||
export * from './commitNode';
|
export * from './commitNode';
|
||||||
export * from './fileHistoryNode';
|
export * from './fileHistoryNode';
|
||||||
|
export * from './historyNode';
|
||||||
|
export * from './remoteNode';
|
||||||
|
export * from './remotesNode';
|
||||||
export * from './repositoryNode';
|
export * from './repositoryNode';
|
||||||
export * from './stashCommitNode';
|
export * from './stashFileNode';
|
||||||
export * from './stashNode';
|
export * from './stashNode';
|
||||||
|
export * from './stashesNode';
|
||||||
export * from './statusNode';
|
export * from './statusNode';
|
||||||
|
export * from './statusUpstreamNode';
|
||||||
@@ -2,28 +2,33 @@
|
|||||||
import { Iterables } from '../system';
|
import { Iterables } from '../system';
|
||||||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||||
import { CommitNode } from './commitNode';
|
import { CommitNode } from './commitNode';
|
||||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
import { ExplorerNode, MessageNode, ResourceType } from './explorerNode';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
|
|
||||||
export class FileHistoryNode extends ExplorerNode {
|
export class FileHistoryNode extends ExplorerNode {
|
||||||
|
|
||||||
static readonly rootType: ResourceType = 'file-history';
|
readonly resourceType: ResourceType = 'gitlens:file-history';
|
||||||
readonly resourceType: ResourceType = 'file-history';
|
|
||||||
|
|
||||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
super(uri, context, git);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(): Promise<CommitNode[]> {
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
const log = await this.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, this.uri.sha);
|
const log = await this.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, this.uri.sha);
|
||||||
if (log === undefined) return [];
|
if (log === undefined) return [new MessageNode('No file history')];
|
||||||
|
|
||||||
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.context, this.git))];
|
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.git.config.gitExplorer.commitFormat, this.context, this.git))];
|
||||||
}
|
}
|
||||||
|
|
||||||
getTreeItem(): TreeItem {
|
getTreeItem(): TreeItem {
|
||||||
const item = new TreeItem(`History of ${this.uri.getFormattedPath()}`, TreeItemCollapsibleState.Expanded);
|
const item = new TreeItem(`${this.uri.getFormattedPath()}`, TreeItemCollapsibleState.Expanded);
|
||||||
item.contextValue = this.resourceType;
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
|
item.iconPath = {
|
||||||
|
dark: this.context.asAbsolutePath('images/dark/icon-history.svg'),
|
||||||
|
light: this.context.asAbsolutePath('images/light/icon-history.svg')
|
||||||
|
};
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,73 +1,199 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
// import { Functions } from '../system';
|
import { Functions, Objects } from '../system';
|
||||||
import { commands, Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri } from 'vscode';
|
import { commands, Event, EventEmitter, ExtensionContext, TextDocumentShowOptions, TextEditor, TreeDataProvider, TreeItem, Uri, window, workspace } from 'vscode';
|
||||||
|
import { Commands, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, openEditor, OpenFileInRemoteCommandArgs } from '../commands';
|
||||||
import { UriComparer } from '../comparers';
|
import { UriComparer } from '../comparers';
|
||||||
import { ExplorerNode, FileHistoryNode, RepositoryNode, ResourceType, StashNode } from './explorerNodes';
|
import { ExtensionKey, IConfig } from '../configuration';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { CommandContext, setCommandContext } from '../constants';
|
||||||
|
import { CommitFileNode, CommitNode, ExplorerNode, HistoryNode, MessageNode, RepositoryNode, StashNode } from './explorerNodes';
|
||||||
|
import { GitService, GitUri, RepoChangedReasons } from '../gitService';
|
||||||
|
|
||||||
export * from './explorerNodes';
|
export * from './explorerNodes';
|
||||||
|
|
||||||
|
export type GitExplorerView =
|
||||||
|
'history' |
|
||||||
|
'repository';
|
||||||
|
export const GitExplorerView = {
|
||||||
|
History: 'history' as GitExplorerView,
|
||||||
|
Repository: 'repository' as GitExplorerView
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface OpenFileRevisionCommandArgs {
|
||||||
|
uri?: Uri;
|
||||||
|
showOptions?: TextDocumentShowOptions;
|
||||||
|
}
|
||||||
|
|
||||||
export class GitExplorer implements TreeDataProvider<ExplorerNode> {
|
export class GitExplorer implements TreeDataProvider<ExplorerNode> {
|
||||||
|
|
||||||
// private _refreshDebounced: () => void;
|
private _config: IConfig;
|
||||||
|
private _root?: ExplorerNode;
|
||||||
|
private _view: GitExplorerView = GitExplorerView.Repository;
|
||||||
|
|
||||||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
|
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
|
||||||
public get onDidChangeTreeData(): Event<ExplorerNode> {
|
public get onDidChangeTreeData(): Event<ExplorerNode> {
|
||||||
return this._onDidChangeTreeData.event;
|
return this._onDidChangeTreeData.event;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _roots: ExplorerNode[] = [];
|
constructor(private readonly context: ExtensionContext, private readonly git: GitService) {
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.switchToHistoryView', () => this.switchTo(GitExplorerView.History), this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.switchToRepositoryView', () => this.switchTo(GitExplorerView.Repository), this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.refresh', this.refresh, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openChanges', this.openChanges, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openChangesWithWorking', this.openChangesWithWorking, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openFile', this.openFile, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openFileRevision', this.openFileRevision, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openFileRevisionInRemote', this.openFileRevisionInRemote, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openChangedFiles', this.openChangedFiles, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.openChangedFileRevisions', this.openChangedFileRevisions, this);
|
||||||
|
commands.registerCommand('gitlens.gitExplorer.applyChanges', this.applyChanges, this);
|
||||||
|
|
||||||
constructor(private context: ExtensionContext, private git: GitService) {
|
context.subscriptions.push(this.git.onDidChangeRepo(this.onRepoChanged, this));
|
||||||
commands.registerCommand('gitlens.gitExplorer.refresh', () => this.refresh());
|
|
||||||
|
|
||||||
// this._refreshDebounced = Functions.debounce(this.refresh.bind(this), 250);
|
const fn = Functions.debounce(this.onActiveEditorChanged, 500);
|
||||||
|
context.subscriptions.push(window.onDidChangeActiveTextEditor(fn, this));
|
||||||
|
context.subscriptions.push(workspace.onDidChangeConfiguration(this.onConfigurationChanged, this));
|
||||||
|
|
||||||
// const editor = window.activeTextEditor;
|
this.onConfigurationChanged();
|
||||||
|
|
||||||
// const uri = (editor !== undefined && editor.document !== undefined)
|
this._view = this._config.gitExplorer.view;
|
||||||
// ? new GitUri(editor.document.uri, { repoPath: git.repoPath, fileName: editor.document.uri.fsPath })
|
setCommandContext(CommandContext.GitExplorerView, this._view);
|
||||||
// : new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
|
this._root = this.getRootNode();
|
||||||
|
|
||||||
const uri = new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
|
|
||||||
this._roots.push(new RepositoryNode(uri, context, git));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
|
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
|
||||||
// if (node.onDidChangeTreeData !== undefined) {
|
|
||||||
// node.onDidChangeTreeData(() => setTimeout(this._refreshDebounced, 1));
|
|
||||||
// }
|
|
||||||
return node.getTreeItem();
|
return node.getTreeItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
|
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
|
||||||
if (this._roots.length === 0) return [];
|
if (this._root === undefined) {
|
||||||
if (node === undefined) return this._roots;
|
if (this._view === GitExplorerView.History) return [new MessageNode('No active file; no history to show')];
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node === undefined) return this._root.getChildren();
|
||||||
return node.getChildren();
|
return node.getChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
addHistory(uri: GitUri) {
|
private getRootNode(editor?: TextEditor): ExplorerNode | undefined {
|
||||||
this._add(uri, FileHistoryNode);
|
const uri = new GitUri(Uri.file(this.git.repoPath), { repoPath: this.git.repoPath, fileName: this.git.repoPath });
|
||||||
|
|
||||||
|
switch (this._view) {
|
||||||
|
case GitExplorerView.History: return this.getHistoryNode(editor || window.activeTextEditor);
|
||||||
|
case GitExplorerView.Repository: return new RepositoryNode(uri, this.context, this.git);
|
||||||
}
|
}
|
||||||
|
|
||||||
addStash(uri: GitUri) {
|
return undefined;
|
||||||
this._add(uri, StashNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _add<T extends ExplorerNode>(uri: GitUri, type: { new (uri: GitUri, context: ExtensionContext, git: GitService): T, rootType: ResourceType }) {
|
private getHistoryNode(editor: TextEditor | undefined): ExplorerNode | undefined {
|
||||||
if (!this._roots.some(_ => _.resourceType === type.rootType && UriComparer.equals(uri, _.uri))) {
|
if (window.visibleTextEditors.length === 0) return undefined;
|
||||||
this._roots.push(new type(uri, this.context, this.git));
|
if (editor === undefined) return this._root;
|
||||||
|
|
||||||
|
const uri = this.git.getGitUriForFile(editor.document.uri) || new GitUri(editor.document.uri, { repoPath: this.git.repoPath, fileName: editor.document.uri.fsPath });
|
||||||
|
if (UriComparer.equals(uri, this._root && this._root.uri)) return this._root;
|
||||||
|
|
||||||
|
return new HistoryNode(uri, this.context, this.git);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onActiveEditorChanged(editor: TextEditor | undefined) {
|
||||||
|
if (this._view !== GitExplorerView.History) return;
|
||||||
|
|
||||||
|
const root = this.getRootNode(editor);
|
||||||
|
if (root === this._root) return;
|
||||||
|
|
||||||
|
this._root = root;
|
||||||
|
this.refresh(undefined, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onConfigurationChanged() {
|
||||||
|
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||||
|
|
||||||
|
if (!Objects.areEquivalent(cfg.gitExplorer, this._config && this._config.gitExplorer)) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._root = this.getRootNode(window.activeTextEditor);
|
||||||
|
this.refresh();
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._config = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private onRepoChanged(reasons: RepoChangedReasons[]) {
|
||||||
|
if (this._view !== GitExplorerView.Repository) return;
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
refresh(node?: ExplorerNode, root?: ExplorerNode) {
|
||||||
this._roots = [];
|
if (root === undefined && this._view === GitExplorerView.History) {
|
||||||
|
this._root = this.getRootNode(window.activeTextEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._onDidChangeTreeData.fire(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
switchTo(view: GitExplorerView) {
|
||||||
|
if (this._view === view) return;
|
||||||
|
|
||||||
|
this._view = view;
|
||||||
|
setCommandContext(CommandContext.GitExplorerView, this._view);
|
||||||
|
|
||||||
|
this._root = this.getRootNode(window.activeTextEditor);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
private async applyChanges(node: CommitNode | StashNode) {
|
||||||
this._onDidChangeTreeData.fire();
|
await this.git.checkoutFile(node.uri);
|
||||||
|
return this.openFile(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private openChanges(node: CommitNode | StashNode) {
|
||||||
|
const command = node.getCommand();
|
||||||
|
if (command === undefined || command.arguments === undefined) return;
|
||||||
|
|
||||||
|
const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs];
|
||||||
|
args.showOptions!.preview = false;
|
||||||
|
return commands.executeCommand(command.command, uri, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private openChangesWithWorking(node: CommitNode | StashNode) {
|
||||||
|
const args: DiffWithWorkingCommandArgs = {
|
||||||
|
commit: node.commit,
|
||||||
|
showOptions: {
|
||||||
|
preserveFocus: true,
|
||||||
|
preview: false
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return commands.executeCommand(Commands.DiffWithWorking, new GitUri(node.commit.uri, node.commit), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private openFile(node: CommitNode | StashNode) {
|
||||||
|
return openEditor(node.uri, { preserveFocus: true, preview: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
private openFileRevision(node: CommitNode | StashNode | CommitFileNode, options: OpenFileRevisionCommandArgs = { showOptions: { preserveFocus: true, preview: false } }) {
|
||||||
|
return openEditor(options.uri || GitService.toGitContentUri(node.uri), options.showOptions || { preserveFocus: true, preview: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async openChangedFiles(node: CommitNode | StashNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) {
|
||||||
|
const repoPath = node.commit.repoPath;
|
||||||
|
const uris = node.commit.fileStatuses.filter(s => s.status !== 'D').map(s => GitUri.fromFileStatus(s, repoPath));
|
||||||
|
for (const uri of uris) {
|
||||||
|
await openEditor(uri, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async openChangedFileRevisions(node: CommitNode | StashNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) {
|
||||||
|
const uris = node.commit.fileStatuses
|
||||||
|
.filter(s => s.status !== 'D')
|
||||||
|
.map(s => GitService.toGitContentUri(node.commit.sha, node.commit.shortSha, s.fileName, node.commit.repoPath, s.originalFileName));
|
||||||
|
for (const uri of uris) {
|
||||||
|
await openEditor(uri, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async openFileRevisionInRemote(node: CommitNode | StashNode) {
|
||||||
|
return commands.executeCommand(Commands.OpenFileInRemote, new GitUri(node.commit.uri, node.commit), { range: false } as OpenFileInRemoteCommandArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
30
src/views/historyNode.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
'use strict';
|
||||||
|
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||||
|
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||||
|
import { FileHistoryNode } from './fileHistoryNode';
|
||||||
|
import { GitService, GitUri } from '../gitService';
|
||||||
|
|
||||||
|
export class HistoryNode extends ExplorerNode {
|
||||||
|
|
||||||
|
readonly resourceType: ResourceType = 'gitlens:history';
|
||||||
|
|
||||||
|
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
|
super(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
|
return [new FileHistoryNode(this.uri, this.context, this.git)];
|
||||||
|
}
|
||||||
|
|
||||||
|
getTreeItem(): TreeItem {
|
||||||
|
const item = new TreeItem(`${this.uri.getFormattedPath()}`, TreeItemCollapsibleState.Expanded);
|
||||||
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
|
item.iconPath = {
|
||||||
|
dark: this.context.asAbsolutePath('images/dark/icon-history.svg'),
|
||||||
|
light: this.context.asAbsolutePath('images/light/icon-history.svg')
|
||||||
|
};
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/views/remoteNode.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
'use strict';
|
||||||
|
import { Iterables } from '../system';
|
||||||
|
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||||
|
import { BranchHistoryNode } from './branchHistoryNode';
|
||||||
|
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||||
|
import { GitRemote, GitService, GitUri } from '../gitService';
|
||||||
|
|
||||||
|
export class RemoteNode extends ExplorerNode {
|
||||||
|
|
||||||
|
readonly resourceType: ResourceType = 'gitlens:remote';
|
||||||
|
|
||||||
|
constructor(public readonly remote: GitRemote, uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
|
super(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
|
const branches = await this.git.getBranches(this.uri.repoPath!);
|
||||||
|
if (branches === undefined) return [];
|
||||||
|
|
||||||
|
branches.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
return [...Iterables.filterMap(branches, b => !b.remote || !b.name.startsWith(this.remote.name) ? undefined : new BranchHistoryNode(b, this.uri, this.git.config.gitExplorer.commitFormat, this.context, this.git))];
|
||||||
|
}
|
||||||
|
|
||||||
|
getTreeItem(): TreeItem {
|
||||||
|
const item = new TreeItem(this.remote.name, TreeItemCollapsibleState.Collapsed);
|
||||||
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
|
// item.iconPath = {
|
||||||
|
// dark: this.context.asAbsolutePath('images/dark/icon-remote.svg'),
|
||||||
|
// light: this.context.asAbsolutePath('images/light/icon-remote.svg')
|
||||||
|
// };
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/views/remotesNode.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
'use strict';
|
||||||
|
import { Arrays, Iterables } from '../system';
|
||||||
|
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
||||||
|
import { ExplorerNode, MessageNode, ResourceType } from './explorerNode';
|
||||||
|
import { GitService, GitUri } from '../gitService';
|
||||||
|
import { RemoteNode } from './remoteNode';
|
||||||
|
|
||||||
|
export class RemotesNode extends ExplorerNode {
|
||||||
|
|
||||||
|
readonly resourceType: ResourceType = 'gitlens:remotes';
|
||||||
|
|
||||||
|
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
|
super(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
|
const remotes = Arrays.uniqueBy(await this.git.getRemotes(this.uri.repoPath!), r => r.url, r => !!r.provider);
|
||||||
|
if (remotes === undefined || remotes.length === 0) return [new MessageNode('No remotes configured')];
|
||||||
|
|
||||||
|
remotes.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
return [...Iterables.map(remotes, r => new RemoteNode(r, this.uri, this.context, this.git))];
|
||||||
|
}
|
||||||
|
|
||||||
|
getTreeItem(): TreeItem {
|
||||||
|
const item = new TreeItem(`Remotes`, TreeItemCollapsibleState.Collapsed);
|
||||||
|
item.contextValue = this.resourceType;
|
||||||
|
|
||||||
|
item.iconPath = {
|
||||||
|
dark: this.context.asAbsolutePath('images/dark/icon-remote.svg'),
|
||||||
|
light: this.context.asAbsolutePath('images/light/icon-remote.svg')
|
||||||
|
};
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,21 +4,24 @@ import { BranchesNode } from './branchesNode';
|
|||||||
import { GlyphChars } from '../constants';
|
import { GlyphChars } from '../constants';
|
||||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
import { ExplorerNode, ResourceType } from './explorerNode';
|
||||||
import { GitService, GitUri } from '../gitService';
|
import { GitService, GitUri } from '../gitService';
|
||||||
// import { StatusNode } from './statusNode';
|
import { RemotesNode } from './remotesNode';
|
||||||
|
import { StatusNode } from './statusNode';
|
||||||
|
import { StashesNode } from './stashesNode';
|
||||||
|
|
||||||
export class RepositoryNode extends ExplorerNode {
|
export class RepositoryNode extends ExplorerNode {
|
||||||
|
|
||||||
static readonly rootType: ResourceType = 'repository';
|
readonly resourceType: ResourceType = 'gitlens:repository';
|
||||||
readonly resourceType: ResourceType = 'repository';
|
|
||||||
|
|
||||||
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
|
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) {
|
||||||
super(uri, context, git);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getChildren(): Promise<ExplorerNode[]> {
|
async getChildren(): Promise<ExplorerNode[]> {
|
||||||
return [
|
return [
|
||||||
// new StatusNode(this.uri, this.context, this.git),
|
new StatusNode(this.uri, this.context, this.git),
|
||||||
new BranchesNode(this.uri, this.context, this.git)
|
new BranchesNode(this.uri, this.context, this.git),
|
||||||
|
new RemotesNode(this.uri, this.context, this.git),
|
||||||
|
new StashesNode(this.uri, this.context, this.git)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
import { Event, EventEmitter, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
|
|
||||||
import { CommitFileNode } from './commitFileNode';
|
|
||||||
import { ExplorerNode, ResourceType } from './explorerNode';
|
|
||||||
import { CommitFormatter, GitService, GitStashCommit, GitUri } from '../gitService';
|
|
||||||
|
|
||||||
export class StashCommitNode extends ExplorerNode {
|
|
||||||
|
|
||||||
readonly resourceType: ResourceType = 'stash-commit';
|
|
||||||
|
|
||||||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
|
|
||||||
public get onDidChangeTreeData(): Event<ExplorerNode> {
|
|
||||||
return this._onDidChangeTreeData.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(public readonly commit: GitStashCommit, context: ExtensionContext, git: GitService) {
|
|
||||||
super(new GitUri(commit.uri, commit), context, git);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getChildren(): Promise<CommitFileNode[]> {
|
|
||||||
return Promise.resolve((this.commit as GitStashCommit).fileStatuses.map(_ => new CommitFileNode(_, this.commit, this.git.config.stashExplorer.stashFileFormat, this.context, this.git)));
|
|
||||||
}
|
|
||||||
|
|
||||||
getTreeItem(): TreeItem {
|
|
||||||
const label = CommitFormatter.fromTemplate(this.git.config.stashExplorer.stashFormat, this.commit, this.git.config.defaultDateFormat);
|
|
||||||
|
|
||||||
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
|
|
||||||
item.contextValue = this.resourceType;
|
|
||||||
// item.command = {
|
|
||||||
// title: 'Show Stash Details',
|
|
||||||
// command: Commands.ShowQuickCommitDetails,
|
|
||||||
// arguments: [
|
|
||||||
// new GitUri(commit.uri, commit),
|
|
||||||
// {
|
|
||||||
// commit: this.commit,
|
|
||||||
// sha: this.commit.sha
|
|
||||||
// } as ShowQuickCommitDetailsCommandArgs
|
|
||||||
// ]
|
|
||||||
// };
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
this._onDidChangeTreeData.fire();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
// import { Functions } from '../system';
|
|
||||||
import { commands, Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri } from 'vscode';
|
|
||||||
import { Commands, DiffWithPreviousCommandArgs, openEditor } from '../commands';
|
|
||||||
import { ExplorerNode, StashCommitNode, StashNode } from './explorerNodes';
|
|
||||||
import { GitService, GitUri } from '../gitService';
|
|
||||||
|
|
||||||
export * from './explorerNodes';
|
|
||||||
|
|
||||||
export class StashExplorer implements TreeDataProvider<ExplorerNode> {
|
|
||||||
|
|
||||||
private _node: ExplorerNode;
|
|
||||||
// private _refreshDebounced: () => void;
|
|
||||||
|
|
||||||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
|
|
||||||
public get onDidChangeTreeData(): Event<ExplorerNode> {
|
|
||||||
return this._onDidChangeTreeData.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(private context: ExtensionContext, private git: GitService) {
|
|
||||||
commands.registerCommand('gitlens.stashExplorer.refresh', this.refresh, this);
|
|
||||||
commands.registerCommand('gitlens.stashExplorer.openChanges', this.openChanges, this);
|
|
||||||
commands.registerCommand('gitlens.stashExplorer.openFile', this.openFile, this);
|
|
||||||
commands.registerCommand('gitlens.stashExplorer.openStashedFile', this.openStashedFile, this);
|
|
||||||
commands.registerCommand('gitlens.stashExplorer.openFileInRemote', this.openFileInRemote, this);
|
|
||||||
|
|
||||||
context.subscriptions.push(this.git.onDidChangeRepo(reasons => {
|
|
||||||
if (!reasons.includes('stash')) return;
|
|
||||||
|
|
||||||
this.refresh();
|
|
||||||
}, this));
|
|
||||||
|
|
||||||
// this._refreshDebounced = Functions.debounce(this.refresh.bind(this), 250);
|
|
||||||
|
|
||||||
// const editor = window.activeTextEditor;
|
|
||||||
|
|
||||||
// const uri = (editor !== undefined && editor.document !== undefined)
|
|
||||||
// ? new GitUri(editor.document.uri, { repoPath: git.repoPath, fileName: editor.document.uri.fsPath })
|
|
||||||
// : new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
|
|
||||||
|
|
||||||
const uri = new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
|
|
||||||
this._node = new StashNode(uri, this.context, this.git);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
|
|
||||||
// if (node.onDidChangeTreeData !== undefined) {
|
|
||||||
// node.onDidChangeTreeData(() => setTimeout(this._refreshDebounced, 1));
|
|
||||||
// }
|
|
||||||
return node.getTreeItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
|
|
||||||
if (node === undefined) return this._node.getChildren();
|
|
||||||
return node.getChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
// update(uri: GitUri) {
|
|
||||||
// this._node = new StashNode(uri, this.context, this.git);
|
|
||||||
// this.refresh();
|
|
||||||
// }
|
|
||||||
|
|
||||||
refresh() {
|
|
||||||
this._onDidChangeTreeData.fire();
|
|
||||||
}
|
|
||||||
|
|
||||||
private openChanges(node: StashCommitNode) {
|
|
||||||
const command = node.getCommand();
|
|
||||||
if (command === undefined || command.arguments === undefined) return;
|
|
||||||
|
|
||||||
const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs];
|
|
||||||
args.showOptions!.preview = false;
|
|
||||||
return commands.executeCommand(command.command, uri, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private openFile(node: StashCommitNode) {
|
|
||||||
return openEditor(node.uri, { preserveFocus: true, preview: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
private openStashedFile(node: StashCommitNode) {
|
|
||||||
return openEditor(GitService.toGitContentUri(node.uri), { preserveFocus: true, preview: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
private openFileInRemote(node: StashCommitNode) {
|
|
||||||
return commands.executeCommand(Commands.OpenFileInRemote, node.commit.previousUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||