Kaynağa Gözat

Adds setting to control rich integrations - #1208

main
Eric Amodio 4 yıl önce
ebeveyn
işleme
bf9208ba2a
12 değiştirilmiş dosya ile 150 ekleme ve 75 silme
  1. +1
    -0
      CHANGELOG.md
  2. +17
    -26
      README.md
  3. +21
    -17
      package.json
  4. +13
    -10
      src/avatars.ts
  5. +80
    -9
      src/commands/remoteProviders.ts
  6. +3
    -1
      src/config.ts
  7. +1
    -1
      src/git/formatters/commitFormatter.ts
  8. +2
    -1
      src/git/gitService.ts
  9. +6
    -9
      src/git/models/repository.ts
  10. +2
    -0
      src/git/remotes/provider.ts
  11. +3
    -1
      src/quickpicks/repositoryPicker.ts
  12. +1
    -0
      src/views/remotesView.ts

+ 1
- 0
CHANGELOG.md Dosyayı Görüntüle

@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Adds preview extensibility APIs
- Adds a preview _action runner_ extensibility point to provide a runner (handler) for a new _createPullRequest_ and _openPullRequest_ actions — see `gitlens.d.ts` for API definitions
- Preview APIs are only available in the Insiders edition
- Adds a `gitlens.integrations.enabled` setting to specify whether to enable rich integrations with any supported remote services — see [#1208](https://github.com/eamodio/vscode-gitlens/issues/1208)
- Adds a `gitlens.showWelcomeOnInstall` setting to specify whether to show the Welcome (Quick Setup) experience on first install — closes [#1049](https://github.com/eamodio/vscode-gitlens/issues/1049) thanks to [PR #1258](https://github.com/eamodio/vscode-gitlens/pull/1258) by Rickard ([@rickardp](https://github.com/rickardp))
### Changed

+ 17
- 26
README.md Dosyayı Görüntüle

@ -551,12 +551,12 @@ The _Search & Compare_ view lists pinnable (saved) results for searching commit
- `git config --global -e`
- set VS Code as your `difftool`
- add or replace these entries:
~~~
```
[diff]
tool = vscode
[difftool "vscode"]
cmd = code --wait --diff $LOCAL $REMOTE
~~~
```
- to use VS Code Insider's, replace `code` & `vscode` in the above with `code-insiders`
## Terminal Links [#](#terminal-links- 'Terminal Links')
@ -570,7 +570,7 @@ The _Search & Compare_ view lists pinnable (saved) results for searching commit
## Remote Provider Integrations [#](#remote-provider-integrations- 'Remote Provider Integrations')
GitLens provides rich integrations with many remote providers, including GitHub, GitHub Enterprise, GitLab, Bitbucket, Bitbucket Server, Azure DevOps. You can also define [custom remote providers](#custom-remotes-settings 'Jump to the Custom Remotes settings') or [remote providers with custom domains](#custom-remotes-settings 'Jump to the Custom Remotes settings') as well.
GitLens provides rich integrations with many remote providers, including GitHub, GitHub Enterprise, GitLab, Bitbucket, Bitbucket Server, Azure DevOps. You can also define [custom remote providers](#remote-provider-integration-settings- 'Jump to the Remote Provider Integration settings') or [remote providers with custom domains](#remote-provider-integration-settings- 'Jump to the Remote Provider Integration settings') as well.
Basic integrations provide issue and pull request auto-linking, while richer integrations (e.g. GitHub) can provide rich hover information provided for auto-linked issues and pull requests, associate pull requests with branches and commits, and provide avatars.
@ -831,25 +831,20 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.views.contributors.pullRequests.enabled` | Specifies whether to query for pull requests associated with the current branch and commits in the _Contributors_ view. Requires a connection to a supported remote service (e.g. GitHub) |
| `gitlens.views.contributors.pullRequests.showForCommits` | Specifies whether to show pull requests (if any) associated with the current branch in the _Contributors_ view. Requires a connection to a supported remote service (e.g. GitHub) |
## Search & Compare View Settings [#](#search-&-compareview-settings- 'Search & Compare View Settings')
## Search & Compare View Settings [#](#search-&-compare-view-settings- 'Search & Compare View Settings')
See also [View Settings](#view-settings- 'Jump to the View settings')
| Name | Description |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gitlens.views.compare.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Search Commits_ view<br />Only applies when `gitlens.views.compare.files.layout` is set to `auto` |
| `gitlens.views.compare.avatars` | Specifies whether to show avatar images instead of commit (or status) icons in the _Compare_ view |
| `gitlens.views.compare.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Compare_ view. Only applies when `gitlens.views.compare.files.layout` is set to `tree` or `auto` |
| `gitlens.views.compare.files.layout` | Specifies how the _Compare_ view will display files<br /><br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.compare.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.compare.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Compare_ view. Only applies when `gitlens.views.compare.files.layout` is set to `auto` |
| `gitlens.views.search.avatars` | Specifies whether to show avatar images instead of commit (or status) icons in the _Search Commits_ view |
| `gitlens.views.search.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Search Commits_ view<br />Only applies when `gitlens.views.compare.files.layout` is set to `tree` or `auto` |
| `gitlens.views.search.files.layout` | Specifies how the _Search Commits_ view will display files<br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.compare.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.compare.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Search Commits_ view<br />Only applies when `gitlens.views.compare.files.layout` is set to `auto` |
See also [View Settings](#view-settings- 'Jump to the View settings')
| Name | Description |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `gitlens.views.compare.avatars` | Specifies whether to show avatar images instead of commit (or status) icons in the _Compare_ view |
| `gitlens.views.compare.files.compact` | Specifies whether to compact (flatten) unnecessary file nesting in the _Compare_ view. Only applies when `gitlens.views.compare.files.layout` is set to `tree` or `auto` |
| `gitlens.views.compare.files.layout` | Specifies how the _Compare_ view will display files<br /><br />`auto` - automatically switches between displaying files as a `tree` or `list` based on the `gitlens.views.compare.files.threshold` value and the number of files at each nesting level<br />`list` - displays files as a list<br />`tree` - displays files as a tree |
| `gitlens.views.compare.files.threshold` | Specifies when to switch between displaying files as a `tree` or `list` based on the number of files in a nesting level in the _Compare_ view. Only applies when `gitlens.views.compare.files.layout` is set to `auto` |
## Gutter Blame Settings [#](#gutter-blame-settings- 'Gutter Blame Settings')
@ -895,6 +890,13 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.gitCommands.search.showResultsInSideBar` | Specifies whether to show the commit search results directly in the quick pick menu, in the Side Bar, or will be based on the context |
| `gitlens.gitCommands.skipConfirmations` | Specifies which (and when) Git commands will skip the confirmation step, using the format: `git-command-name:(menu/command)` |
## Remote Provider Integration Settings [#](#remote-provider-integration-settings- 'Remote Provider Integration Settings')
| Name | Description |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gitlens.integrations.enabled` | Specifies whether to enable rich integrations with any supported remote services |
| `gitlens.remotes` | Specifies user-defined remote (code-hosting) services or custom domains for built-in remote services<br /><br />Example:<br />`"gitlens.remotes": [{ "domain": "git.corporate-url.com", "type": "GitHub" }]`<br /><br />Example:<br />`"gitlens.remotes": [{`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"domain": "git.corporate-url.com",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"type": "Custom",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"name": "My Company",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"protocol": "https",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"urls": {`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"repository": "https://git.corporate-url.com/${repo}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branches": "https://git.corporate-url.com/${repo}/branches",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branch": "https://git.corporate-url.com/${repo}/commits/${branch}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"commit": "https://git.corporate-url.com/${repo}/commit/${id}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"file": "https://git.corporate-url.com/${repo}?path=${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInBranch": "https://git.corporate-url.com/${repo}/blob/${branch}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInCommit": "https://git.corporate-url.com/${repo}/blob/${id}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileLine": "#L${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileRange": "#L${start}-L${end}"`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br />&nbsp;&nbsp;&nbsp;&nbsp;`}]`<br /><br />Example:<br />`"gitlens.remotes": [{`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"domain": "git.corporate-url.com",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"type": "Custom",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"name": "My Company",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"protocol": "https",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"urls": {`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"repository": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branches": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/branches",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branch": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/commits/${branch}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"commit": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/commit/${id}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"file": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}?path=${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInBranch": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/blob/${branch}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInCommit": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/blob/${id}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileLine": "#L${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileRange": "#L${start}-L${end}"`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br />&nbsp;&nbsp;&nbsp;&nbsp;`}]` |
## Date & Time Settings [#](#date--time-settings- 'Date & Time Settings')
| Name | Description |
@ -926,24 +928,17 @@ See also [View Settings](#view-settings- 'Jump to the View settings')
| `gitlens.mode.statusBar.alignment` | Specifies the active GitLens mode alignment in the status bar<br /><br />`left` - aligns to the left<br />`right` - aligns to the right |
| `gitlens.modes` | Specifies the user-defined GitLens modes<br /><br />Example &mdash; adds heatmap annotations to the built-in _Reviewing_ mode<br />`"gitlens.modes": { "review": { "annotations": "heatmap" } }`<br /><br />Example &mdash; adds a new _Annotating_ mode with blame annotations<br />`"gitlens.modes": {`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"annotate": {`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"name": "Annotating",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"statusBarItemName": "Annotating",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"description": "for root cause analysis",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"annotations": "blame",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"codeLens": false,`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"currentLine": false,`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"hovers": true`<br />&nbsp;&nbsp;&nbsp;&nbsp;`}`<br />`}` |
## Autolink Settings
## Autolink Settingss [#](#autolink-settings- 'Autolink Settings')
| Name | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `gitlens.autolinks` | Specifies autolinks to external resources in commit messages. Use `<num>` as the variable for the reference number<br /><br />Example to autolink Jira issues: (e.g. `JIRA-123 ⟶ https://jira.company.com/issue?query=123`)<br />`"gitlens.autolinks": [{ "prefix": "JIRA-", "url": "https://jira.company.com/issue?query=<num>" }]` |
## Custom Remotes Settings
| Name | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gitlens.remotes` | Specifies user-defined remote (code-hosting) services or custom domains for built-in remote services<br /><br />Example:<br />`"gitlens.remotes": [{ "domain": "git.corporate-url.com", "type": "GitHub" }]`<br /><br />Example:<br />`"gitlens.remotes": [{`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"domain": "git.corporate-url.com",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"type": "Custom",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"name": "My Company",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"protocol": "https",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"urls": {`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"repository": "https://git.corporate-url.com/${repo}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branches": "https://git.corporate-url.com/${repo}/branches",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branch": "https://git.corporate-url.com/${repo}/commits/${branch}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"commit": "https://git.corporate-url.com/${repo}/commit/${id}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"file": "https://git.corporate-url.com/${repo}?path=${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInBranch": "https://git.corporate-url.com/${repo}/blob/${branch}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInCommit": "https://git.corporate-url.com/${repo}/blob/${id}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileLine": "#L${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileRange": "#L${start}-L${end}"`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br />&nbsp;&nbsp;&nbsp;&nbsp;`}]`<br /><br />Example:<br />`"gitlens.remotes": [{`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"domain": "git.corporate-url.com",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"type": "Custom",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"name": "My Company",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"protocol": "https",`<br />&nbsp;&nbsp;&nbsp;&nbsp;`"urls": {`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"repository": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branches": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/branches",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"branch": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/commits/${branch}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"commit": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/commit/${id}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"file": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}?path=${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInBranch": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/blob/${branch}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileInCommit": "https://git.corporate-url.com/projects/${repoBase}/repos/${repoPath}/blob/${id}/${file}${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileLine": "#L${line}",`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`"fileRange": "#L${start}-L${end}"`<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br />&nbsp;&nbsp;&nbsp;&nbsp;`}]` |
## Misc Settings [#](#misc-settings- 'Misc Settings')
| Name | Description |
| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gitlens.defaultGravatarsStyle` | Specifies the style of the gravatar default (fallback) images<br /><br />`identicon` - a geometric pattern<br />`mm` - a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)<br />`monsterid` - a monster with different colors, faces, etc<br />`retro` - 8-bit arcade-style pixelated faces<br />`robohash` - a robot with different colors, faces, etc<br />`wavatar` - a face with differing features and backgrounds |
| `gitlens.insiders` | Specifies whether to enable experimental features |
| `gitlens.liveshare.allowGuestAccess` | Specifies whether to allow guest access to GitLens features when using Visual Studio Live Share |
| `gitlens.outputLevel` | Specifies how much (if any) output will be sent to the GitLens output channel |
| `gitlens.showWelcomeOnInstall` | Specifies whether to show the Welcome (Quick Setup) experience on first install |
@ -979,10 +974,6 @@ GitLens defines a set of themable colors which can be provided by vscode themes
| `gitlens.lineHighlightBackgroundColor` | Specifies the background color of the associated line highlights in blame annotations |
| `gitlens.lineHighlightOverviewRulerColor` | Specifies the overview ruler color of the associated line highlights in blame annotations |
## Insiders
Add [`"gitlens.insiders": true`](#misc-settings- 'Jump to Misc settings') to your settings to join the insiders channel and get early access to upcoming features. Be aware that because this provides early access expect there to be issues.
# Contributors &#x1F64F;&#x2764;
A big thanks to the people that have contributed to this project:

+ 21
- 17
package.json Dosyayı Görüntüle

@ -909,9 +909,13 @@
"scope": "window"
},
"gitlens.insiders": {
"deprecationMessage": "Deprecated. Use the Insiders edition of GitLens instead",
"markdownDeprecationMessage": "Deprecated. Use the [Insiders edition](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens-insiders) of GitLens instead"
},
"gitlens.integrations.enabled": {
"type": "boolean",
"default": false,
"markdownDescription": "Specifies whether to enable experimental features",
"default": true,
"markdownDescription": "Specifies whether to enable rich integrations with any supported remote services",
"scope": "window"
},
"gitlens.keymap": {
@ -3060,6 +3064,11 @@
}
},
{
"command": "gitlens.resetRemoteConnectionAuthorization",
"title": "Reset Remote Connection Authorization",
"category": "GitLens"
},
{
"command": "gitlens.copyMessageToClipboard",
"title": "Copy Message",
"category": "GitLens",
@ -4446,11 +4455,6 @@
"command": "gitlens.views.tags.setShowAvatarsOff",
"title": "Hide Avatars",
"category": "GitLens"
},
{
"command": "gitlens.resetRemoteConnectionAuthorization",
"title": "Reset Remote Connection Authorization",
"category": "GitLens"
}
],
"menus": {
@ -4765,11 +4769,15 @@
},
{
"command": "gitlens.connectRemoteProvider",
"when": "false"
"when": "config.gitlens.integrations.enabled && gitlens:hasRichRemotes && !gitlens:hasConnectedRemotes"
},
{
"command": "gitlens.disconnectRemoteProvider",
"when": "false"
"when": "config.gitlens.integrations.enabled && gitlens:hasRichRemotes && gitlens:hasConnectedRemotes"
},
{
"command": "gitlens.resetRemoteConnectionAuthorization",
"when": "config.gitlens.integrations.enabled && gitlens:hasRichRemotes"
},
{
"command": "gitlens.copyMessageToClipboard",
@ -5654,10 +5662,6 @@
{
"command": "gitlens.views.tags.setShowAvatarsOff",
"when": "false"
},
{
"command": "gitlens.resetRemoteConnectionAuthorization",
"when": "gitlens:hasRichRemotes"
}
],
"editor/context": [
@ -7054,12 +7058,12 @@
},
{
"command": "gitlens.connectRemoteProvider",
"when": "viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+disconnected\\b)/",
"when": "config.gitlens.integrations.enabled && viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+disconnected\\b)/",
"group": "inline@98"
},
{
"command": "gitlens.disconnectRemoteProvider",
"when": "viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+connected\\b)/",
"when": "config.gitlens.integrations.enabled && viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+connected\\b)/",
"group": "inline@98"
},
{
@ -7107,12 +7111,12 @@
},
{
"command": "gitlens.connectRemoteProvider",
"when": "viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+disconnected\\b)/",
"when": "config.gitlens.integrations.enabled && viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+disconnected\\b)/",
"group": "8_gitlens_actions@2"
},
{
"command": "gitlens.disconnectRemoteProvider",
"when": "viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+connected\\b)/",
"when": "config.gitlens.integrations.enabled && viewItem =~ /gitlens:remote\\b(?=.*?\\b\\+connected\\b)/",
"group": "8_gitlens_actions@2"
},
{

+ 13
- 10
src/avatars.ts Dosyayı Görüntüle

@ -102,7 +102,10 @@ export function getAvatarUri(
query = getAvatarUriFromRemoteProvider(avatar, key, email, repoPathOrCommit, { size: size }).then(
uri => uri ?? avatar.uri ?? avatar.fallback!,
);
avatarQueue.set(key, query);
avatarQueue.set(
key,
query.finally(() => avatarQueue.delete(key)),
);
}
if (query != null) return query;
@ -179,13 +182,15 @@ async function getAvatarUriFromRemoteProvider(
try {
let account;
// if (typeof repoPathOrCommit === 'string') {
// const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit);
// account = await remote?.provider.getAccountForEmail(email, { avatarSize: size });
// } else {
if (typeof repoPathOrCommit !== 'string') {
const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit.repoPath);
account = await remote?.provider.getAccountForCommit(repoPathOrCommit.ref, { avatarSize: size });
if (Container.config.integrations.enabled) {
// if (typeof repoPathOrCommit === 'string') {
// const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit);
// account = await remote?.provider.getAccountForEmail(email, { avatarSize: size });
// } else {
if (typeof repoPathOrCommit !== 'string') {
const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit.repoPath);
account = await remote?.provider.getAccountForCommit(repoPathOrCommit.ref, { avatarSize: size });
}
}
if (account == null) {
// If we have no account assume that won't change (without a reset), so set the timestamp to "never expire"
@ -213,8 +218,6 @@ async function getAvatarUriFromRemoteProvider(
avatar.retries++;
return undefined;
} finally {
avatarQueue.delete(key);
}
}

+ 80
- 9
src/commands/remoteProviders.ts Dosyayı Görüntüle

@ -1,7 +1,9 @@
'use strict';
import { GitCommit, GitRemote } from '../git/git';
import { GitCommit, GitRemote, Repository, RichRemoteProvider } from '../git/git';
import { command, Command, CommandContext, Commands, isCommandContextViewNodeHasRemote } from './common';
import { Container } from '../container';
import { RepositoryPicker } from '../quickpicks/repositoryPicker';
import { Iterables } from '../system';
export interface ConnectRemoteProviderCommandArgs {
remote: string;
@ -39,14 +41,46 @@ export class ConnectRemoteProviderCommand extends Command {
}
async execute(args?: ConnectRemoteProviderCommandArgs): Promise<any> {
if (args?.repoPath == null || args?.remote == null) return false;
let remote: GitRemote<RichRemoteProvider> | undefined;
let remotes: GitRemote[] | undefined;
let repoPath;
if (args?.repoPath == null) {
const repos = new Map<Repository, GitRemote<RichRemoteProvider>>();
for (const repo of await Container.git.getOrderedRepositories()) {
const remote = await repo.getRichRemote();
if (remote?.provider != null && !(await remote.provider.isConnected())) {
repos.set(repo, remote);
}
}
if (repos.size === 0) return false;
if (repos.size === 1) {
let repo;
[repo, remote] = Iterables.first(repos);
repoPath = repo.path;
} else {
const pick = await RepositoryPicker.show('', '', [...repos.keys()]);
if (pick?.item == null) return undefined;
repoPath = pick.repoPath;
remote = repos.get(pick.item)!;
}
} else if (args?.remote == null) {
repoPath = args.repoPath;
remote = await Container.git.getRichRemoteProvider(repoPath, { includeDisconnected: true });
if (remote == null) return false;
} else {
repoPath = args.repoPath;
const remotes = await Container.git.getRemotes(args.repoPath);
const remote = remotes.find(r => r.id === args.remote);
if (!remote?.provider.hasApi()) return false;
remotes = await Container.git.getRemotes(repoPath);
remote = remotes.find(r => r.id === args.remote) as GitRemote<RichRemoteProvider> | undefined;
if (!remote?.provider.hasApi()) return false;
}
const connected = await remote.provider.connect();
if (connected && !remotes.some(r => r.default)) {
if (connected && !(remotes ?? (await Container.git.getRemotes(repoPath))).some(r => r.default)) {
await remote.setAsDefault(true);
}
return connected;
@ -92,10 +126,47 @@ export class DisconnectRemoteProviderCommand extends Command {
}
async execute(args?: DisconnectRemoteProviderCommandArgs): Promise<any> {
if (args?.repoPath == null || args?.remote == null) return undefined;
let remote: GitRemote<RichRemoteProvider> | undefined;
let repoPath;
if (args?.repoPath == null) {
const repos = new Map<Repository, GitRemote<RichRemoteProvider>>();
for (const repo of await Container.git.getOrderedRepositories()) {
const remote = await repo.getRichRemote(true);
if (remote != null) {
repos.set(repo, remote);
}
}
if (repos.size === 0) return undefined;
if (repos.size === 1) {
let repo;
[repo, remote] = Iterables.first(repos);
repoPath = repo.path;
} else {
const pick = await RepositoryPicker.show(
'Choose which repository to disconnect the remote on',
undefined,
[...repos.keys()],
);
if (pick?.item == null) return undefined;
repoPath = pick.repoPath;
remote = repos.get(pick.item)!;
}
} else if (args?.remote == null) {
repoPath = args.repoPath;
remote = await Container.git.getRichRemoteProvider(repoPath, { includeDisconnected: false });
if (remote == null) return undefined;
} else {
repoPath = args.repoPath;
const remote = (await Container.git.getRemotes(args.repoPath)).find(r => r.id === args.remote);
if (!remote?.provider.hasApi()) return undefined;
remote = (await Container.git.getRemotes(repoPath)).find(r => r.id === args.remote) as
| GitRemote<RichRemoteProvider>
| undefined;
if (!remote?.provider.hasApi()) return undefined;
}
return remote.provider.disconnect();
}

+ 3
- 1
src/config.ts Dosyayı Görüntüle

@ -92,7 +92,9 @@ export interface Config {
enabled: boolean;
};
};
insiders: boolean;
integrations: {
enabled: boolean;
};
keymap: KeyMap;
liveshare: {
allowGuestAccess: boolean;

+ 1
- 1
src/git/formatters/commitFormatter.ts Dosyayı Görüntüle

@ -310,7 +310,7 @@ export class CommitFormatter extends Formatter {
}\n${GlyphChars.Dash.repeat(2)}\n${pr.title}\n${pr.state}, ${pr.formatDateFromNow()}")${separator}`;
} else if (pr instanceof Promises.CancellationError) {
commands += `[$(git-pull-request) PR $(sync~spin)](command:${Commands.RefreshHover} "Searching for a Pull Request (if any) that introduced this commit...")${separator}`;
} else if (pr.provider != null) {
} else if (pr.provider != null && Container.config.integrations.enabled) {
commands += `[$(plug) Connect to ${pr.provider.name}${
GlyphChars.Ellipsis
}](${ConnectRemoteProviderCommand.getMarkdownCommandArgs(pr)} "Connect to ${

+ 2
- 1
src/git/gitService.ts Dosyayı Görüntüle

@ -146,6 +146,7 @@ export class GitService implements Disposable {
resetAvatarCache('failed');
}
this._remotesWithApiProviderCache.clear();
void this.updateContext(this._repositoryTree);
}),
);
this.onConfigurationChanged(configuration.initializingChangeEvent);
@ -450,7 +451,7 @@ export class GitService implements Disposable {
if (hasRepository) {
for (const repo of repositoryTree.values()) {
if (!hasConnectedRemotes) {
hasConnectedRemotes = await repo.hasConnectedRemote();
hasConnectedRemotes = await repo.hasRichRemote(true);
if (hasConnectedRemotes) {
hasRichRemotes = true;

+ 6
- 9
src/git/models/repository.ts Dosyayı Görüntüle

@ -507,6 +507,10 @@ export class Repository implements Disposable {
return this._remotes;
}
async getRichRemote(connectedOnly: boolean = false): Promise<GitRemote<RichRemoteProvider> | undefined> {
return Container.git.getRichRemoteProvider(await this.getRemotes(), { includeDisconnected: !connectedOnly });
}
private resetRemotesCache() {
this._remotes = undefined;
this._remotesDisposable?.dispose();
@ -541,20 +545,13 @@ export class Repository implements Disposable {
return Container.git.getTags(this.path, options);
}
async hasConnectedRemote(): Promise<boolean> {
const remote = await Container.git.getRichRemoteProvider(await this.getRemotes());
return remote?.provider != null;
}
async hasRemotes(): Promise<boolean> {
const remotes = await this.getRemotes();
return remotes?.length > 0;
}
async hasRichRemote(): Promise<boolean> {
const remote = await Container.git.getRichRemoteProvider(await this.getRemotes(), {
includeDisconnected: true,
});
async hasRichRemote(connectedOnly: boolean = false): Promise<boolean> {
const remote = await this.getRichRemote(connectedOnly);
return remote?.provider != null;
}

+ 2
- 0
src/git/remotes/provider.ts Dosyayı Görüntüle

@ -532,6 +532,8 @@ export abstract class RichRemoteProvider extends RemoteProvider {
private async ensureSession(createIfNeeded: boolean): Promise<AuthenticationSession | undefined> {
if (this._session != null) return this._session;
if (!Container.config.integrations.enabled) return undefined;
if (createIfNeeded) {
await Promise.all([
Container.context.workspaceState.update(this.connectedKey, undefined),

+ 3
- 1
src/quickpicks/repositoryPicker.ts Dosyayı Görüntüle

@ -1,6 +1,7 @@
'use strict';
import { Disposable, window } from 'vscode';
import { Container } from '../container';
import { Repository } from '../git/git';
import { getQuickPickIgnoreFocusOut, RepositoryQuickPickItem } from '../quickpicks';
import { Iterables } from '../system';
@ -8,9 +9,10 @@ export namespace RepositoryPicker {
export async function show(
title: string,
placeholder: string = 'Choose a repository',
repositories?: Repository[],
): Promise<RepositoryQuickPickItem | undefined> {
const items: RepositoryQuickPickItem[] = await Promise.all([
...Iterables.map(await Container.git.getOrderedRepositories(), r =>
...Iterables.map(repositories ?? (await Container.git.getOrderedRepositories()), r =>
RepositoryQuickPickItem.create(r, undefined, { branch: true, status: true }),
),
]);

+ 1
- 0
src/views/remotesView.ts Dosyayı Görüntüle

@ -181,6 +181,7 @@ export class RemotesView extends ViewBase {
!configuration.changed(e, 'defaultDateSource') &&
!configuration.changed(e, 'defaultDateStyle') &&
!configuration.changed(e, 'defaultGravatarsStyle') &&
!configuration.changed(e, 'integrations', 'enabled') &&
!configuration.changed(e, 'sortBranchesBy')
) {
return false;

Yükleniyor…
İptal
Kaydet