mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
src/**
|
||||
test/**
|
||||
out/test/**
|
||||
tsconfig.json
|
||||
tsconfig.json
|
||||
build/**
|
||||
@@ -1,29 +1,52 @@
|
||||
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
|
||||
[{
|
||||
"name": "textmate/git.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/textmate/git.tmbundle",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) 2008 Tim Harper",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining",
|
||||
"a copy of this software and associated documentation files (the\"",
|
||||
"Software\"), to deal in the Software without restriction, including",
|
||||
"without limitation the rights to use, copy, modify, merge, publish,",
|
||||
"distribute, sublicense, and/or sell copies of the Software, and to",
|
||||
"permit persons to whom the Software is furnished to do so, subject to",
|
||||
"the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be",
|
||||
"included in all copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
|
||||
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
|
||||
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND",
|
||||
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE",
|
||||
"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION",
|
||||
"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION",
|
||||
"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
]
|
||||
}]
|
||||
[
|
||||
{
|
||||
"name": "textmate/git.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repositoryURL": "https://github.com/textmate/git.tmbundle",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) 2008 Tim Harper",
|
||||
"",
|
||||
"Permission is hereby granted, free of charge, to any person obtaining",
|
||||
"a copy of this software and associated documentation files (the\"",
|
||||
"Software\"), to deal in the Software without restriction, including",
|
||||
"without limitation the rights to use, copy, modify, merge, publish,",
|
||||
"distribute, sublicense, and/or sell copies of the Software, and to",
|
||||
"permit persons to whom the Software is furnished to do so, subject to",
|
||||
"the following conditions:",
|
||||
"",
|
||||
"The above copyright notice and this permission notice shall be",
|
||||
"included in all copies or substantial portions of the Software.",
|
||||
"",
|
||||
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
|
||||
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
|
||||
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND",
|
||||
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE",
|
||||
"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION",
|
||||
"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION",
|
||||
"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "textmate/diff.tmbundle",
|
||||
"version": "0.0.0",
|
||||
"license": "TextMate Bundle License",
|
||||
"repositoryURL": "https://github.com/textmate/diff.tmbundle",
|
||||
"licenseDetail": [
|
||||
"Copyright (c) textmate-diff.tmbundle project authors",
|
||||
"",
|
||||
"If not otherwise specified (see below), files in this repository fall under the following license:",
|
||||
"",
|
||||
"Permission to copy, use, modify, sell and distribute this",
|
||||
"software is granted. This software is provided \"as is\" without",
|
||||
"express or implied warranty, and with no claim as to its",
|
||||
"suitability for any purpose.",
|
||||
"",
|
||||
"An exception is made for files in readable text which contain their own license information,",
|
||||
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
|
||||
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
|
||||
"\"tidy\" is accompanied by \"tidy-license.txt\"."
|
||||
]
|
||||
}
|
||||
]
|
||||
2
extensions/git/README.md
Normal file
2
extensions/git/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Git integration for Visual Studio Code
|
||||
|
||||
16
extensions/git/build/update-grammars.js
Normal file
16
extensions/git/build/update-grammars.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
var updateGrammar = require('../../../build/npm/update-grammar');
|
||||
|
||||
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Commit%20Message.tmLanguage', './syntaxes/git-commit.tmLanguage.json');
|
||||
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Rebase%20Message.tmLanguage', './syntaxes/git-rebase.tmLanguage.json');
|
||||
updateGrammar.update('textmate/diff.tmbundle', 'Syntaxes/Diff.plist', './syntaxes/diff.tmLanguage.json');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
11
extensions/git/languages/diff.language-configuration.json
Normal file
11
extensions/git/languages/diff.language-configuration.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"comments": {
|
||||
"lineComment": "#",
|
||||
"blockComment": [ "#", " " ]
|
||||
},
|
||||
"brackets": [
|
||||
["{", "}"],
|
||||
["[", "]"],
|
||||
["(", ")"]
|
||||
]
|
||||
}
|
||||
36
extensions/git/npm-shrinkwrap.json
generated
36
extensions/git/npm-shrinkwrap.json
generated
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "git",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"applicationinsights": {
|
||||
"version": "0.18.0",
|
||||
"from": "applicationinsights@0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz"
|
||||
},
|
||||
"byline": {
|
||||
"version": "5.0.0",
|
||||
"from": "byline@latest",
|
||||
"resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz"
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.15",
|
||||
"from": "iconv-lite@0.4.15",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz"
|
||||
},
|
||||
"vscode-extension-telemetry": {
|
||||
"version": "0.0.8",
|
||||
"from": "vscode-extension-telemetry@>=0.0.8 <0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz"
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "2.0.2",
|
||||
"from": "vscode-nls@>=2.0.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-2.0.2.tgz"
|
||||
},
|
||||
"winreg": {
|
||||
"version": "1.2.3",
|
||||
"from": "winreg@1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "git",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"publisher": "vscode",
|
||||
"displayName": "git",
|
||||
"description": "Git",
|
||||
"version": "0.0.1",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"vscode": "^1.5.0"
|
||||
},
|
||||
@@ -16,9 +16,11 @@
|
||||
"*"
|
||||
],
|
||||
"main": "./out/main",
|
||||
"icon": "resources/icons/git.png",
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:git",
|
||||
"watch": "gulp watch-extension:git"
|
||||
"watch": "gulp watch-extension:git",
|
||||
"update-grammar": "node ./build/update-grammars.js"
|
||||
},
|
||||
"contributes": {
|
||||
"commands": [
|
||||
@@ -68,6 +70,15 @@
|
||||
"dark": "resources/icons/dark/open-file.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.openFile2",
|
||||
"title": "%command.openFile%",
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/open-file-mono.svg",
|
||||
"dark": "resources/icons/dark/open-file-mono.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.openHEADFile",
|
||||
"title": "%command.openHEADFile%",
|
||||
@@ -327,35 +338,35 @@
|
||||
},
|
||||
{
|
||||
"command": "git.close",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.refresh",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.openHEADFile",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stage",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stageAll",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stageChange",
|
||||
@@ -363,155 +374,159 @@
|
||||
},
|
||||
{
|
||||
"command": "git.revertSelectedRanges",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.revertChange",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile2",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "git.unstage",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageAll",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageSelectedRanges",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.clean",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && !gitFreshRepository"
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAll",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && !gitFreshRepository"
|
||||
},
|
||||
{
|
||||
"command": "git.commit",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.commitStaged",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.commitStagedSigned",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.commitStagedAmend",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.commitAll",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.commitAllSigned",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.commitAllAmend",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.undoCommit",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.checkout",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.branch",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.deleteBranch",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.renameBranch",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.pull",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.pullFrom",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.pullRebase",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.pullFrom",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.merge",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.createTag",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.fetch",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.push",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.pushTo",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.pushWithTags",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.sync",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.syncRebase",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.publish",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.showOutput",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled"
|
||||
},
|
||||
{
|
||||
"command": "git.ignore",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stashIncludeUntracked",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stash",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stashPop",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
},
|
||||
{
|
||||
"command": "git.stashPopLatest",
|
||||
"when": "gitOpenRepositoryCount != 0"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
|
||||
}
|
||||
],
|
||||
"scm/title": [
|
||||
@@ -618,7 +633,7 @@
|
||||
{
|
||||
"command": "git.cleanAll",
|
||||
"group": "4_stage",
|
||||
"when": "scmProvider == git"
|
||||
"when": "scmProvider == git && !gitFreshRepository"
|
||||
},
|
||||
{
|
||||
"command": "git.stashIncludeUntracked",
|
||||
@@ -676,7 +691,7 @@
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAll",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && !gitFreshRepository",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
@@ -686,7 +701,7 @@
|
||||
},
|
||||
{
|
||||
"command": "git.cleanAll",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && !gitFreshRepository",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
@@ -701,11 +716,21 @@
|
||||
"when": "scmProvider == git && scmResourceGroup == merge",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"when": "scmProvider == git && scmResourceGroup == merge",
|
||||
"group": "navigation"
|
||||
},
|
||||
{
|
||||
"command": "git.stage",
|
||||
"when": "scmProvider == git && scmResourceGroup == merge",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile2",
|
||||
"when": "scmProvider == git && scmResourceGroup == merge && config.git.showInlineOpenFileAction",
|
||||
"group": "inline0"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
"when": "scmProvider == git && scmResourceGroup == index",
|
||||
@@ -731,6 +756,11 @@
|
||||
"when": "scmProvider == git && scmResourceGroup == index",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile2",
|
||||
"when": "scmProvider == git && scmResourceGroup == index && config.git.showInlineOpenFileAction",
|
||||
"group": "inline0"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
@@ -753,12 +783,12 @@
|
||||
},
|
||||
{
|
||||
"command": "git.clean",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && !gitFreshRepository",
|
||||
"group": "1_modification"
|
||||
},
|
||||
{
|
||||
"command": "git.clean",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && !gitFreshRepository",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
@@ -766,6 +796,11 @@
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
"group": "inline"
|
||||
},
|
||||
{
|
||||
"command": "git.openFile2",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree && config.git.showInlineOpenFileAction",
|
||||
"group": "inline0"
|
||||
},
|
||||
{
|
||||
"command": "git.ignore",
|
||||
"when": "scmProvider == git && scmResourceGroup == workingTree",
|
||||
@@ -776,27 +811,27 @@
|
||||
{
|
||||
"command": "git.openFile",
|
||||
"group": "navigation",
|
||||
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != extension && resourceScheme != merge-conflict.conflict-diff"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.openChange",
|
||||
"group": "navigation",
|
||||
"when": "gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme == file"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme == file"
|
||||
},
|
||||
{
|
||||
"command": "git.stageSelectedRanges",
|
||||
"group": "2_git@1",
|
||||
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.unstageSelectedRanges",
|
||||
"group": "2_git@2",
|
||||
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
},
|
||||
{
|
||||
"command": "git.revertSelectedRanges",
|
||||
"group": "2_git@3",
|
||||
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
|
||||
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/"
|
||||
}
|
||||
],
|
||||
"scm/change/title": [
|
||||
@@ -828,6 +863,11 @@
|
||||
"default": null,
|
||||
"isExecutable": true
|
||||
},
|
||||
"git.autoRepositoryDetection": {
|
||||
"type": "boolean",
|
||||
"description": "%config.autoRepositoryDetection%",
|
||||
"default": true
|
||||
},
|
||||
"git.autorefresh": {
|
||||
"type": "boolean",
|
||||
"description": "%config.autorefresh%",
|
||||
@@ -898,6 +938,32 @@
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "%config.decorations.enabled%"
|
||||
},
|
||||
"git.promptToSaveFilesBeforeCommit": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "%config.promptToSaveFilesBeforeCommit%"
|
||||
},
|
||||
"git.showInlineOpenFileAction": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "%config.showInlineOpenFileAction%"
|
||||
},
|
||||
"git.inputValidation": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"always",
|
||||
"warn",
|
||||
"off"
|
||||
],
|
||||
"default": "warn",
|
||||
"description": "%config.inputValidation%"
|
||||
},
|
||||
"git.detectSubmodules": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
"default": true,
|
||||
"description": "%config.detectSubmodules%"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -946,15 +1012,86 @@
|
||||
"dark": "#6c6cc4",
|
||||
"highContrast": "#6c6cc4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gitDecoration.submoduleResourceForeground",
|
||||
"description": "%colors.submodule%",
|
||||
"defaults": {
|
||||
"light": "#1258a7",
|
||||
"dark": "#8db9e2",
|
||||
"highContrast": "#8db9e2"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"languages": [
|
||||
{
|
||||
"id": "git-commit",
|
||||
"aliases": [
|
||||
"Git Commit Message",
|
||||
"git-commit"
|
||||
],
|
||||
"filenames": [
|
||||
"COMMIT_EDITMSG",
|
||||
"MERGE_MSG"
|
||||
],
|
||||
"configuration": "./languages/git-commit.language-configuration.json"
|
||||
},
|
||||
{
|
||||
"id": "git-rebase",
|
||||
"aliases": [
|
||||
"Git Rebase Message",
|
||||
"git-rebase"
|
||||
],
|
||||
"filenames": [
|
||||
"git-rebase-todo"
|
||||
],
|
||||
"configuration": "./languages/git-rebase.language-configuration.json"
|
||||
},
|
||||
{
|
||||
"id": "diff",
|
||||
"aliases": [
|
||||
"Diff",
|
||||
"diff"
|
||||
],
|
||||
"extensions": [
|
||||
".patch",
|
||||
".diff",
|
||||
".rej"
|
||||
],
|
||||
"configuration": "./languages/diff.language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "git-commit",
|
||||
"scopeName": "text.git-commit",
|
||||
"path": "./syntaxes/git-commit.tmLanguage.json"
|
||||
},
|
||||
{
|
||||
"language": "git-rebase",
|
||||
"scopeName": "text.git-rebase",
|
||||
"path": "./syntaxes/git-rebase.tmLanguage.json"
|
||||
},
|
||||
{
|
||||
"language": "diff",
|
||||
"scopeName": "source.diff",
|
||||
"path": "./syntaxes/diff.tmLanguage.json"
|
||||
}
|
||||
],
|
||||
"configurationDefaults": {
|
||||
"[git-commit]": {
|
||||
"editor.rulers": [
|
||||
72
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"byline": "^5.0.0",
|
||||
"file-type": "^7.2.0",
|
||||
"iconv-lite": "0.4.19",
|
||||
"vscode-extension-telemetry": "0.0.8",
|
||||
"vscode-nls": "2.0.2",
|
||||
"vscode-extension-telemetry": "0.0.15",
|
||||
"vscode-nls": "^3.2.1",
|
||||
"which": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -965,4 +1102,4 @@
|
||||
"@types/which": "^1.0.28",
|
||||
"mocha": "^3.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"displayName": "Git",
|
||||
"description": "Git SCM Integration",
|
||||
"command.clone": "Clone",
|
||||
"command.init": "Initialize Repository",
|
||||
"command.close": "Close Repository",
|
||||
@@ -49,12 +51,13 @@
|
||||
"command.stashPopLatest": "Pop Latest Stash",
|
||||
"config.enabled": "Whether git is enabled",
|
||||
"config.path": "Path to the git executable",
|
||||
"config.autoRepositoryDetection": "Whether repositories should be automatically detected",
|
||||
"config.autorefresh": "Whether auto refreshing is enabled",
|
||||
"config.autofetch": "Whether auto fetching is enabled",
|
||||
"config.enableLongCommitWarning": "Whether long commit messages should be warned about",
|
||||
"config.confirmSync": "Confirm before synchronizing git repositories",
|
||||
"config.countBadge": "Controls the git badge counter. `all` counts all changes. `tracked` counts only the tracked changes. `off` turns it off.",
|
||||
"config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branchs, `tags` shows only tags and `remote` shows only remote branches.",
|
||||
"config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branches, `tags` shows only tags and `remote` shows only remote branches.",
|
||||
"config.ignoreLegacyWarning": "Ignores the legacy Git warning",
|
||||
"config.ignoreMissingGitWarning": "Ignores the warning when Git is missing",
|
||||
"config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository",
|
||||
@@ -63,9 +66,14 @@
|
||||
"config.enableCommitSigning": "Enables commit signing with GPG.",
|
||||
"config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.",
|
||||
"config.decorations.enabled": "Controls if Git contributes colors and badges to the explorer and the open editors view.",
|
||||
"config.promptToSaveFilesBeforeCommit": "Controls whether Git should check for unsaved files before committing.",
|
||||
"config.showInlineOpenFileAction": "Controls whether to show an inline Open File action in the Git changes view.",
|
||||
"config.inputValidation": "Controls when to show commit message input validation.",
|
||||
"config.detectSubmodules": "Controls whether to automatically detect git submodules.",
|
||||
"colors.modified": "Color for modified resources.",
|
||||
"colors.deleted": "Color for deleted resources.",
|
||||
"colors.untracked": "Color for untracked resources.",
|
||||
"colors.ignored": "Color for ignored resources.",
|
||||
"colors.conflict": "Color for resources with conflicts."
|
||||
"colors.conflict": "Color for resources with conflicts.",
|
||||
"colors.submodule": "Color for submodule resources."
|
||||
}
|
||||
1
extensions/git/resources/icons/dark/open-file-mono.svg
Normal file
1
extensions/git/resources/icons/dark/open-file-mono.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#C5C5C5" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#C5C5C5" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>
|
||||
|
After Width: | Height: | Size: 262 B |
BIN
extensions/git/resources/icons/git.png
Normal file
BIN
extensions/git/resources/icons/git.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
1
extensions/git/resources/icons/light/open-file-mono.svg
Normal file
1
extensions/git/resources/icons/light/open-file-mono.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#424242" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#424242" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>
|
||||
|
After Width: | Height: | Size: 262 B |
@@ -1,3 +1 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#656565" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#00539C" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#656565" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#00539C" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>
|
||||
|
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 262 B |
@@ -6,7 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import { Model } from './model';
|
||||
import { SourceControlInputBox, Uri } from 'vscode';
|
||||
import { Uri } from 'vscode';
|
||||
|
||||
export interface InputBox {
|
||||
value: string;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget, commands, Uri } from 'vscode';
|
||||
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget } from 'vscode';
|
||||
import { GitErrorCodes } from './git';
|
||||
import { Repository, Operation } from './repository';
|
||||
import { eventToPromise, filterEvent, onceEvent } from './util';
|
||||
@@ -54,20 +54,14 @@ export class AutoFetcher {
|
||||
}
|
||||
|
||||
const yes: MessageItem = { title: localize('yes', "Yes") };
|
||||
const readMore: MessageItem = { title: localize('read more', "Read More") };
|
||||
const no: MessageItem = { isCloseAffordance: true, title: localize('no', "No") };
|
||||
const askLater: MessageItem = { title: localize('not now', "Ask Me Later") };
|
||||
const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like Code to periodically run `git fetch`?"), yes, readMore, no, askLater);
|
||||
const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like Code to [periodically run 'git fetch']({0})?", 'https://go.microsoft.com/fwlink/?linkid=865294'), yes, no, askLater);
|
||||
|
||||
if (result === askLater) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result === readMore) {
|
||||
commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=865294'));
|
||||
return this.onFirstGoodRemoteOperation();
|
||||
}
|
||||
|
||||
if (result === yes) {
|
||||
const gitConfig = workspace.getConfiguration('git');
|
||||
gitConfig.update('autofetch', true, ConfigurationTarget.Global);
|
||||
|
||||
@@ -10,9 +10,10 @@ import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
|
||||
import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository';
|
||||
import { Model } from './model';
|
||||
import { toGitUri, fromGitUri } from './uri';
|
||||
import { grep } from './util';
|
||||
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange } from './staging';
|
||||
import { grep, isDescendant } from './util';
|
||||
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange, getModifiedRange } from './staging';
|
||||
import * as path from 'path';
|
||||
import { lstat, Stats } from 'fs';
|
||||
import * as os from 'os';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
@@ -168,8 +169,28 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private async _openResource(resource: Resource, preview?: boolean, preserveFocus?: boolean, preserveSelection?: boolean): Promise<void> {
|
||||
const left = await this.getLeftResource(resource);
|
||||
const right = await this.getRightResource(resource);
|
||||
let stat: Stats | undefined;
|
||||
|
||||
try {
|
||||
stat = await new Promise<Stats>((c, e) => lstat(resource.resourceUri.fsPath, (err, stat) => err ? e(err) : c(stat)));
|
||||
} catch (err) {
|
||||
// noop
|
||||
}
|
||||
|
||||
let left: Uri | undefined;
|
||||
let right: Uri | undefined;
|
||||
|
||||
if (stat && stat.isDirectory()) {
|
||||
const repository = this.model.getRepositoryForSubmodule(resource.resourceUri);
|
||||
|
||||
if (repository) {
|
||||
right = toGitUri(resource.resourceUri, resource.resourceGroupType === ResourceGroupType.Index ? 'index' : 'wt', { submoduleOf: repository.root });
|
||||
}
|
||||
} else {
|
||||
left = await this.getLeftResource(resource);
|
||||
right = await this.getRightResource(resource);
|
||||
}
|
||||
|
||||
const title = this.getTitle(resource);
|
||||
|
||||
if (!right) {
|
||||
@@ -216,7 +237,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
const { size, object } = await repository.lstree(gitRef, uri.fsPath);
|
||||
const { mimetype, encoding } = await repository.detectObjectType(object);
|
||||
const { mimetype } = await repository.detectObjectType(object);
|
||||
|
||||
if (mimetype === 'text/plain') {
|
||||
return toGitUri(uri, ref);
|
||||
@@ -330,7 +351,6 @@ export class CommandCenter {
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
let value = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
value = value.replace(/^~/, os.homedir());
|
||||
|
||||
const parentPath = await window.showInputBox({
|
||||
prompt: localize('parent', "Parent Directory"),
|
||||
@@ -358,11 +378,10 @@ export class CommandCenter {
|
||||
statusBarItem.command = cancelCommandId;
|
||||
statusBarItem.show();
|
||||
|
||||
const clonePromise = this.git.clone(url, parentPath, tokenSource.token);
|
||||
const clonePromise = this.git.clone(url, parentPath.replace(/^~/, os.homedir()), tokenSource.token);
|
||||
|
||||
try {
|
||||
window.withProgress({ location: ProgressLocation.SourceControl, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
|
||||
// window.withProgress({ location: ProgressLocation.Window, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
|
||||
|
||||
const repositoryPath = await clonePromise;
|
||||
|
||||
@@ -484,7 +503,10 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
if (resource) {
|
||||
uris = [...resourceStates.map(r => r.resourceUri), resource.resourceUri];
|
||||
const resources = ([resource, ...resourceStates] as Resource[])
|
||||
.filter(r => r.type !== Status.DELETED && r.type !== Status.INDEX_DELETED);
|
||||
|
||||
uris = resources.map(r => r.resourceUri);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,6 +533,11 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.openFile2')
|
||||
async openFile2(arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise<void> {
|
||||
this.openFile(arg, ...resourceStates);
|
||||
}
|
||||
|
||||
@command('git.openHEADFile')
|
||||
async openHEADFile(arg?: Resource | Uri): Promise<void> {
|
||||
let resource: Resource | undefined = undefined;
|
||||
@@ -709,10 +736,7 @@ export class CommandCenter {
|
||||
const modifiedDocument = textEditor.document;
|
||||
const selections = textEditor.selections;
|
||||
const selectedChanges = changes.filter(change => {
|
||||
const modifiedRange = change.modifiedEndLineNumber === 0
|
||||
? new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(change.modifiedStartLineNumber).range.start)
|
||||
: new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(change.modifiedEndLineNumber - 1).range.end);
|
||||
|
||||
const modifiedRange = getModifiedRange(modifiedDocument, change);
|
||||
return selections.every(selection => !selection.intersection(modifiedRange));
|
||||
});
|
||||
|
||||
@@ -940,6 +964,29 @@ export class CommandCenter {
|
||||
opts?: CommitOptions
|
||||
): Promise<boolean> {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const promptToSaveFilesBeforeCommit = config.get<boolean>('promptToSaveFilesBeforeCommit') === true;
|
||||
|
||||
if (promptToSaveFilesBeforeCommit) {
|
||||
const unsavedTextDocuments = workspace.textDocuments
|
||||
.filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath));
|
||||
|
||||
if (unsavedTextDocuments.length > 0) {
|
||||
const message = unsavedTextDocuments.length === 1
|
||||
? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before comitting?", path.basename(unsavedTextDocuments[0].uri.fsPath))
|
||||
: localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before comitting?", unsavedTextDocuments.length);
|
||||
const saveAndCommit = localize('save and commit', "Save All & Commit");
|
||||
const commit = localize('commit', "Commit Anyway");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit);
|
||||
|
||||
if (pick === saveAndCommit) {
|
||||
await Promise.all(unsavedTextDocuments.map(d => d.save()));
|
||||
await repository.status();
|
||||
} else if (pick !== commit) {
|
||||
return false; // do not commit on cancel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const enableSmartCommit = config.get<boolean>('enableSmartCommit') === true;
|
||||
const enableCommitSigning = config.get<boolean>('enableCommitSigning') === true;
|
||||
const noStagedChanges = repository.indexGroup.resourceStates.length === 0;
|
||||
@@ -963,6 +1010,8 @@ export class CommandCenter {
|
||||
|
||||
if (!opts) {
|
||||
opts = { all: noStagedChanges };
|
||||
} else if (!opts.all && noStagedChanges) {
|
||||
opts = { ...opts, all: true };
|
||||
}
|
||||
|
||||
// enable signing of commits if configurated
|
||||
@@ -996,8 +1045,14 @@ export class CommandCenter {
|
||||
return message;
|
||||
}
|
||||
|
||||
let value: string | undefined = undefined;
|
||||
|
||||
if (opts && opts.amend && repository.HEAD && repository.HEAD.commit) {
|
||||
value = (await repository.getCommit(repository.HEAD.commit)).message;
|
||||
}
|
||||
|
||||
return await window.showInputBox({
|
||||
value: opts && opts.defaultMsg,
|
||||
value,
|
||||
placeHolder: localize('commit message', "Commit message"),
|
||||
prompt: localize('provide commit message', "Please provide a commit message"),
|
||||
ignoreFocusOut: true
|
||||
@@ -1041,15 +1096,7 @@ export class CommandCenter {
|
||||
|
||||
@command('git.commitStagedAmend', { repository: true })
|
||||
async commitStagedAmend(repository: Repository): Promise<void> {
|
||||
let msg;
|
||||
if (repository.HEAD) {
|
||||
if (repository.HEAD.commit) {
|
||||
let id = repository.HEAD.commit;
|
||||
let commit = await repository.getCommit(id);
|
||||
msg = commit.message;
|
||||
}
|
||||
}
|
||||
await this.commitWithAnyInput(repository, { all: false, amend: true, defaultMsg: msg });
|
||||
await this.commitWithAnyInput(repository, { all: false, amend: true });
|
||||
}
|
||||
|
||||
@command('git.commitAll', { repository: true })
|
||||
@@ -1267,25 +1314,26 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const picks = remotes.map(r => ({ label: r.name, description: r.url }));
|
||||
const remotePicks = remotes.map(r => ({ label: r.name, description: r.url }));
|
||||
const placeHolder = localize('pick remote pull repo', "Pick a remote to pull the branch from");
|
||||
const pick = await window.showQuickPick(picks, { placeHolder });
|
||||
const remotePick = await window.showQuickPick(remotePicks, { placeHolder });
|
||||
|
||||
if (!pick) {
|
||||
if (!remotePick) {
|
||||
return;
|
||||
}
|
||||
|
||||
const branchName = await window.showInputBox({
|
||||
placeHolder: localize('branch name', "Branch name"),
|
||||
prompt: localize('provide branch name', "Please provide a branch name"),
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
const remoteRefs = repository.refs;
|
||||
const remoteRefsFiltered = remoteRefs.filter(r => (r.remote === remotePick.label));
|
||||
const branchPicks = remoteRefsFiltered.map(r => ({ label: r.name })) as { label: string; description: string }[];
|
||||
const branchPick = await window.showQuickPick(branchPicks, { placeHolder });
|
||||
|
||||
if (!branchName) {
|
||||
if (!branchPick) {
|
||||
return;
|
||||
}
|
||||
|
||||
repository.pull(false, pick.label, branchName);
|
||||
const remoteCharCnt = remotePick.label.length;
|
||||
|
||||
repository.pull(false, remotePick.label, branchPick.label.slice(remoteCharCnt + 1));
|
||||
}
|
||||
|
||||
@command('git.pull', { repository: true })
|
||||
@@ -1321,7 +1369,27 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.push();
|
||||
if (!repository.HEAD || !repository.HEAD.name) {
|
||||
window.showWarningMessage(localize('nobranch', "Please check out a branch to push to a remote."));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await repository.push();
|
||||
} catch (err) {
|
||||
if (err.gitErrorCode !== GitErrorCodes.NoUpstreamBranch) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
const branchName = repository.HEAD.name;
|
||||
const message = localize('confirm publish branch', "The branch '{0}' has no upstream branch. Would you like to publish this branch?", branchName);
|
||||
const yes = localize('ok', "OK");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick === yes) {
|
||||
await this.publish(repository);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.pushWithTags', { repository: true })
|
||||
@@ -1377,7 +1445,7 @@ export class CommandCenter {
|
||||
if (shouldPrompt) {
|
||||
const message = localize('sync is unpredictable', "This action will push and pull commits to and from '{0}'.", HEAD.upstream);
|
||||
const yes = localize('ok', "OK");
|
||||
const neverAgain = localize('never again', "OK, Never Show Again");
|
||||
const neverAgain = localize('never again', "OK, Don't Show Again");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain);
|
||||
|
||||
if (pick === neverAgain) {
|
||||
@@ -1465,7 +1533,10 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private async _stash(repository: Repository, includeUntracked = false): Promise<void> {
|
||||
if (repository.workingTreeGroup.resourceStates.length === 0) {
|
||||
const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0;
|
||||
const noStagedChanges = repository.indexGroup.resourceStates.length === 0;
|
||||
|
||||
if (noUnstagedChanges && noStagedChanges) {
|
||||
window.showInformationMessage(localize('no changes stash', "There are no changes to stash."));
|
||||
return;
|
||||
}
|
||||
@@ -1641,13 +1712,18 @@ export class CommandCenter {
|
||||
const isSingleResource = arg instanceof Uri;
|
||||
|
||||
const groups = resources.reduce((result, resource) => {
|
||||
const repository = this.model.getRepository(resource);
|
||||
let repository = this.model.getRepository(resource);
|
||||
|
||||
if (!repository) {
|
||||
console.warn('Could not find git repository for ', resource);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Could it be a submodule?
|
||||
if (resource.fsPath === repository.root) {
|
||||
repository = this.model.getRepositoryForSubmodule(resource) || repository;
|
||||
}
|
||||
|
||||
const tuple = result.filter(p => p.repository === repository)[0];
|
||||
|
||||
if (tuple) {
|
||||
|
||||
@@ -52,7 +52,7 @@ export class GitContentProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidChange.fire(toGitUri(uri, '', true));
|
||||
this._onDidChange.fire(toGitUri(uri, '', { replaceFileExtension: true }));
|
||||
}
|
||||
|
||||
@debounce(1100)
|
||||
@@ -83,6 +83,18 @@ export class GitContentProvider {
|
||||
}
|
||||
|
||||
async provideTextDocumentContent(uri: Uri): Promise<string> {
|
||||
let { path, ref, submoduleOf } = fromGitUri(uri);
|
||||
|
||||
if (submoduleOf) {
|
||||
const repository = this.model.getRepository(submoduleOf);
|
||||
|
||||
if (!repository) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return await repository.diff(path, { cached: ref === 'index' });
|
||||
}
|
||||
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
@@ -95,8 +107,6 @@ export class GitContentProvider {
|
||||
|
||||
this.cache[cacheKey] = cacheValue;
|
||||
|
||||
let { path, ref } = fromGitUri(uri);
|
||||
|
||||
if (ref === '~') {
|
||||
const fileUri = Uri.file(path);
|
||||
const uriString = fileUri.toString();
|
||||
|
||||
@@ -6,35 +6,48 @@
|
||||
'use strict';
|
||||
|
||||
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
|
||||
import * as path from 'path';
|
||||
import { Repository, GitResourceGroup, Status } from './repository';
|
||||
import { Model } from './model';
|
||||
import { debounce } from './decorators';
|
||||
import { filterEvent } from './util';
|
||||
import { filterEvent, dispose, anyEvent, fireEvent } from './util';
|
||||
import { GitErrorCodes } from './git';
|
||||
|
||||
type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void };
|
||||
|
||||
class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
|
||||
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
|
||||
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
private checkIgnoreQueue = new Map<string, { resolve: (status: boolean) => void, reject: (err: any) => void }>();
|
||||
readonly onDidChangeDecorations: Event<Uri[]>;
|
||||
private queue = new Map<string, { repository: Repository; queue: Map<string, Callback>; }>();
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private repository: Repository) {
|
||||
this.disposables.push(
|
||||
window.registerDecorationProvider(this),
|
||||
filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore'))(_ => this._onDidChangeDecorations.fire())
|
||||
//todo@joh -> events when the ignore status actually changes, not only when the file changes
|
||||
);
|
||||
}
|
||||
constructor(private model: Model) {
|
||||
//todo@joh -> events when the ignore status actually changes, not only when the file changes
|
||||
this.onDidChangeDecorations = fireEvent(anyEvent<any>(
|
||||
filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore')),
|
||||
model.onDidOpenRepository,
|
||||
model.onDidCloseRepository
|
||||
));
|
||||
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
this.checkIgnoreQueue.clear();
|
||||
this.disposables.push(window.registerDecorationProvider(this));
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): Promise<DecorationData | undefined> {
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
let queueItem = this.queue.get(repository.root);
|
||||
|
||||
if (!queueItem) {
|
||||
queueItem = { repository, queue: new Map<string, Callback>() };
|
||||
this.queue.set(repository.root, queueItem);
|
||||
}
|
||||
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
this.checkIgnoreQueue.set(uri.fsPath, { resolve, reject });
|
||||
queueItem!.queue.set(uri.fsPath, { resolve, reject });
|
||||
this.checkIgnoreSoon();
|
||||
}).then(ignored => {
|
||||
if (ignored) {
|
||||
@@ -48,23 +61,42 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
|
||||
@debounce(500)
|
||||
private checkIgnoreSoon(): void {
|
||||
const queue = new Map(this.checkIgnoreQueue.entries());
|
||||
this.checkIgnoreQueue.clear();
|
||||
this.repository.checkIgnore([...queue.keys()]).then(ignoreSet => {
|
||||
for (const [key, value] of queue.entries()) {
|
||||
value.resolve(ignoreSet.has(key));
|
||||
}
|
||||
}, err => {
|
||||
console.error(err);
|
||||
for (const [, value] of queue.entries()) {
|
||||
value.reject(err);
|
||||
}
|
||||
});
|
||||
const queue = new Map(this.queue.entries());
|
||||
this.queue.clear();
|
||||
|
||||
for (const [, item] of queue) {
|
||||
const paths = [...item.queue.keys()];
|
||||
|
||||
item.repository.checkIgnore(paths).then(ignoreSet => {
|
||||
for (const [key, value] of item.queue.entries()) {
|
||||
value.resolve(ignoreSet.has(key));
|
||||
}
|
||||
}, err => {
|
||||
if (err.gitErrorCode !== GitErrorCodes.IsInSubmodule) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
for (const [, value] of item.queue.entries()) {
|
||||
value.reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
this.queue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class GitDecorationProvider implements DecorationProvider {
|
||||
|
||||
private static SubmoduleDecorationData: DecorationData = {
|
||||
title: 'Submodule',
|
||||
abbreviation: 'S',
|
||||
color: new ThemeColor('gitDecoration.submoduleResourceForeground')
|
||||
};
|
||||
|
||||
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
|
||||
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
@@ -80,6 +112,8 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
|
||||
private onDidRunGitStatus(): void {
|
||||
let newDecorations = new Map<string, DecorationData>();
|
||||
|
||||
this.collectSubmoduleDecorationData(newDecorations);
|
||||
this.collectDecorationData(this.repository.indexGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.workingTreeGroup, newDecorations);
|
||||
this.collectDecorationData(this.repository.mergeGroup, newDecorations);
|
||||
@@ -101,6 +135,12 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
});
|
||||
}
|
||||
|
||||
private collectSubmoduleDecorationData(bucket: Map<string, DecorationData>): void {
|
||||
for (const submodule of this.repository.submodules) {
|
||||
bucket.set(Uri.file(path.join(this.repository.root, submodule.path)).toString(), GitDecorationProvider.SubmoduleDecorationData);
|
||||
}
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): DecorationData | undefined {
|
||||
return this.decorations.get(uri.toString());
|
||||
}
|
||||
@@ -113,17 +153,21 @@ class GitDecorationProvider implements DecorationProvider {
|
||||
|
||||
export class GitDecorations {
|
||||
|
||||
private configListener: Disposable;
|
||||
private modelListener: Disposable[] = [];
|
||||
private disposables: Disposable[] = [];
|
||||
private modelDisposables: Disposable[] = [];
|
||||
private providers = new Map<Repository, Disposable>();
|
||||
|
||||
constructor(private model: Model) {
|
||||
this.configListener = workspace.onDidChangeConfiguration(e => e.affectsConfiguration('git.decorations.enabled') && this.update());
|
||||
this.disposables.push(new GitIgnoreDecorationProvider(model));
|
||||
|
||||
const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.decorations.enabled'));
|
||||
onEnablementChange(this.update, this, this.disposables);
|
||||
this.update();
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
const enabled = workspace.getConfiguration('git').get('decorations.enabled');
|
||||
|
||||
if (enabled) {
|
||||
this.enable();
|
||||
} else {
|
||||
@@ -132,26 +176,25 @@ export class GitDecorations {
|
||||
}
|
||||
|
||||
private enable(): void {
|
||||
this.modelListener = [];
|
||||
this.model.onDidOpenRepository(this.onDidOpenRepository, this, this.modelListener);
|
||||
this.model.onDidCloseRepository(this.onDidCloseRepository, this, this.modelListener);
|
||||
this.model.onDidOpenRepository(this.onDidOpenRepository, this, this.modelDisposables);
|
||||
this.model.onDidCloseRepository(this.onDidCloseRepository, this, this.modelDisposables);
|
||||
this.model.repositories.forEach(this.onDidOpenRepository, this);
|
||||
}
|
||||
|
||||
private disable(): void {
|
||||
this.modelListener.forEach(d => d.dispose());
|
||||
this.modelDisposables = dispose(this.modelDisposables);
|
||||
this.providers.forEach(value => value.dispose());
|
||||
this.providers.clear();
|
||||
}
|
||||
|
||||
private onDidOpenRepository(repository: Repository): void {
|
||||
const provider = new GitDecorationProvider(repository);
|
||||
const ignoreProvider = new GitIgnoreDecorationProvider(repository);
|
||||
this.providers.set(repository, Disposable.from(provider, ignoreProvider));
|
||||
this.providers.set(repository, provider);
|
||||
}
|
||||
|
||||
private onDidCloseRepository(repository: Repository): void {
|
||||
const provider = this.providers.get(repository);
|
||||
|
||||
if (provider) {
|
||||
provider.dispose();
|
||||
this.providers.delete(repository);
|
||||
@@ -159,9 +202,7 @@ export class GitDecorations {
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.configListener.dispose();
|
||||
this.modelListener.forEach(d => d.dispose());
|
||||
this.providers.forEach(value => value.dispose);
|
||||
this.providers.clear();
|
||||
this.disable();
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ function _throttle<T>(fn: Function, key: string): Function {
|
||||
|
||||
export const throttle = decorate(_throttle);
|
||||
|
||||
function _sequentialize<T>(fn: Function, key: string): Function {
|
||||
function _sequentialize(fn: Function, key: string): Function {
|
||||
const currentKey = `__$sequence$${key}`;
|
||||
|
||||
return function (this: any, ...args: any[]) {
|
||||
|
||||
@@ -16,7 +16,7 @@ import * as filetype from 'file-type';
|
||||
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util';
|
||||
import { CancellationToken } from 'vscode';
|
||||
|
||||
const readfile = denodeify<string>(fs.readFile);
|
||||
const readfile = denodeify<string, string | null, string>(fs.readFile);
|
||||
|
||||
export interface IGit {
|
||||
path: string;
|
||||
@@ -267,6 +267,7 @@ export class GitError {
|
||||
this.message = data.error.message;
|
||||
} else {
|
||||
this.error = void 0;
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
this.message = this.message || data.message || 'Git error';
|
||||
@@ -325,7 +326,9 @@ export const GitErrorCodes = {
|
||||
BranchAlreadyExists: 'BranchAlreadyExists',
|
||||
NoLocalChanges: 'NoLocalChanges',
|
||||
NoStashFound: 'NoStashFound',
|
||||
LocalChangesOverwritten: 'LocalChangesOverwritten'
|
||||
LocalChangesOverwritten: 'LocalChangesOverwritten',
|
||||
NoUpstreamBranch: 'NoUpstreamBranch',
|
||||
IsInSubmodule: 'IsInSubmodule'
|
||||
};
|
||||
|
||||
function getGitErrorCode(stderr: string): string | undefined {
|
||||
@@ -359,7 +362,6 @@ function getGitErrorCode(stderr: string): string | undefined {
|
||||
export class Git {
|
||||
|
||||
private gitPath: string;
|
||||
private version: string;
|
||||
private env: any;
|
||||
|
||||
private _onOutput = new EventEmitter();
|
||||
@@ -367,7 +369,6 @@ export class Git {
|
||||
|
||||
constructor(options: IGitOptions) {
|
||||
this.gitPath = options.gitPath;
|
||||
this.version = options.version;
|
||||
this.env = options.env || {};
|
||||
}
|
||||
|
||||
@@ -460,7 +461,7 @@ export class Git {
|
||||
});
|
||||
|
||||
if (options.log !== false) {
|
||||
this.log(`git ${args.join(' ')}\n`);
|
||||
this.log(`> git ${args.join(' ')}\n`);
|
||||
}
|
||||
|
||||
return cp.spawn(this.gitPath, args, options);
|
||||
@@ -542,6 +543,72 @@ export class GitStatusParser {
|
||||
}
|
||||
}
|
||||
|
||||
export interface Submodule {
|
||||
name: string;
|
||||
path: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export function parseGitmodules(raw: string): Submodule[] {
|
||||
const regex = /\r?\n/g;
|
||||
let position = 0;
|
||||
let match: RegExpExecArray | null = null;
|
||||
|
||||
const result: Submodule[] = [];
|
||||
let submodule: Partial<Submodule> = {};
|
||||
|
||||
function parseLine(line: string): void {
|
||||
const sectionMatch = /^\s*\[submodule "([^"]+)"\]\s*$/.exec(line);
|
||||
|
||||
if (sectionMatch) {
|
||||
if (submodule.name && submodule.path && submodule.url) {
|
||||
result.push(submodule as Submodule);
|
||||
}
|
||||
|
||||
const name = sectionMatch[1];
|
||||
|
||||
if (name) {
|
||||
submodule = { name };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!submodule) {
|
||||
return;
|
||||
}
|
||||
|
||||
const propertyMatch = /^\s*(\w+) = (.*)$/.exec(line);
|
||||
|
||||
if (!propertyMatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [, key, value] = propertyMatch;
|
||||
|
||||
switch (key) {
|
||||
case 'path': submodule.path = value; break;
|
||||
case 'url': submodule.url = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
while (match = regex.exec(raw)) {
|
||||
parseLine(raw.substring(position, match.index));
|
||||
position = match.index + match[0].length;
|
||||
}
|
||||
|
||||
parseLine(raw.substring(position));
|
||||
|
||||
if (submodule.name && submodule.path && submodule.url) {
|
||||
result.push(submodule as Submodule);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface DiffOptions {
|
||||
cached?: boolean;
|
||||
}
|
||||
|
||||
export class Repository {
|
||||
|
||||
constructor(
|
||||
@@ -611,7 +678,7 @@ export class Repository {
|
||||
return stdout;
|
||||
}
|
||||
|
||||
async lstree(treeish: string, path: string): Promise<{ mode: number, object: string, size: number }> {
|
||||
async lstree(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }> {
|
||||
if (!treeish) { // index
|
||||
const { stdout } = await this.run(['ls-files', '--stage', '--', path]);
|
||||
|
||||
@@ -625,7 +692,7 @@ export class Repository {
|
||||
const catFile = await this.run(['cat-file', '-s', object]);
|
||||
const size = parseInt(catFile.stdout);
|
||||
|
||||
return { mode: parseInt(mode), object, size };
|
||||
return { mode, object, size };
|
||||
}
|
||||
|
||||
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', path]);
|
||||
@@ -637,7 +704,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const [, mode, , object, size] = match;
|
||||
return { mode: parseInt(mode), object, size: parseInt(size) };
|
||||
return { mode, object, size: parseInt(size) };
|
||||
}
|
||||
|
||||
async detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
|
||||
@@ -680,6 +747,19 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
async diff(path: string, options: DiffOptions = {}): Promise<string> {
|
||||
const args = ['diff'];
|
||||
|
||||
if (options.cached) {
|
||||
args.push('--cached');
|
||||
}
|
||||
|
||||
args.push('--', path);
|
||||
|
||||
const result = await this.run(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async add(paths: string[]): Promise<void> {
|
||||
const args = ['add', '-A', '--'];
|
||||
|
||||
@@ -706,7 +786,16 @@ export class Repository {
|
||||
});
|
||||
}
|
||||
|
||||
await this.run(['update-index', '--cacheinfo', '100644', hash, path]);
|
||||
let mode: string;
|
||||
|
||||
try {
|
||||
const details = await this.lstree('HEAD', path);
|
||||
mode = details.mode;
|
||||
} catch (err) {
|
||||
mode = '100644';
|
||||
}
|
||||
|
||||
await this.run(['update-index', '--cacheinfo', mode, hash, path]);
|
||||
}
|
||||
|
||||
async checkout(treeish: string, paths: string[]): Promise<void> {
|
||||
@@ -953,6 +1042,8 @@ export class Repository {
|
||||
err.gitErrorCode = GitErrorCodes.PushRejected;
|
||||
} else if (/Could not read from remote repository/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.RemoteConnectionError;
|
||||
} else if (/^fatal: The current branch .* has no upstream branch/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoUpstreamBranch;
|
||||
}
|
||||
|
||||
throw err;
|
||||
@@ -1067,7 +1158,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
async getRefs(): Promise<Ref[]> {
|
||||
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)']);
|
||||
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)', '--sort', '-committerdate']);
|
||||
|
||||
const fn = (line: string): Ref | null => {
|
||||
let match: RegExpExecArray | null;
|
||||
@@ -1186,4 +1277,24 @@ export class Repository {
|
||||
|
||||
return { hash: match[1], message: match[2] };
|
||||
}
|
||||
|
||||
async updateSubmodules(paths: string[]): Promise<void> {
|
||||
const args = ['submodule', 'update', '--', ...paths];
|
||||
await this.run(args);
|
||||
}
|
||||
|
||||
async getSubmodules(): Promise<Submodule[]> {
|
||||
const gitmodulesPath = path.join(this.root, '.gitmodules');
|
||||
|
||||
try {
|
||||
const gitmodulesRaw = await readfile(gitmodulesPath, 'utf8');
|
||||
return parseGitmodules(gitmodulesRaw);
|
||||
} catch (err) {
|
||||
if (/ENOENT/.test(err.message)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
|
||||
const localize = nls.loadMessageBundle();
|
||||
import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel } from 'vscode';
|
||||
import { findGit, Git, IGit } from './git';
|
||||
import { Model } from './model';
|
||||
@@ -14,21 +14,19 @@ import { CommandCenter } from './commands';
|
||||
import { GitContentProvider } from './contentProvider';
|
||||
import { GitDecorations } from './decorationProvider';
|
||||
import { Askpass } from './askpass';
|
||||
import { toDisposable } from './util';
|
||||
import { toDisposable, filterEvent, eventToPromise } from './util';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { API, createApi } from './api';
|
||||
|
||||
async function init(context: ExtensionContext, outputChannel: OutputChannel, disposables: Disposable[]): Promise<Model> {
|
||||
const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string };
|
||||
const telemetryReporter: TelemetryReporter = new TelemetryReporter(name, version, aiKey);
|
||||
disposables.push(telemetryReporter);
|
||||
let telemetryReporter: TelemetryReporter;
|
||||
|
||||
async function init(context: ExtensionContext, outputChannel: OutputChannel, disposables: Disposable[]): Promise<Model> {
|
||||
const pathHint = workspace.getConfiguration('git').get<string>('path');
|
||||
const info = await findGit(pathHint, path => outputChannel.appendLine(localize('looking', "Looking for git in: {0}", path)));
|
||||
const askpass = new Askpass();
|
||||
const env = await askpass.getEnv();
|
||||
const git = new Git({ gitPath: info.path, version: info.version, env });
|
||||
const model = new Model(git, context.globalState);
|
||||
const model = new Model(git, context.globalState, outputChannel);
|
||||
disposables.push(model);
|
||||
|
||||
const onRepository = () => commands.executeCommand('setContext', 'gitOpenRepositoryCount', `${model.repositories.length}`);
|
||||
@@ -38,7 +36,15 @@ async function init(context: ExtensionContext, outputChannel: OutputChannel, dis
|
||||
|
||||
outputChannel.appendLine(localize('using git', "Using git {0} from {1}", info.version, info.path));
|
||||
|
||||
const onOutput = (str: string) => outputChannel.append(str);
|
||||
const onOutput = (str: string) => {
|
||||
const lines = str.split(/\r?\n/mg);
|
||||
|
||||
while (/^\s*$/.test(lines[lines.length - 1])) {
|
||||
lines.pop();
|
||||
}
|
||||
|
||||
outputChannel.appendLine(lines.join('\n'));
|
||||
};
|
||||
git.onOutput.addListener('log', onOutput);
|
||||
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
|
||||
|
||||
@@ -77,7 +83,7 @@ async function _activate(context: ExtensionContext, disposables: Disposable[]):
|
||||
outputChannel.show();
|
||||
|
||||
const download = localize('downloadgit', "Download Git");
|
||||
const neverShowAgain = localize('neverShowAgain', "Don't show again");
|
||||
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
|
||||
const choice = await window.showWarningMessage(
|
||||
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
|
||||
download,
|
||||
@@ -93,11 +99,30 @@ async function _activate(context: ExtensionContext, disposables: Disposable[]):
|
||||
}
|
||||
|
||||
export function activate(context: ExtensionContext): API {
|
||||
const config = workspace.getConfiguration('git', null);
|
||||
const enabled = config.get<boolean>('enabled');
|
||||
|
||||
const disposables: Disposable[] = [];
|
||||
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
|
||||
|
||||
const activatePromise = _activate(context, disposables);
|
||||
const modelPromise = activatePromise.then(model => model || Promise.reject<Model>('Git model not found'));
|
||||
const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string };
|
||||
telemetryReporter = new TelemetryReporter(name, version, aiKey);
|
||||
|
||||
let activatePromise: Promise<Model | undefined>;
|
||||
|
||||
if (enabled) {
|
||||
activatePromise = _activate(context, disposables);
|
||||
} else {
|
||||
const onConfigChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git'));
|
||||
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get<boolean>('enabled') === true);
|
||||
|
||||
activatePromise = eventToPromise(onEnabled)
|
||||
.then(() => _activate(context, disposables));
|
||||
}
|
||||
|
||||
const modelPromise = activatePromise
|
||||
.then(model => model || Promise.reject<Model>('Git model not found'));
|
||||
|
||||
activatePromise.catch(err => console.error(err));
|
||||
|
||||
return createApi(modelPromise);
|
||||
@@ -123,7 +148,7 @@ async function checkGitVersion(info: IGit): Promise<void> {
|
||||
}
|
||||
|
||||
const update = localize('updateGit', "Update Git");
|
||||
const neverShowAgain = localize('neverShowAgain', "Don't show again");
|
||||
const neverShowAgain = localize('neverShowAgain', "Don't Show Again");
|
||||
|
||||
const choice = await window.showWarningMessage(
|
||||
localize('git20', "You seem to have git {0} installed. Code works best with git >= 2", info.version),
|
||||
@@ -139,3 +164,7 @@ async function checkGitVersion(info: IGit): Promise<void> {
|
||||
// {{SQL CARBON EDIT}}
|
||||
*/
|
||||
}
|
||||
|
||||
export function deactivate(): Promise<any> {
|
||||
return telemetryReporter ? telemetryReporter.dispose() : Promise.resolve(null);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, ConfigurationChangeEvent } from 'vscode';
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel } from 'vscode';
|
||||
import { Repository, RepositoryState } from './repository';
|
||||
import { memoize, sequentialize, debounce } from './decorators';
|
||||
import { dispose, anyEvent, filterEvent, IDisposable, isDescendant } from './util';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex } from './util';
|
||||
import { Git, GitErrorCodes } from './git';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@@ -28,7 +28,7 @@ class RepositoryPick implements QuickPickItem {
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
constructor(public readonly repository: Repository) { }
|
||||
constructor(public readonly repository: Repository, public readonly index: number) { }
|
||||
}
|
||||
|
||||
export interface ModelChangeEvent {
|
||||
@@ -66,7 +66,7 @@ export class Model {
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private git: Git, private globalState: Memento) {
|
||||
constructor(private git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
|
||||
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
|
||||
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] });
|
||||
|
||||
@@ -93,17 +93,25 @@ export class Model {
|
||||
private async scanWorkspaceFolders(): Promise<void> {
|
||||
for (const folder of workspace.workspaceFolders || []) {
|
||||
const root = folder.uri.fsPath;
|
||||
const children = await new Promise<string[]>((c, e) => fs.readdir(root, (err, r) => err ? e(err) : c(r)));
|
||||
|
||||
children
|
||||
.filter(child => child !== '.git')
|
||||
.forEach(child => this.tryOpenRepository(path.join(root, child)));
|
||||
try {
|
||||
const children = await new Promise<string[]>((c, e) => fs.readdir(root, (err, r) => err ? e(err) : c(r)));
|
||||
|
||||
children
|
||||
.filter(child => child !== '.git')
|
||||
.forEach(child => this.tryOpenRepository(path.join(root, child)));
|
||||
} catch (err) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onPossibleGitRepositoryChange(uri: Uri): void {
|
||||
const possibleGitRepositoryPath = uri.fsPath.replace(/\.git.*$/, '');
|
||||
this.possibleGitRepositoryPaths.add(possibleGitRepositoryPath);
|
||||
this.eventuallyScanPossibleGitRepository(uri.fsPath.replace(/\.git.*$/, ''));
|
||||
}
|
||||
|
||||
private eventuallyScanPossibleGitRepository(path: string) {
|
||||
this.possibleGitRepositoryPaths.add(path);
|
||||
this.eventuallyScanPossibleGitRepositories();
|
||||
}
|
||||
|
||||
@@ -150,6 +158,13 @@ export class Model {
|
||||
}
|
||||
|
||||
private onDidChangeVisibleTextEditors(editors: TextEditor[]): void {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const enabled = config.get<boolean>('autoRepositoryDetection') === true;
|
||||
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
editors.forEach(editor => {
|
||||
const uri = editor.document.uri;
|
||||
|
||||
@@ -181,11 +196,13 @@ export class Model {
|
||||
}
|
||||
|
||||
try {
|
||||
const repositoryRoot = await this.git.getRepositoryRoot(path);
|
||||
const rawRoot = await this.git.getRepositoryRoot(path);
|
||||
|
||||
// This can happen whenever `path` has the wrong case sensitivity in
|
||||
// case insensitive file systems
|
||||
// https://github.com/Microsoft/vscode/issues/33498
|
||||
const repositoryRoot = Uri.file(rawRoot).fsPath;
|
||||
|
||||
if (this.getRepository(repositoryRoot)) {
|
||||
return;
|
||||
}
|
||||
@@ -203,15 +220,31 @@ export class Model {
|
||||
}
|
||||
|
||||
private open(repository: Repository): void {
|
||||
this.outputChannel.appendLine(`Open repository: ${repository.root}`);
|
||||
|
||||
const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed);
|
||||
const disappearListener = onDidDisappearRepository(() => dispose());
|
||||
const changeListener = repository.onDidChangeRepository(uri => this._onDidChangeRepository.fire({ repository, uri }));
|
||||
const originalResourceChangeListener = repository.onDidChangeOriginalResource(uri => this._onDidChangeOriginalResource.fire({ repository, uri }));
|
||||
|
||||
const checkForSubmodules = () => {
|
||||
if (repository.submodules.length > 10) {
|
||||
window.showWarningMessage(localize('too many submodules', "The '{0}' repository has {1} submodules which won't be opened automatically. You can still open each one individually by opening a file within.", path.basename(repository.root), repository.submodules.length));
|
||||
statusListener.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
this.scanSubmodules(repository);
|
||||
};
|
||||
|
||||
const statusListener = repository.onDidRunGitStatus(checkForSubmodules);
|
||||
checkForSubmodules();
|
||||
|
||||
const dispose = () => {
|
||||
disappearListener.dispose();
|
||||
changeListener.dispose();
|
||||
originalResourceChangeListener.dispose();
|
||||
statusListener.dispose();
|
||||
repository.dispose();
|
||||
|
||||
this.openRepositories = this.openRepositories.filter(e => e !== openRepository);
|
||||
@@ -223,6 +256,20 @@ export class Model {
|
||||
this._onDidOpenRepository.fire(repository);
|
||||
}
|
||||
|
||||
private scanSubmodules(repository: Repository): void {
|
||||
const shouldScanSubmodules = workspace
|
||||
.getConfiguration('git', Uri.file(repository.root))
|
||||
.get<boolean>('detectSubmodules') === true;
|
||||
|
||||
if (!shouldScanSubmodules) {
|
||||
return;
|
||||
}
|
||||
|
||||
repository.submodules
|
||||
.map(r => path.join(repository.root, r.path))
|
||||
.forEach(p => this.eventuallyScanPossibleGitRepository(p));
|
||||
}
|
||||
|
||||
close(repository: Repository): void {
|
||||
const openRepository = this.getOpenRepository(repository);
|
||||
|
||||
@@ -230,6 +277,7 @@ export class Model {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outputChannel.appendLine(`Close repository: ${repository.root}`);
|
||||
openRepository.dispose();
|
||||
}
|
||||
|
||||
@@ -238,7 +286,16 @@ export class Model {
|
||||
throw new Error(localize('no repositories', "There are no available repositories"));
|
||||
}
|
||||
|
||||
const picks = this.openRepositories.map(e => new RepositoryPick(e.repository));
|
||||
const picks = this.openRepositories.map((e, index) => new RepositoryPick(e.repository, index));
|
||||
const active = window.activeTextEditor;
|
||||
const repository = active && this.getRepository(active.document.fileName);
|
||||
const index = firstIndex(picks, pick => pick.repository === repository);
|
||||
|
||||
// Move repository pick containing the active text editor to appear first
|
||||
if (index > -1) {
|
||||
picks.unshift(...picks.splice(index, 1));
|
||||
}
|
||||
|
||||
const placeHolder = localize('pick repo', "Choose a repository");
|
||||
const pick = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
@@ -281,12 +338,21 @@ export class Model {
|
||||
resourcePath = hint.fsPath;
|
||||
}
|
||||
|
||||
for (const liveRepository of this.openRepositories) {
|
||||
const relativePath = path.relative(liveRepository.repository.root, resourcePath);
|
||||
|
||||
if (isDescendant(liveRepository.repository.root, resourcePath)) {
|
||||
return liveRepository;
|
||||
outer:
|
||||
for (const liveRepository of this.openRepositories.sort((a, b) => b.repository.root.length - a.repository.root.length)) {
|
||||
if (!isDescendant(liveRepository.repository.root, resourcePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const submodule of liveRepository.repository.submodules) {
|
||||
const submoduleRoot = path.join(liveRepository.repository.root, submodule.path);
|
||||
|
||||
if (isDescendant(submoduleRoot, resourcePath)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
return liveRepository;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -307,6 +373,20 @@ export class Model {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getRepositoryForSubmodule(submoduleUri: Uri): Repository | undefined {
|
||||
for (const repository of this.repositories) {
|
||||
for (const submodule of repository.submodules) {
|
||||
const submodulePath = path.join(repository.root, submodule.path);
|
||||
|
||||
if (submodulePath === submoduleUri.fsPath) {
|
||||
return repository;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
const openRepositories = [...this.openRepositories];
|
||||
openRepositories.forEach(r => r.dispose());
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento } from 'vscode';
|
||||
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError } from './git';
|
||||
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant } from './util';
|
||||
import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType } from 'vscode';
|
||||
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError, Submodule, DiffOptions } from './git';
|
||||
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util';
|
||||
import { memoize, throttle, debounce } from './decorators';
|
||||
import { toGitUri } from './uri';
|
||||
import { AutoFetcher } from './autofetch';
|
||||
@@ -105,7 +105,7 @@ export class Resource implements SourceControlResourceState {
|
||||
}
|
||||
};
|
||||
|
||||
private getIconPath(theme: string): Uri | undefined {
|
||||
private getIconPath(theme: string): Uri {
|
||||
switch (this.type) {
|
||||
case Status.INDEX_MODIFIED: return Resource.Icons[theme].Modified;
|
||||
case Status.MODIFIED: return Resource.Icons[theme].Modified;
|
||||
@@ -123,7 +123,6 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.DELETED_BY_US: return Resource.Icons[theme].Conflict;
|
||||
case Status.BOTH_ADDED: return Resource.Icons[theme].Conflict;
|
||||
case Status.BOTH_MODIFIED: return Resource.Icons[theme].Conflict;
|
||||
default: return void 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +181,7 @@ export class Resource implements SourceControlResourceState {
|
||||
return { strikeThrough, faded, tooltip, light, dark, letter, color, source: 'git.resource' /*todo@joh*/ };
|
||||
}
|
||||
|
||||
get letter(): string | undefined {
|
||||
get letter(): string {
|
||||
switch (this.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.MODIFIED:
|
||||
@@ -207,12 +206,10 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.BOTH_ADDED:
|
||||
case Status.BOTH_MODIFIED:
|
||||
return 'C';
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
get color(): ThemeColor | undefined {
|
||||
get color(): ThemeColor {
|
||||
switch (this.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.MODIFIED:
|
||||
@@ -235,8 +232,6 @@ export class Resource implements SourceControlResourceState {
|
||||
case Status.BOTH_ADDED:
|
||||
case Status.BOTH_MODIFIED:
|
||||
return new ThemeColor('gitDecoration.conflictingResourceForeground');
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +256,7 @@ export class Resource implements SourceControlResourceState {
|
||||
}
|
||||
}
|
||||
|
||||
get resourceDecoration(): DecorationData | undefined {
|
||||
get resourceDecoration(): DecorationData {
|
||||
const title = this.tooltip;
|
||||
const abbreviation = this.letter;
|
||||
const color = this.color;
|
||||
@@ -280,6 +275,7 @@ export class Resource implements SourceControlResourceState {
|
||||
|
||||
export enum Operation {
|
||||
Status = 'Status',
|
||||
Diff = 'Diff',
|
||||
Add = 'Add',
|
||||
RevertFiles = 'RevertFiles',
|
||||
Commit = 'Commit',
|
||||
@@ -301,7 +297,8 @@ export enum Operation {
|
||||
Tag = 'Tag',
|
||||
Stash = 'Stash',
|
||||
CheckIgnore = 'CheckIgnore',
|
||||
LSTree = 'LSTree'
|
||||
LSTree = 'LSTree',
|
||||
SubmoduleUpdate = 'SubmoduleUpdate'
|
||||
}
|
||||
|
||||
function isReadOnly(operation: Operation): boolean {
|
||||
@@ -330,6 +327,7 @@ function shouldShowProgress(operation: Operation): boolean {
|
||||
|
||||
export interface Operations {
|
||||
isIdle(): boolean;
|
||||
shouldShowProgress(): boolean;
|
||||
isRunning(operation: Operation): boolean;
|
||||
}
|
||||
|
||||
@@ -366,6 +364,18 @@ class OperationsImpl implements Operations {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
shouldShowProgress(): boolean {
|
||||
const operations = this.operations.keys();
|
||||
|
||||
for (const operation of operations) {
|
||||
if (shouldShowProgress(operation)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export interface CommitOptions {
|
||||
@@ -373,7 +383,6 @@ export interface CommitOptions {
|
||||
amend?: boolean;
|
||||
signoff?: boolean;
|
||||
signCommit?: boolean;
|
||||
defaultMsg?: string;
|
||||
}
|
||||
|
||||
export interface GitResourceGroup extends SourceControlResourceGroup {
|
||||
@@ -385,8 +394,33 @@ export interface OperationResult {
|
||||
error: any;
|
||||
}
|
||||
|
||||
class ProgressManager {
|
||||
|
||||
private disposable: IDisposable = EmptyDisposable;
|
||||
|
||||
constructor(repository: Repository) {
|
||||
const start = onceEvent(filterEvent(repository.onDidChangeOperations, () => repository.operations.shouldShowProgress()));
|
||||
const end = onceEvent(filterEvent(debounceEvent(repository.onDidChangeOperations, 300), () => !repository.operations.shouldShowProgress()));
|
||||
|
||||
const setup = () => {
|
||||
this.disposable = start(() => {
|
||||
const promise = eventToPromise(end).then(() => setup());
|
||||
window.withProgress({ location: ProgressLocation.SourceControl }, () => promise);
|
||||
});
|
||||
};
|
||||
|
||||
setup();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposable.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class Repository implements Disposable {
|
||||
|
||||
private static readonly InputValidationLength = 72;
|
||||
|
||||
private _onDidChangeRepository = new EventEmitter<Uri>();
|
||||
readonly onDidChangeRepository: Event<Uri> = this._onDidChangeRepository.event;
|
||||
|
||||
@@ -439,6 +473,11 @@ export class Repository implements Disposable {
|
||||
return this._remotes;
|
||||
}
|
||||
|
||||
private _submodules: Submodule[] = [];
|
||||
get submodules(): Submodule[] {
|
||||
return this._submodules;
|
||||
}
|
||||
|
||||
private _operations = new OperationsImpl();
|
||||
get operations(): Operations { return this._operations; }
|
||||
|
||||
@@ -474,7 +513,7 @@ export class Repository implements Disposable {
|
||||
|
||||
const onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
|
||||
const onRepositoryChange = filterEvent(onWorkspaceChange, uri => isDescendant(repository.root, uri.fsPath));
|
||||
const onRelevantRepositoryChange = filterEvent(onRepositoryChange, uri => !/\/\.git\/index\.lock$/.test(uri.path));
|
||||
const onRelevantRepositoryChange = filterEvent(onRepositoryChange, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path));
|
||||
onRelevantRepositoryChange(this.onFSChange, this, this.disposables);
|
||||
|
||||
const onRelevantGitChange = filterEvent(onRelevantRepositoryChange, uri => /\/\.git\//.test(uri.path));
|
||||
@@ -484,6 +523,7 @@ export class Repository implements Disposable {
|
||||
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)");
|
||||
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
|
||||
this._sourceControl.quickDiffProvider = this;
|
||||
this._sourceControl.inputBox.validateInput = this.validateInput.bind(this);
|
||||
this.disposables.push(this._sourceControl);
|
||||
|
||||
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes"));
|
||||
@@ -504,16 +544,56 @@ export class Repository implements Disposable {
|
||||
statusBar.onDidChange(() => this._sourceControl.statusBarCommands = statusBar.commands, null, this.disposables);
|
||||
this._sourceControl.statusBarCommands = statusBar.commands;
|
||||
|
||||
const progressManager = new ProgressManager(this);
|
||||
this.disposables.push(progressManager);
|
||||
|
||||
this.updateCommitTemplate();
|
||||
this.status();
|
||||
}
|
||||
|
||||
validateInput(text: string, position: number): SourceControlInputBoxValidation | undefined {
|
||||
const config = workspace.getConfiguration('git');
|
||||
const setting = config.get<'always' | 'warn' | 'off'>('inputValidation');
|
||||
|
||||
if (setting === 'off') {
|
||||
return;
|
||||
}
|
||||
|
||||
let start = 0, end;
|
||||
let match: RegExpExecArray | null;
|
||||
const regex = /\r?\n/g;
|
||||
|
||||
while ((match = regex.exec(text)) && position > match.index) {
|
||||
start = match.index + match[0].length;
|
||||
}
|
||||
|
||||
end = match ? match.index : text.length;
|
||||
|
||||
const line = text.substring(start, end);
|
||||
|
||||
if (line.length <= Repository.InputValidationLength) {
|
||||
if (setting !== 'always') {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
message: localize('commitMessageCountdown', "{0} characters left in current line", Repository.InputValidationLength - line.length),
|
||||
type: SourceControlInputBoxValidationType.Information
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
message: localize('commitMessageWarning', "{0} characters over {1} in current line", line.length - Repository.InputValidationLength, Repository.InputValidationLength),
|
||||
type: SourceControlInputBoxValidationType.Warning
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
provideOriginalResource(uri: Uri): Uri | undefined {
|
||||
if (uri.scheme !== 'file') {
|
||||
return;
|
||||
}
|
||||
|
||||
return toGitUri(uri, '', true);
|
||||
return toGitUri(uri, '', { replaceFileExtension: true });
|
||||
}
|
||||
|
||||
private async updateCommitTemplate(): Promise<void> {
|
||||
@@ -524,21 +604,15 @@ export class Repository implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
// @throttle
|
||||
// async init(): Promise<void> {
|
||||
// if (this.state !== State.NotAGitRepository) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// await this.git.init(this.workspaceRoot.fsPath);
|
||||
// await this.status();
|
||||
// }
|
||||
|
||||
@throttle
|
||||
async status(): Promise<void> {
|
||||
await this.run(Operation.Status);
|
||||
}
|
||||
|
||||
diff(path: string, options: DiffOptions = {}): Promise<string> {
|
||||
return this.run(Operation.Diff, () => this.repository.diff(path, options));
|
||||
}
|
||||
|
||||
async add(resources: Uri[]): Promise<void> {
|
||||
await this.run(Operation.Add, () => this.repository.add(resources.map(r => r.fsPath)));
|
||||
}
|
||||
@@ -567,8 +641,18 @@ export class Repository implements Disposable {
|
||||
await this.run(Operation.Clean, async () => {
|
||||
const toClean: string[] = [];
|
||||
const toCheckout: string[] = [];
|
||||
const submodulesToUpdate: string[] = [];
|
||||
|
||||
resources.forEach(r => {
|
||||
const fsPath = r.fsPath;
|
||||
|
||||
for (const submodule of this.submodules) {
|
||||
if (path.join(this.root, submodule.path) === fsPath) {
|
||||
submodulesToUpdate.push(fsPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const raw = r.toString();
|
||||
const scmResource = find(this.workingTreeGroup.resourceStates, sr => sr.resourceUri.toString() === raw);
|
||||
|
||||
@@ -579,11 +663,11 @@ export class Repository implements Disposable {
|
||||
switch (scmResource.type) {
|
||||
case Status.UNTRACKED:
|
||||
case Status.IGNORED:
|
||||
toClean.push(r.fsPath);
|
||||
toClean.push(fsPath);
|
||||
break;
|
||||
|
||||
default:
|
||||
toCheckout.push(r.fsPath);
|
||||
toCheckout.push(fsPath);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -598,6 +682,10 @@ export class Repository implements Disposable {
|
||||
promises.push(this.repository.checkout('', toCheckout));
|
||||
}
|
||||
|
||||
if (submodulesToUpdate.length > 0) {
|
||||
promises.push(this.repository.updateSubmodules(submodulesToUpdate));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
});
|
||||
}
|
||||
@@ -702,15 +790,15 @@ export class Repository implements Disposable {
|
||||
async buffer(ref: string, filePath: string): Promise<Buffer> {
|
||||
return await this.run(Operation.Show, async () => {
|
||||
const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/');
|
||||
const configFiles = workspace.getConfiguration('files', Uri.file(filePath));
|
||||
const encoding = configFiles.get<string>('encoding');
|
||||
// const configFiles = workspace.getConfiguration('files', Uri.file(filePath));
|
||||
// const encoding = configFiles.get<string>('encoding');
|
||||
|
||||
// TODO@joao: REsource config api
|
||||
return await this.repository.buffer(`${ref}:${relativePath}`);
|
||||
});
|
||||
}
|
||||
|
||||
lstree(ref: string, filePath: string): Promise<{ mode: number, object: string, size: number }> {
|
||||
lstree(ref: string, filePath: string): Promise<{ mode: string, object: string, size: number }> {
|
||||
return this.run(Operation.LSTree, () => this.repository.lstree(ref, filePath));
|
||||
}
|
||||
|
||||
@@ -780,7 +868,11 @@ export class Repository implements Disposable {
|
||||
// paths are separated by the null-character
|
||||
resolve(new Set<string>(data.split('\0')));
|
||||
} else {
|
||||
reject(new GitError({ stdout: data, stderr, exitCode }));
|
||||
if (/ is in submodule /.test(stderr)) {
|
||||
reject(new GitError({ stdout: data, stderr, exitCode, gitErrorCode: GitErrorCodes.IsInSubmodule }));
|
||||
} else {
|
||||
reject(new GitError({ stdout: data, stderr, exitCode }));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -807,37 +899,31 @@ export class Repository implements Disposable {
|
||||
throw new Error('Repository not initialized');
|
||||
}
|
||||
|
||||
const run = async () => {
|
||||
let error: any = null;
|
||||
let error: any = null;
|
||||
|
||||
this._operations.start(operation);
|
||||
this._onRunOperation.fire(operation);
|
||||
this._operations.start(operation);
|
||||
this._onRunOperation.fire(operation);
|
||||
|
||||
try {
|
||||
const result = await this.retryRun(runOperation);
|
||||
try {
|
||||
const result = await this.retryRun(runOperation);
|
||||
|
||||
if (!isReadOnly(operation)) {
|
||||
await this.updateModelState();
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (err) {
|
||||
error = err;
|
||||
|
||||
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
|
||||
this.state = RepositoryState.Disposed;
|
||||
}
|
||||
|
||||
throw err;
|
||||
} finally {
|
||||
this._operations.end(operation);
|
||||
this._onDidRunOperation.fire({ operation, error });
|
||||
if (!isReadOnly(operation)) {
|
||||
await this.updateModelState();
|
||||
}
|
||||
};
|
||||
|
||||
return shouldShowProgress(operation)
|
||||
? window.withProgress({ location: ProgressLocation.SourceControl }, run)
|
||||
: run();
|
||||
return result;
|
||||
} catch (err) {
|
||||
error = err;
|
||||
|
||||
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
|
||||
this.state = RepositoryState.Disposed;
|
||||
}
|
||||
|
||||
throw err;
|
||||
} finally {
|
||||
this._operations.end(operation);
|
||||
this._onDidRunOperation.fire({ operation, error });
|
||||
}
|
||||
}
|
||||
|
||||
private async retryRun<T>(runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> {
|
||||
@@ -868,10 +954,9 @@ export class Repository implements Disposable {
|
||||
this.isRepositoryHuge = didHitLimit;
|
||||
|
||||
if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) {
|
||||
const ok = { title: localize('ok', "OK"), isCloseAffordance: true };
|
||||
const neverAgain = { title: localize('neveragain', "Never Show Again") };
|
||||
const neverAgain = { title: localize('neveragain', "Don't Show Again") };
|
||||
|
||||
window.showWarningMessage(localize('huge', "The git repository at '{0}' has too many active changes, only a subset of Git features will be enabled.", this.repository.root), ok, neverAgain).then(result => {
|
||||
window.showWarningMessage(localize('huge', "The git repository at '{0}' has too many active changes, only a subset of Git features will be enabled.", this.repository.root), neverAgain).then(result => {
|
||||
if (result === neverAgain) {
|
||||
config.update('ignoreLimitWarning', true, false);
|
||||
}
|
||||
@@ -896,11 +981,12 @@ export class Repository implements Disposable {
|
||||
// noop
|
||||
}
|
||||
|
||||
const [refs, remotes] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes()]);
|
||||
const [refs, remotes, submodules] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes(), this.repository.getSubmodules()]);
|
||||
|
||||
this._HEAD = HEAD;
|
||||
this._refs = refs;
|
||||
this._remotes = remotes;
|
||||
this._submodules = submodules;
|
||||
|
||||
const index: Resource[] = [];
|
||||
const workingTree: Resource[] = [];
|
||||
@@ -922,10 +1008,8 @@ export class Repository implements Disposable {
|
||||
case 'UU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED, useIcons));
|
||||
}
|
||||
|
||||
let isModifiedInIndex = false;
|
||||
|
||||
switch (raw.x) {
|
||||
case 'M': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_MODIFIED, useIcons)); isModifiedInIndex = true; break;
|
||||
case 'M': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_MODIFIED, useIcons)); break;
|
||||
case 'A': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_ADDED, useIcons)); break;
|
||||
case 'D': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_DELETED, useIcons)); break;
|
||||
case 'R': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_RENAMED, useIcons, renameUri)); break;
|
||||
@@ -954,13 +1038,9 @@ export class Repository implements Disposable {
|
||||
|
||||
this._sourceControl.count = count;
|
||||
|
||||
// set context key
|
||||
let stateContextKey = '';
|
||||
|
||||
switch (this.state) {
|
||||
case RepositoryState.Idle: stateContextKey = 'idle'; break;
|
||||
case RepositoryState.Disposed: stateContextKey = 'norepo'; break;
|
||||
}
|
||||
// Disable `Discard All Changes` for "fresh" repositories
|
||||
// https://github.com/Microsoft/vscode/issues/43066
|
||||
commands.executeCommand('setContext', 'gitFreshRepository', !this._HEAD || !this._HEAD.commit);
|
||||
|
||||
this._onDidChangeStatus.fire();
|
||||
}
|
||||
|
||||
@@ -72,10 +72,16 @@ export function toLineRanges(selections: Selection[], textDocument: TextDocument
|
||||
return result;
|
||||
}
|
||||
|
||||
function getModifiedRange(textDocument: TextDocument, diff: LineChange): Range {
|
||||
return diff.modifiedEndLineNumber === 0
|
||||
? new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, textDocument.lineAt(diff.modifiedStartLineNumber).range.start)
|
||||
: new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, textDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);
|
||||
export function getModifiedRange(textDocument: TextDocument, diff: LineChange): Range {
|
||||
if (diff.modifiedEndLineNumber === 0) {
|
||||
if (diff.modifiedStartLineNumber === 0) {
|
||||
return new Range(textDocument.lineAt(diff.modifiedStartLineNumber).range.end, textDocument.lineAt(diff.modifiedStartLineNumber).range.start);
|
||||
} else {
|
||||
return new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, textDocument.lineAt(diff.modifiedStartLineNumber).range.start);
|
||||
}
|
||||
} else {
|
||||
return new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, textDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);
|
||||
}
|
||||
}
|
||||
|
||||
export function intersectDiffWithRange(textDocument: TextDocument, diff: LineChange, range: Range): LineChange | null {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import 'mocha';
|
||||
import { GitStatusParser } from '../git';
|
||||
import { GitStatusParser, parseGitmodules } from '../git';
|
||||
import * as assert from 'assert';
|
||||
|
||||
suite('git', () => {
|
||||
@@ -135,4 +135,44 @@ suite('git', () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('parseGitmodules', () => {
|
||||
test('empty', () => {
|
||||
assert.deepEqual(parseGitmodules(''), []);
|
||||
});
|
||||
|
||||
test('sample', () => {
|
||||
const sample = `[submodule "deps/spdlog"]
|
||||
path = deps/spdlog
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
`;
|
||||
|
||||
assert.deepEqual(parseGitmodules(sample), [
|
||||
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' }
|
||||
]);
|
||||
});
|
||||
|
||||
test('big', () => {
|
||||
const sample = `[submodule "deps/spdlog"]
|
||||
path = deps/spdlog
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
[submodule "deps/spdlog2"]
|
||||
path = deps/spdlog2
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
[submodule "deps/spdlog3"]
|
||||
path = deps/spdlog3
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
[submodule "deps/spdlog4"]
|
||||
path = deps/spdlog4
|
||||
url = https://github.com/gabime/spdlog4.git
|
||||
`;
|
||||
|
||||
assert.deepEqual(parseGitmodules(sample), [
|
||||
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' },
|
||||
{ name: 'deps/spdlog2', path: 'deps/spdlog2', url: 'https://github.com/gabime/spdlog.git' },
|
||||
{ name: 'deps/spdlog3', path: 'deps/spdlog3', url: 'https://github.com/gabime/spdlog.git' },
|
||||
{ name: 'deps/spdlog4', path: 'deps/spdlog4', url: 'https://github.com/gabime/spdlog4.git' }
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -7,20 +7,45 @@
|
||||
|
||||
import { Uri } from 'vscode';
|
||||
|
||||
export function fromGitUri(uri: Uri): { path: string; ref: string; } {
|
||||
export interface GitUriParams {
|
||||
path: string;
|
||||
ref: string;
|
||||
submoduleOf?: string;
|
||||
}
|
||||
|
||||
export function fromGitUri(uri: Uri): GitUriParams {
|
||||
return JSON.parse(uri.query);
|
||||
}
|
||||
|
||||
export interface GitUriOptions {
|
||||
replaceFileExtension?: boolean;
|
||||
submoduleOf?: string;
|
||||
}
|
||||
|
||||
// As a mitigation for extensions like ESLint showing warnings and errors
|
||||
// for git URIs, let's change the file extension of these uris to .git,
|
||||
// when `replaceFileExtension` is true.
|
||||
export function toGitUri(uri: Uri, ref: string, replaceFileExtension = false): Uri {
|
||||
export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Uri {
|
||||
const params: GitUriParams = {
|
||||
path: uri.fsPath,
|
||||
ref
|
||||
};
|
||||
|
||||
if (options.submoduleOf) {
|
||||
params.submoduleOf = options.submoduleOf;
|
||||
}
|
||||
|
||||
let path = uri.path;
|
||||
|
||||
if (options.replaceFileExtension) {
|
||||
path = `${path}.git`;
|
||||
} else if (options.submoduleOf) {
|
||||
path = `${path}.diff`;
|
||||
}
|
||||
|
||||
return uri.with({
|
||||
scheme: 'git',
|
||||
path: replaceFileExtension ? `${uri.path}.git` : uri.path,
|
||||
query: JSON.stringify({
|
||||
path: uri.fsPath,
|
||||
ref
|
||||
})
|
||||
path,
|
||||
query: JSON.stringify(params)
|
||||
});
|
||||
}
|
||||
@@ -34,6 +34,10 @@ export function combinedDisposable(disposables: IDisposable[]): IDisposable {
|
||||
|
||||
export const EmptyDisposable = toDisposable(() => null);
|
||||
|
||||
export function fireEvent<T>(event: Event<T>): Event<T> {
|
||||
return (listener, thisArgs = null, disposables?) => event(_ => listener.call(thisArgs), null, disposables);
|
||||
}
|
||||
|
||||
export function mapEvent<I, O>(event: Event<I>, map: (i: I) => O): Event<O> {
|
||||
return (listener, thisArgs = null, disposables?) => event(i => listener.call(thisArgs, map(i)), null, disposables);
|
||||
}
|
||||
@@ -69,6 +73,16 @@ export function onceEvent<T>(event: Event<T>): Event<T> {
|
||||
};
|
||||
}
|
||||
|
||||
export function debounceEvent<T>(event: Event<T>, delay: number): Event<T> {
|
||||
return (listener, thisArgs = null, disposables?) => {
|
||||
let timer: NodeJS.Timer;
|
||||
return event(e => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => listener.call(thisArgs, e), delay);
|
||||
}, null, disposables);
|
||||
};
|
||||
}
|
||||
|
||||
export function eventToPromise<T>(event: Event<T>): Promise<T> {
|
||||
return new Promise<T>(c => onceEvent(event)(c));
|
||||
}
|
||||
@@ -116,6 +130,10 @@ export function groupBy<T>(arr: T[], fn: (el: T) => string): { [key: string]: T[
|
||||
}, Object.create(null));
|
||||
}
|
||||
|
||||
export function denodeify<A, B, C, R>(fn: Function): (a: A, b: B, c: C) => Promise<R>;
|
||||
export function denodeify<A, B, R>(fn: Function): (a: A, b: B) => Promise<R>;
|
||||
export function denodeify<A, R>(fn: Function): (a: A) => Promise<R>;
|
||||
export function denodeify<R>(fn: Function): (...args: any[]) => Promise<R>;
|
||||
export function denodeify<R>(fn: Function): (...args: any[]) => Promise<R> {
|
||||
return (...args) => new Promise<R>((c, e) => fn(...args, (err: any, r: any) => err ? e(err) : c(r)));
|
||||
}
|
||||
@@ -177,6 +195,16 @@ export function uniqueFilter<T>(keyFn: (t: T) => string): (t: T) => boolean {
|
||||
};
|
||||
}
|
||||
|
||||
export function firstIndex<T>(array: T[], fn: (t: T) => boolean): number {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (fn(array[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function find<T>(array: T[], fn: (t: T) => boolean): T | undefined {
|
||||
let result: T | undefined = undefined;
|
||||
|
||||
@@ -211,7 +239,7 @@ export async function grep(filename: string, pattern: RegExp): Promise<boolean>
|
||||
export function readBytes(stream: Readable, bytes: number): Promise<Buffer> {
|
||||
return new Promise<Buffer>((complete, error) => {
|
||||
let done = false;
|
||||
let buffer = new Buffer(bytes);
|
||||
let buffer = Buffer.allocUnsafe(bytes);
|
||||
let bytesRead = 0;
|
||||
|
||||
stream.on('data', (data: Buffer) => {
|
||||
|
||||
160
extensions/git/syntaxes/diff.tmLanguage.json
Normal file
160
extensions/git/syntaxes/diff.tmLanguage.json
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"information_for_contributors": [
|
||||
"This file has been converted from https://github.com/textmate/diff.tmbundle/blob/master/Syntaxes/Diff.plist",
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/textmate/diff.tmbundle/commit/0593bb775eab1824af97ef2172fd38822abd97d7",
|
||||
"name": "Diff",
|
||||
"scopeName": "source.diff",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.separator.diff"
|
||||
}
|
||||
},
|
||||
"match": "^((\\*{15})|(={67})|(-{3}))$\\n?",
|
||||
"name": "meta.separator.diff"
|
||||
},
|
||||
{
|
||||
"match": "^\\d+(,\\d+)*(a|d|c)\\d+(,\\d+)*$\\n?",
|
||||
"name": "meta.diff.range.normal"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.range.diff"
|
||||
},
|
||||
"2": {
|
||||
"name": "meta.toc-list.line-number.diff"
|
||||
},
|
||||
"3": {
|
||||
"name": "punctuation.definition.range.diff"
|
||||
}
|
||||
},
|
||||
"match": "^(@@)\\s*(.+?)\\s*(@@)($\\n?)?",
|
||||
"name": "meta.diff.range.unified"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"3": {
|
||||
"name": "punctuation.definition.range.diff"
|
||||
},
|
||||
"4": {
|
||||
"name": "punctuation.definition.range.diff"
|
||||
},
|
||||
"6": {
|
||||
"name": "punctuation.definition.range.diff"
|
||||
},
|
||||
"7": {
|
||||
"name": "punctuation.definition.range.diff"
|
||||
}
|
||||
},
|
||||
"match": "^(((\\-{3}) .+ (\\-{4}))|((\\*{3}) .+ (\\*{4})))$\\n?",
|
||||
"name": "meta.diff.range.context"
|
||||
},
|
||||
{
|
||||
"match": "^diff --git a/.*$\\n?",
|
||||
"name": "meta.diff.header.git"
|
||||
},
|
||||
{
|
||||
"match": "^diff (-|\\S+\\s+\\S+).*$\\n?",
|
||||
"name": "meta.diff.header.command"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"4": {
|
||||
"name": "punctuation.definition.from-file.diff"
|
||||
},
|
||||
"6": {
|
||||
"name": "punctuation.definition.from-file.diff"
|
||||
},
|
||||
"7": {
|
||||
"name": "punctuation.definition.from-file.diff"
|
||||
}
|
||||
},
|
||||
"match": "(^(((-{3}) .+)|((\\*{3}) .+))$\\n?|^(={4}) .+(?= - ))",
|
||||
"name": "meta.diff.header.from-file"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"2": {
|
||||
"name": "punctuation.definition.to-file.diff"
|
||||
},
|
||||
"3": {
|
||||
"name": "punctuation.definition.to-file.diff"
|
||||
},
|
||||
"4": {
|
||||
"name": "punctuation.definition.to-file.diff"
|
||||
}
|
||||
},
|
||||
"match": "(^(\\+{3}) .+$\\n?| (-) .* (={4})$\\n?)",
|
||||
"name": "meta.diff.header.to-file"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"3": {
|
||||
"name": "punctuation.definition.inserted.diff"
|
||||
},
|
||||
"6": {
|
||||
"name": "punctuation.definition.inserted.diff"
|
||||
}
|
||||
},
|
||||
"match": "^(((>)( .*)?)|((\\+).*))$\\n?",
|
||||
"name": "markup.inserted.diff"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.changed.diff"
|
||||
}
|
||||
},
|
||||
"match": "^(!).*$\\n?",
|
||||
"name": "markup.changed.diff"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"3": {
|
||||
"name": "punctuation.definition.deleted.diff"
|
||||
},
|
||||
"6": {
|
||||
"name": "punctuation.definition.deleted.diff"
|
||||
}
|
||||
},
|
||||
"match": "^(((<)( .*)?)|((-).*))$\\n?",
|
||||
"name": "markup.deleted.diff"
|
||||
},
|
||||
{
|
||||
"begin": "^(#)",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.diff"
|
||||
}
|
||||
},
|
||||
"comment": "Git produces unified diffs with embedded comments\"",
|
||||
"end": "\\n",
|
||||
"name": "comment.line.number-sign.diff"
|
||||
},
|
||||
{
|
||||
"match": "^index [0-9a-f]{7,40}\\.\\.[0-9a-f]{7,40}.*$\\n?",
|
||||
"name": "meta.diff.index.git"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.separator.key-value.diff"
|
||||
},
|
||||
"2": {
|
||||
"name": "meta.toc-list.file-name.diff"
|
||||
}
|
||||
},
|
||||
"match": "^Index(:) (.+)$\\n?",
|
||||
"name": "meta.diff.index"
|
||||
},
|
||||
{
|
||||
"match": "^Only in .*: .*$\\n?",
|
||||
"name": "meta.diff.only-in"
|
||||
}
|
||||
]
|
||||
}
|
||||
141
extensions/git/syntaxes/git-commit.tmLanguage.json
Normal file
141
extensions/git/syntaxes/git-commit.tmLanguage.json
Normal file
@@ -0,0 +1,141 @@
|
||||
{
|
||||
"information_for_contributors": [
|
||||
"This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Commit%20Message.tmLanguage",
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/textmate/git.tmbundle/commit/93897a78c6e52bef13dadc0d4091d203c5facb40",
|
||||
"name": "Git Commit Message",
|
||||
"scopeName": "text.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\A(?!# Please enter the commit message)",
|
||||
"end": "^(?=# Please enter the commit message)",
|
||||
"name": "meta.scope.message.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\A(?=#)",
|
||||
"end": "^(?!#)",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#comment"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "^(?!# Please enter the commit message)",
|
||||
"end": "^(?=# Please enter the commit message)",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "\\G",
|
||||
"end": "^(?!\\G)",
|
||||
"name": "meta.scope.subject.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "keyword.other.$2.git-commit"
|
||||
}
|
||||
},
|
||||
"match": "\\G((fixup|squash)!)\\s*"
|
||||
},
|
||||
{
|
||||
"match": ".{73,}$",
|
||||
"name": "invalid.illegal.line-too-long.git-commit"
|
||||
},
|
||||
{
|
||||
"match": ".{51,}$",
|
||||
"name": "invalid.deprecated.line-too-long.git-commit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "^(?!# Please enter the commit message)",
|
||||
"end": "^(?=# Please enter the commit message)",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#comment"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"begin": "^(?=# Please enter the commit message)",
|
||||
"end": "\\z",
|
||||
"name": "meta.scope.metadata.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#metadata"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"comment": {
|
||||
"begin": "^(#)",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.git-commit"
|
||||
}
|
||||
},
|
||||
"end": "\\n",
|
||||
"name": "comment.line.number-sign.git-commit"
|
||||
},
|
||||
"metadata": {
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "(?=^# Changes to be committed:)",
|
||||
"end": "(?!\\G)((?=^# \\w)|(?!^#))",
|
||||
"patterns": [
|
||||
{
|
||||
"begin": "(^[ \\t]+)?(?=#)",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.whitespace.comment.leading.git-commit"
|
||||
}
|
||||
},
|
||||
"contentName": "comment.line.number-sign.git-commit",
|
||||
"end": "(?!\\G)^",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "\\G#",
|
||||
"name": "punctuation.definition.comment.git-commit"
|
||||
},
|
||||
{
|
||||
"match": "((modified|renamed):.*)$\\n?",
|
||||
"name": "markup.changed.git-commit"
|
||||
},
|
||||
{
|
||||
"match": "(new file:.*)$\\n?",
|
||||
"name": "markup.inserted.git-commit"
|
||||
},
|
||||
{
|
||||
"match": "(deleted:.*)$\\n?",
|
||||
"name": "markup.deleted.git-commit"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"include": "#comment"
|
||||
},
|
||||
{
|
||||
"begin": "(?=diff\\ \\-\\-git)",
|
||||
"comment": "diff presented at the end of the commit message when using commit -v.",
|
||||
"contentName": "source.diff",
|
||||
"end": "\\z",
|
||||
"name": "meta.embedded.diff.git-commit",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "source.diff"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
36
extensions/git/syntaxes/git-rebase.tmLanguage.json
Normal file
36
extensions/git/syntaxes/git-rebase.tmLanguage.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"information_for_contributors": [
|
||||
"This file has been converted from https://github.com/textmate/git.tmbundle/blob/master/Syntaxes/Git%20Rebase%20Message.tmLanguage",
|
||||
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
|
||||
"Once accepted there, we are happy to receive an update request."
|
||||
],
|
||||
"version": "https://github.com/textmate/git.tmbundle/commit/d1db42c2d71948662098183a6df519fb53a7a15b",
|
||||
"name": "Git Rebase Message",
|
||||
"scopeName": "text.git-rebase",
|
||||
"patterns": [
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.comment.git-rebase"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*(#).*$\\n?",
|
||||
"name": "comment.line.number-sign.git-rebase"
|
||||
},
|
||||
{
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "support.function.git-rebase"
|
||||
},
|
||||
"2": {
|
||||
"name": "constant.sha.git-rebase"
|
||||
},
|
||||
"3": {
|
||||
"name": "meta.commit-message.git-rebase"
|
||||
}
|
||||
},
|
||||
"match": "^\\s*(pick|p|reword|r|edit|e|squash|s|fixup|f|exec|x|drop|d)\\s+([0-9a-f]+)\\s+(.*)$",
|
||||
"name": "meta.commit-command.git-rebase"
|
||||
}
|
||||
]
|
||||
}
|
||||
13
extensions/git/test/colorize-fixtures/COMMIT_EDITMSG
Normal file
13
extensions/git/test/colorize-fixtures/COMMIT_EDITMSG
Normal file
@@ -0,0 +1,13 @@
|
||||
This is the summary line. It can't be too long.
|
||||
After I can write a much more detailed description without quite the same restrictions on length.
|
||||
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch master
|
||||
# Your branch is up-to-date with 'origin/master'.
|
||||
#
|
||||
# Changes to be committed:
|
||||
# deleted: README.md
|
||||
# modified: index.less
|
||||
# new file: spec/COMMIT_EDITMSG
|
||||
#
|
||||
7
extensions/git/test/colorize-fixtures/example.diff
Normal file
7
extensions/git/test/colorize-fixtures/example.diff
Normal file
@@ -0,0 +1,7 @@
|
||||
diff --git a/helloworld.txt b/helloworld.txt
|
||||
index e4f37c4..557db03 100644
|
||||
--- a/helloworld.txt
|
||||
+++ b/helloworld.txt
|
||||
@@ -1 +1 @@
|
||||
-Hello world
|
||||
+Hello World
|
||||
15
extensions/git/test/colorize-fixtures/git-rebase-todo
Normal file
15
extensions/git/test/colorize-fixtures/git-rebase-todo
Normal file
@@ -0,0 +1,15 @@
|
||||
pick 1fc6c95 Patch A
|
||||
squash fa39187 Something to add to patch A
|
||||
pick 7b36971 Something to move before patch B
|
||||
pick 6b2481b Patch B
|
||||
fixup c619268 A fix for Patch B
|
||||
edit dd1475d Something I want to split
|
||||
reword 4ca2acc i cant' typ goods
|
||||
|
||||
# Commands:
|
||||
# p, pick = use commit
|
||||
# r, reword = use commit, but edit the commit message
|
||||
# e, edit = use commit, but stop for amending
|
||||
# s, squash = use commit, but meld into previous commit
|
||||
# f, fixup = like "squash", but discard this commit's log message
|
||||
# x, exec = run command (the rest of the line) using shell
|
||||
255
extensions/git/test/colorize-results/COMMIT_EDITMSG.json
Normal file
255
extensions/git/test/colorize-results/COMMIT_EDITMSG.json
Normal file
@@ -0,0 +1,255 @@
|
||||
[
|
||||
{
|
||||
"c": "This is the summary line. It can't be too long.",
|
||||
"t": "text.git-commit meta.scope.message.git-commit meta.scope.subject.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "After I can write a much more detailed description without quite the same restrictions on length.",
|
||||
"t": "text.git-commit meta.scope.message.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " Please enter the commit message for your changes. Lines starting",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " with '#' will be ignored, and an empty message aborts the commit.",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " On branch master",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " Your branch is up-to-date with 'origin/master'.",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " Changes to be committed:",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "\t",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "deleted: README.md",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.deleted.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "markup.deleted: #CE9178",
|
||||
"light_plus": "markup.deleted: #A31515",
|
||||
"dark_vs": "markup.deleted: #CE9178",
|
||||
"light_vs": "markup.deleted: #A31515",
|
||||
"hc_black": "markup.deleted: #CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "\t",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "modified: index.less",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.changed.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "markup.changed: #569CD6",
|
||||
"light_plus": "markup.changed: #0451A5",
|
||||
"dark_vs": "markup.changed: #569CD6",
|
||||
"light_vs": "markup.changed: #0451A5",
|
||||
"hc_black": "markup.changed: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "\t",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "new file: spec/COMMIT_EDITMSG",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit markup.inserted.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "markup.inserted: #B5CEA8",
|
||||
"light_plus": "markup.inserted: #09885A",
|
||||
"dark_vs": "markup.inserted: #B5CEA8",
|
||||
"light_vs": "markup.inserted: #09885A",
|
||||
"hc_black": "markup.inserted: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-commit meta.scope.metadata.git-commit comment.line.number-sign.git-commit punctuation.definition.comment.git-commit",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
}
|
||||
]
|
||||
167
extensions/git/test/colorize-results/example_diff.json
Normal file
167
extensions/git/test/colorize-results/example_diff.json
Normal file
@@ -0,0 +1,167 @@
|
||||
[
|
||||
{
|
||||
"c": "diff --git a/helloworld.txt b/helloworld.txt",
|
||||
"t": "source.diff meta.diff.header.git",
|
||||
"r": {
|
||||
"dark_plus": "meta.diff.header: #569CD6",
|
||||
"light_plus": "meta.diff.header: #000080",
|
||||
"dark_vs": "meta.diff.header: #569CD6",
|
||||
"light_vs": "meta.diff.header: #000080",
|
||||
"hc_black": "meta.diff.header: #000080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "index e4f37c4..557db03 100644",
|
||||
"t": "source.diff meta.diff.index.git",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "---",
|
||||
"t": "source.diff meta.diff.header.from-file punctuation.definition.from-file.diff",
|
||||
"r": {
|
||||
"dark_plus": "meta.diff.header: #569CD6",
|
||||
"light_plus": "meta.diff.header: #000080",
|
||||
"dark_vs": "meta.diff.header: #569CD6",
|
||||
"light_vs": "meta.diff.header: #000080",
|
||||
"hc_black": "meta.diff.header: #000080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " a/helloworld.txt",
|
||||
"t": "source.diff meta.diff.header.from-file",
|
||||
"r": {
|
||||
"dark_plus": "meta.diff.header: #569CD6",
|
||||
"light_plus": "meta.diff.header: #000080",
|
||||
"dark_vs": "meta.diff.header: #569CD6",
|
||||
"light_vs": "meta.diff.header: #000080",
|
||||
"hc_black": "meta.diff.header: #000080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "+++",
|
||||
"t": "source.diff meta.diff.header.to-file punctuation.definition.to-file.diff",
|
||||
"r": {
|
||||
"dark_plus": "meta.diff.header: #569CD6",
|
||||
"light_plus": "meta.diff.header: #000080",
|
||||
"dark_vs": "meta.diff.header: #569CD6",
|
||||
"light_vs": "meta.diff.header: #000080",
|
||||
"hc_black": "meta.diff.header: #000080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " b/helloworld.txt",
|
||||
"t": "source.diff meta.diff.header.to-file",
|
||||
"r": {
|
||||
"dark_plus": "meta.diff.header: #569CD6",
|
||||
"light_plus": "meta.diff.header: #000080",
|
||||
"dark_vs": "meta.diff.header: #569CD6",
|
||||
"light_vs": "meta.diff.header: #000080",
|
||||
"hc_black": "meta.diff.header: #000080"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "@@",
|
||||
"t": "source.diff meta.diff.range.unified punctuation.definition.range.diff",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.diff meta.diff.range.unified",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "-1 +1",
|
||||
"t": "source.diff meta.diff.range.unified meta.toc-list.line-number.diff",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.diff meta.diff.range.unified",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "@@",
|
||||
"t": "source.diff meta.diff.range.unified punctuation.definition.range.diff",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "-",
|
||||
"t": "source.diff markup.deleted.diff punctuation.definition.deleted.diff",
|
||||
"r": {
|
||||
"dark_plus": "markup.deleted: #CE9178",
|
||||
"light_plus": "markup.deleted: #A31515",
|
||||
"dark_vs": "markup.deleted: #CE9178",
|
||||
"light_vs": "markup.deleted: #A31515",
|
||||
"hc_black": "markup.deleted: #CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Hello world",
|
||||
"t": "source.diff markup.deleted.diff",
|
||||
"r": {
|
||||
"dark_plus": "markup.deleted: #CE9178",
|
||||
"light_plus": "markup.deleted: #A31515",
|
||||
"dark_vs": "markup.deleted: #CE9178",
|
||||
"light_vs": "markup.deleted: #A31515",
|
||||
"hc_black": "markup.deleted: #CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "+",
|
||||
"t": "source.diff markup.inserted.diff punctuation.definition.inserted.diff",
|
||||
"r": {
|
||||
"dark_plus": "markup.inserted: #B5CEA8",
|
||||
"light_plus": "markup.inserted: #09885A",
|
||||
"dark_vs": "markup.inserted: #B5CEA8",
|
||||
"light_vs": "markup.inserted: #09885A",
|
||||
"hc_black": "markup.inserted: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Hello World",
|
||||
"t": "source.diff markup.inserted.diff",
|
||||
"r": {
|
||||
"dark_plus": "markup.inserted: #B5CEA8",
|
||||
"light_plus": "markup.inserted: #09885A",
|
||||
"dark_vs": "markup.inserted: #B5CEA8",
|
||||
"light_vs": "markup.inserted: #09885A",
|
||||
"hc_black": "markup.inserted: #B5CEA8"
|
||||
}
|
||||
}
|
||||
]
|
||||
541
extensions/git/test/colorize-results/git-rebase-todo.json
Normal file
541
extensions/git/test/colorize-results/git-rebase-todo.json
Normal file
@@ -0,0 +1,541 @@
|
||||
[
|
||||
{
|
||||
"c": "pick",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "1fc6c95",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Patch A",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "squash",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "fa39187",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Something to add to patch A",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "pick",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "7b36971",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Something to move before patch B",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "pick",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "6b2481b",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Patch B",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "fixup",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "c619268",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "A fix for Patch B",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "edit",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "dd1475d",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "Something I want to split",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "reword",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase support.function.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "support.function.git-rebase: #9CDCFE",
|
||||
"light_plus": "support.function.git-rebase: #0451A5",
|
||||
"dark_vs": "support.function.git-rebase: #9CDCFE",
|
||||
"light_vs": "support.function.git-rebase: #0451A5",
|
||||
"hc_black": "support.function.git-rebase: #D4D4D4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "4ca2acc",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase constant.sha.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_plus": "constant.sha.git-rebase: #09885A",
|
||||
"dark_vs": "constant.sha.git-rebase: #B5CEA8",
|
||||
"light_vs": "constant.sha.git-rebase: #09885A",
|
||||
"hc_black": "constant.sha.git-rebase: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "i cant' typ goods",
|
||||
"t": "text.git-rebase meta.commit-command.git-rebase meta.commit-message.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " Commands:",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " p, pick = use commit",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " r, reword = use commit, but edit the commit message",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " e, edit = use commit, but stop for amending",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " s, squash = use commit, but meld into previous commit",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " f, fixup = like \"squash\", but discard this commit's log message",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase punctuation.definition.comment.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " x, exec = run command (the rest of the line) using shell",
|
||||
"t": "text.git-rebase comment.line.number-sign.git-rebase",
|
||||
"r": {
|
||||
"dark_plus": "comment: #608B4E",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #608B4E",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -10,7 +10,8 @@
|
||||
"./node_modules/@types"
|
||||
],
|
||||
"strict": true,
|
||||
"experimentalDecorators": true
|
||||
"experimentalDecorators": true,
|
||||
"noUnusedLocals": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
|
||||
@@ -30,9 +30,13 @@
|
||||
version "1.0.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
|
||||
|
||||
applicationinsights@0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-0.18.0.tgz#162ebb48a383408bc4de44db32b417307f45bbc1"
|
||||
applicationinsights@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.1.tgz#53446b830fe8d5d619eee2a278b31d3d25030927"
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
zone.js "0.7.6"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -69,6 +73,16 @@ debug@2.6.8:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
diagnostic-channel-publishers@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||
|
||||
diagnostic-channel@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
diff@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
||||
@@ -229,22 +243,25 @@ path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
|
||||
supports-color@3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
|
||||
dependencies:
|
||||
has-flag "^1.0.0"
|
||||
|
||||
vscode-extension-telemetry@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz#2261bff986b6690a6f1f746a45ac5bd1f85d29e0"
|
||||
vscode-extension-telemetry@0.0.15:
|
||||
version "0.0.15"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.15.tgz#685c32f3b67e8fb85ba689c1d7f88ff90ff87856"
|
||||
dependencies:
|
||||
applicationinsights "0.18.0"
|
||||
winreg "1.2.3"
|
||||
applicationinsights "1.0.1"
|
||||
|
||||
vscode-nls@2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
|
||||
vscode-nls@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.1.tgz#b1f3e04e8a94a715d5a7bcbc8339c51e6d74ca51"
|
||||
|
||||
which@^1.3.0:
|
||||
version "1.3.0"
|
||||
@@ -252,10 +269,10 @@ which@^1.3.0:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
winreg@1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.3.tgz#93ad116b2696da87d58f7265a8fcea5254a965d5"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
zone.js@0.7.6:
|
||||
version "0.7.6"
|
||||
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"
|
||||
|
||||
Reference in New Issue
Block a user