Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
c85718eb
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c85718eb
编写于
7月 14, 2020
作者:
J
João Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
git: remote source provider picker command
fixes #102394
上级
78aeeac9
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
199 addition
and
199 deletion
+199
-199
extensions/git/src/api/api1.ts
extensions/git/src/api/api1.ts
+50
-38
extensions/git/src/api/extension.ts
extensions/git/src/api/extension.ts
+4
-0
extensions/git/src/commands.ts
extensions/git/src/commands.ts
+11
-160
extensions/git/src/main.ts
extensions/git/src/main.ts
+1
-1
extensions/git/src/remoteSource.ts
extensions/git/src/remoteSource.ts
+133
-0
未找到文件。
extensions/git/src/api/api1.ts
浏览文件 @
c85718eb
...
...
@@ -5,10 +5,12 @@
import
{
Model
}
from
'
../model
'
;
import
{
Repository
as
BaseRepository
,
Resource
}
from
'
../repository
'
;
import
{
InputBox
,
Git
,
API
,
Repository
,
Remote
,
RepositoryState
,
Branch
,
Ref
,
Submodule
,
Commit
,
Change
,
RepositoryUIState
,
Status
,
LogOptions
,
APIState
,
CommitOptions
,
GitExtension
,
RefType
,
RemoteSourceProvider
,
CredentialsProvider
,
BranchQuery
}
from
'
./git
'
;
import
{
InputBox
,
Git
,
API
,
Repository
,
Remote
,
RepositoryState
,
Branch
,
Ref
,
Submodule
,
Commit
,
Change
,
RepositoryUIState
,
Status
,
LogOptions
,
APIState
,
CommitOptions
,
RefType
,
RemoteSourceProvider
,
CredentialsProvider
,
BranchQuery
}
from
'
./git
'
;
import
{
Event
,
SourceControlInputBox
,
Uri
,
SourceControl
,
Disposable
,
commands
}
from
'
vscode
'
;
import
{
mapEvent
}
from
'
../util
'
;
import
{
toGitUri
}
from
'
../uri
'
;
import
{
pickRemoteSource
,
PickRemoteSourceOptions
}
from
'
../remoteSource
'
;
import
{
GitExtensionImpl
}
from
'
./extension
'
;
class
ApiInputBox
implements
InputBox
{
set
value
(
value
:
string
)
{
this
.
_inputBox
.
value
=
value
;
}
...
...
@@ -308,41 +310,51 @@ function getStatus(status: Status): string {
return
'
UNKNOWN
'
;
}
export
function
registerAPICommands
(
extension
:
GitExtension
):
Disposable
{
return
Disposable
.
from
(
commands
.
registerCommand
(
'
git.api.getRepositories
'
,
()
=>
{
const
api
=
extension
.
getAPI
(
1
);
return
api
.
repositories
.
map
(
r
=>
r
.
rootUri
.
toString
());
}),
commands
.
registerCommand
(
'
git.api.getRepositoryState
'
,
(
uri
:
string
)
=>
{
const
api
=
extension
.
getAPI
(
1
);
const
repository
=
api
.
getRepository
(
Uri
.
parse
(
uri
));
if
(
!
repository
)
{
return
null
;
}
const
state
=
repository
.
state
;
const
ref
=
(
ref
:
Ref
|
undefined
)
=>
(
ref
&&
{
...
ref
,
type
:
getRefType
(
ref
.
type
)
});
const
change
=
(
change
:
Change
)
=>
({
uri
:
change
.
uri
.
toString
(),
originalUri
:
change
.
originalUri
.
toString
(),
renameUri
:
change
.
renameUri
?.
toString
(),
status
:
getStatus
(
change
.
status
)
});
return
{
HEAD
:
ref
(
state
.
HEAD
),
refs
:
state
.
refs
.
map
(
ref
),
remotes
:
state
.
remotes
,
submodules
:
state
.
submodules
,
rebaseCommit
:
state
.
rebaseCommit
,
mergeChanges
:
state
.
mergeChanges
.
map
(
change
),
indexChanges
:
state
.
indexChanges
.
map
(
change
),
workingTreeChanges
:
state
.
workingTreeChanges
.
map
(
change
)
};
})
);
export
function
registerAPICommands
(
extension
:
GitExtensionImpl
):
Disposable
{
const
disposables
:
Disposable
[]
=
[];
disposables
.
push
(
commands
.
registerCommand
(
'
git.api.getRepositories
'
,
()
=>
{
const
api
=
extension
.
getAPI
(
1
);
return
api
.
repositories
.
map
(
r
=>
r
.
rootUri
.
toString
());
}));
disposables
.
push
(
commands
.
registerCommand
(
'
git.api.getRepositoryState
'
,
(
uri
:
string
)
=>
{
const
api
=
extension
.
getAPI
(
1
);
const
repository
=
api
.
getRepository
(
Uri
.
parse
(
uri
));
if
(
!
repository
)
{
return
null
;
}
const
state
=
repository
.
state
;
const
ref
=
(
ref
:
Ref
|
undefined
)
=>
(
ref
&&
{
...
ref
,
type
:
getRefType
(
ref
.
type
)
});
const
change
=
(
change
:
Change
)
=>
({
uri
:
change
.
uri
.
toString
(),
originalUri
:
change
.
originalUri
.
toString
(),
renameUri
:
change
.
renameUri
?.
toString
(),
status
:
getStatus
(
change
.
status
)
});
return
{
HEAD
:
ref
(
state
.
HEAD
),
refs
:
state
.
refs
.
map
(
ref
),
remotes
:
state
.
remotes
,
submodules
:
state
.
submodules
,
rebaseCommit
:
state
.
rebaseCommit
,
mergeChanges
:
state
.
mergeChanges
.
map
(
change
),
indexChanges
:
state
.
indexChanges
.
map
(
change
),
workingTreeChanges
:
state
.
workingTreeChanges
.
map
(
change
)
};
}));
disposables
.
push
(
commands
.
registerCommand
(
'
git.api.getRemoteSources
'
,
(
opts
?:
PickRemoteSourceOptions
)
=>
{
if
(
!
extension
.
model
)
{
return
;
}
return
pickRemoteSource
(
extension
.
model
,
opts
);
}));
return
Disposable
.
from
(...
disposables
);
}
extensions/git/src/api/extension.ts
浏览文件 @
c85718eb
...
...
@@ -42,6 +42,10 @@ export class GitExtensionImpl implements GitExtension {
this
.
_onDidChangeEnablement
.
fire
(
this
.
enabled
);
}
get
model
():
Model
|
undefined
{
return
this
.
_model
;
}
constructor
(
model
?:
Model
)
{
if
(
model
)
{
this
.
enabled
=
true
;
...
...
extensions/git/src/commands.ts
浏览文件 @
c85718eb
...
...
@@ -6,10 +6,10 @@
import
{
lstat
,
Stats
}
from
'
fs
'
;
import
*
as
os
from
'
os
'
;
import
*
as
path
from
'
path
'
;
import
{
commands
,
Disposable
,
LineChange
,
MessageOptions
,
OutputChannel
,
Position
,
ProgressLocation
,
QuickPickItem
,
Range
,
SourceControlResourceState
,
TextDocumentShowOptions
,
TextEditor
,
Uri
,
ViewColumn
,
window
,
workspace
,
WorkspaceEdit
,
WorkspaceFolder
,
TimelineItem
,
env
,
QuickPick
}
from
'
vscode
'
;
import
{
commands
,
Disposable
,
LineChange
,
MessageOptions
,
OutputChannel
,
Position
,
ProgressLocation
,
QuickPickItem
,
Range
,
SourceControlResourceState
,
TextDocumentShowOptions
,
TextEditor
,
Uri
,
ViewColumn
,
window
,
workspace
,
WorkspaceEdit
,
WorkspaceFolder
,
TimelineItem
,
env
}
from
'
vscode
'
;
import
TelemetryReporter
from
'
vscode-extension-telemetry
'
;
import
*
as
nls
from
'
vscode-nls
'
;
import
{
Branch
,
GitErrorCodes
,
Ref
,
RefType
,
Status
,
CommitOptions
,
RemoteSourceProvider
,
RemoteSource
}
from
'
./api/git
'
;
import
{
Branch
,
GitErrorCodes
,
Ref
,
RefType
,
Status
,
CommitOptions
,
RemoteSourceProvider
}
from
'
./api/git
'
;
import
{
ForcePushMode
,
Git
,
Stash
}
from
'
./git
'
;
import
{
Model
}
from
'
./model
'
;
import
{
Repository
,
Resource
,
ResourceGroupType
}
from
'
./repository
'
;
...
...
@@ -18,8 +18,8 @@ import { fromGitUri, toGitUri, isGitUri } from './uri';
import
{
grep
,
isDescendant
,
pathEquals
}
from
'
./util
'
;
import
{
Log
,
LogLevel
}
from
'
./log
'
;
import
{
GitTimelineItem
}
from
'
./timelineProvider
'
;
import
{
throttle
,
debounce
}
from
'
./decorators
'
;
import
{
ApiRepository
}
from
'
./api/api1
'
;
import
{
pickRemoteSource
}
from
'
./remoteSource
'
;
const
localize
=
nls
.
loadMessageBundle
();
...
...
@@ -240,72 +240,6 @@ interface PushOptions {
silent
?:
boolean
;
}
async
function
getQuickPickResult
<
T
extends
QuickPickItem
>
(
quickpick
:
QuickPick
<
T
>
):
Promise
<
T
|
undefined
>
{
const
result
=
await
new
Promise
<
T
|
undefined
>
(
c
=>
{
quickpick
.
onDidAccept
(()
=>
c
(
quickpick
.
selectedItems
[
0
]));
quickpick
.
onDidHide
(()
=>
c
(
undefined
));
quickpick
.
show
();
});
quickpick
.
hide
();
return
result
;
}
class
RemoteSourceProviderQuickPick
{
private
quickpick
:
QuickPick
<
QuickPickItem
&
{
remoteSource
?:
RemoteSource
}
>
;
constructor
(
private
provider
:
RemoteSourceProvider
)
{
this
.
quickpick
=
window
.
createQuickPick
();
this
.
quickpick
.
ignoreFocusOut
=
true
;
if
(
provider
.
supportsQuery
)
{
this
.
quickpick
.
placeholder
=
localize
(
'
type to search
'
,
"
Repository name (type to search)
"
);
this
.
quickpick
.
onDidChangeValue
(
this
.
onDidChangeValue
,
this
);
}
else
{
this
.
quickpick
.
placeholder
=
localize
(
'
type to filter
'
,
"
Repository name
"
);
}
}
@
debounce
(
300
)
onDidChangeValue
():
void
{
this
.
query
();
}
@
throttle
async
query
():
Promise
<
void
>
{
this
.
quickpick
.
busy
=
true
;
try
{
const
remoteSources
=
await
this
.
provider
.
getRemoteSources
(
this
.
quickpick
.
value
)
||
[];
if
(
remoteSources
.
length
===
0
)
{
this
.
quickpick
.
items
=
[{
label
:
localize
(
'
none found
'
,
"
No remote repositories found.
"
),
alwaysShow
:
true
}];
}
else
{
this
.
quickpick
.
items
=
remoteSources
.
map
(
remoteSource
=>
({
label
:
remoteSource
.
name
,
description
:
remoteSource
.
description
||
(
typeof
remoteSource
.
url
===
'
string
'
?
remoteSource
.
url
:
remoteSource
.
url
[
0
]),
remoteSource
}));
}
}
catch
(
err
)
{
this
.
quickpick
.
items
=
[{
label
:
localize
(
'
error
'
,
"
$(error) Error: {0}
"
,
err
.
message
),
alwaysShow
:
true
}];
console
.
error
(
err
);
}
finally
{
this
.
quickpick
.
busy
=
false
;
}
}
async
pick
():
Promise
<
RemoteSource
|
undefined
>
{
this
.
query
();
const
result
=
await
getQuickPickResult
(
this
.
quickpick
);
return
result
?.
remoteSource
;
}
}
export
class
CommandCenter
{
private
disposables
:
Disposable
[];
...
...
@@ -527,51 +461,10 @@ export class CommandCenter {
@
command
(
'
git.clone
'
)
async
clone
(
url
?:
string
,
parentPath
?:
string
):
Promise
<
void
>
{
if
(
!
url
)
{
const
quickpick
=
window
.
createQuickPick
<
(
QuickPickItem
&
{
provider
?:
RemoteSourceProvider
,
url
?:
string
})
>
();
quickpick
.
ignoreFocusOut
=
true
;
const
providers
=
this
.
model
.
getRemoteProviders
()
.
map
(
provider
=>
({
label
:
(
provider
.
icon
?
`$(
${
provider
.
icon
}
) `
:
''
)
+
localize
(
'
clonefrom
'
,
"
Clone from {0}
"
,
provider
.
name
),
alwaysShow
:
true
,
provider
}));
quickpick
.
placeholder
=
providers
.
length
===
0
?
localize
(
'
provide url
'
,
"
Provide repository URL
"
)
:
localize
(
'
provide url or pick
'
,
"
Provide repository URL or pick a repository source.
"
);
const
updatePicks
=
(
value
?:
string
)
=>
{
if
(
value
)
{
quickpick
.
items
=
[{
label
:
localize
(
'
repourl
'
,
"
Clone from URL
"
),
description
:
value
,
alwaysShow
:
true
,
url
:
value
},
...
providers
];
}
else
{
quickpick
.
items
=
providers
;
}
};
quickpick
.
onDidChangeValue
(
updatePicks
);
updatePicks
();
const
result
=
await
getQuickPickResult
(
quickpick
);
if
(
result
)
{
if
(
result
.
url
)
{
url
=
result
.
url
;
}
else
if
(
result
.
provider
)
{
const
quickpick
=
new
RemoteSourceProviderQuickPick
(
result
.
provider
);
const
remote
=
await
quickpick
.
pick
();
if
(
remote
)
{
if
(
typeof
remote
.
url
===
'
string
'
)
{
url
=
remote
.
url
;
}
else
if
(
remote
.
url
.
length
>
0
)
{
url
=
await
window
.
showQuickPick
(
remote
.
url
,
{
ignoreFocusOut
:
true
,
placeHolder
:
localize
(
'
pick url
'
,
"
Choose a URL to clone from.
"
)
});
}
}
}
}
url
=
await
pickRemoteSource
(
this
.
model
,
{
providerLabel
:
provider
=>
localize
(
'
clonefrom
'
,
"
Clone from {0}
"
,
provider
.
name
),
urlLabel
:
localize
(
'
repourl
'
,
"
Clone from URL
"
)
});
}
if
(
!
url
)
{
...
...
@@ -2146,52 +2039,10 @@ export class CommandCenter {
@
command
(
'
git.addRemote
'
,
{
repository
:
true
})
async
addRemote
(
repository
:
Repository
):
Promise
<
string
|
undefined
>
{
const
quickpick
=
window
.
createQuickPick
<
(
QuickPickItem
&
{
provider
?:
RemoteSourceProvider
,
url
?:
string
})
>
();
quickpick
.
ignoreFocusOut
=
true
;
const
providers
=
this
.
model
.
getRemoteProviders
()
.
map
(
provider
=>
({
label
:
(
provider
.
icon
?
`$(
${
provider
.
icon
}
) `
:
''
)
+
localize
(
'
addfrom
'
,
"
Add remote from {0}
"
,
provider
.
name
),
alwaysShow
:
true
,
provider
}));
quickpick
.
placeholder
=
providers
.
length
===
0
?
localize
(
'
provide url
'
,
"
Provide repository URL
"
)
:
localize
(
'
provide url or pick
'
,
"
Provide repository URL or pick a repository source.
"
);
const
updatePicks
=
(
value
?:
string
)
=>
{
if
(
value
)
{
quickpick
.
items
=
[{
label
:
localize
(
'
addFrom
'
,
"
Add remote from URL
"
),
description
:
value
,
alwaysShow
:
true
,
url
:
value
},
...
providers
];
}
else
{
quickpick
.
items
=
providers
;
}
};
quickpick
.
onDidChangeValue
(
updatePicks
);
updatePicks
();
const
result
=
await
getQuickPickResult
(
quickpick
);
let
url
:
string
|
undefined
;
if
(
result
)
{
if
(
result
.
url
)
{
url
=
result
.
url
;
}
else
if
(
result
.
provider
)
{
const
quickpick
=
new
RemoteSourceProviderQuickPick
(
result
.
provider
);
const
remote
=
await
quickpick
.
pick
();
if
(
remote
)
{
if
(
typeof
remote
.
url
===
'
string
'
)
{
url
=
remote
.
url
;
}
else
if
(
remote
.
url
.
length
>
0
)
{
url
=
await
window
.
showQuickPick
(
remote
.
url
,
{
ignoreFocusOut
:
true
,
placeHolder
:
localize
(
'
pick url
'
,
"
Choose a URL to clone from.
"
)
});
}
}
}
}
const
url
=
await
pickRemoteSource
(
this
.
model
,
{
providerLabel
:
provider
=>
localize
(
'
addfrom
'
,
"
Add remote from {0}
"
,
provider
.
name
),
urlLabel
:
localize
(
'
addFrom
'
,
"
Add remote from URL
"
)
});
if
(
!
url
)
{
return
;
...
...
extensions/git/src/main.ts
浏览文件 @
c85718eb
...
...
@@ -127,7 +127,7 @@ async function warnAboutMissingGit(): Promise<void> {
}
}
export
async
function
_activate
(
context
:
ExtensionContext
):
Promise
<
GitExtension
>
{
export
async
function
_activate
(
context
:
ExtensionContext
):
Promise
<
GitExtension
Impl
>
{
const
disposables
:
Disposable
[]
=
[];
context
.
subscriptions
.
push
(
new
Disposable
(()
=>
Disposable
.
from
(...
disposables
).
dispose
()));
...
...
extensions/git/src/remoteSource.ts
0 → 100644
浏览文件 @
c85718eb
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
QuickPickItem
,
window
,
QuickPick
}
from
'
vscode
'
;
import
*
as
nls
from
'
vscode-nls
'
;
import
{
RemoteSourceProvider
,
RemoteSource
}
from
'
./api/git
'
;
import
{
Model
}
from
'
./model
'
;
import
{
throttle
,
debounce
}
from
'
./decorators
'
;
const
localize
=
nls
.
loadMessageBundle
();
async
function
getQuickPickResult
<
T
extends
QuickPickItem
>
(
quickpick
:
QuickPick
<
T
>
):
Promise
<
T
|
undefined
>
{
const
result
=
await
new
Promise
<
T
|
undefined
>
(
c
=>
{
quickpick
.
onDidAccept
(()
=>
c
(
quickpick
.
selectedItems
[
0
]));
quickpick
.
onDidHide
(()
=>
c
(
undefined
));
quickpick
.
show
();
});
quickpick
.
hide
();
return
result
;
}
class
RemoteSourceProviderQuickPick
{
private
quickpick
:
QuickPick
<
QuickPickItem
&
{
remoteSource
?:
RemoteSource
}
>
;
constructor
(
private
provider
:
RemoteSourceProvider
)
{
this
.
quickpick
=
window
.
createQuickPick
();
this
.
quickpick
.
ignoreFocusOut
=
true
;
if
(
provider
.
supportsQuery
)
{
this
.
quickpick
.
placeholder
=
localize
(
'
type to search
'
,
"
Repository name (type to search)
"
);
this
.
quickpick
.
onDidChangeValue
(
this
.
onDidChangeValue
,
this
);
}
else
{
this
.
quickpick
.
placeholder
=
localize
(
'
type to filter
'
,
"
Repository name
"
);
}
}
@
debounce
(
300
)
private
onDidChangeValue
():
void
{
this
.
query
();
}
@
throttle
private
async
query
():
Promise
<
void
>
{
this
.
quickpick
.
busy
=
true
;
try
{
const
remoteSources
=
await
this
.
provider
.
getRemoteSources
(
this
.
quickpick
.
value
)
||
[];
if
(
remoteSources
.
length
===
0
)
{
this
.
quickpick
.
items
=
[{
label
:
localize
(
'
none found
'
,
"
No remote repositories found.
"
),
alwaysShow
:
true
}];
}
else
{
this
.
quickpick
.
items
=
remoteSources
.
map
(
remoteSource
=>
({
label
:
remoteSource
.
name
,
description
:
remoteSource
.
description
||
(
typeof
remoteSource
.
url
===
'
string
'
?
remoteSource
.
url
:
remoteSource
.
url
[
0
]),
remoteSource
}));
}
}
catch
(
err
)
{
this
.
quickpick
.
items
=
[{
label
:
localize
(
'
error
'
,
"
$(error) Error: {0}
"
,
err
.
message
),
alwaysShow
:
true
}];
console
.
error
(
err
);
}
finally
{
this
.
quickpick
.
busy
=
false
;
}
}
async
pick
():
Promise
<
RemoteSource
|
undefined
>
{
this
.
query
();
const
result
=
await
getQuickPickResult
(
this
.
quickpick
);
return
result
?.
remoteSource
;
}
}
export
interface
PickRemoteSourceOptions
{
readonly
providerLabel
?:
(
provider
:
RemoteSourceProvider
)
=>
string
;
readonly
urlLabel
?:
string
;
}
export
async
function
pickRemoteSource
(
model
:
Model
,
options
:
PickRemoteSourceOptions
=
{}):
Promise
<
string
|
undefined
>
{
const
quickpick
=
window
.
createQuickPick
<
(
QuickPickItem
&
{
provider
?:
RemoteSourceProvider
,
url
?:
string
})
>
();
quickpick
.
ignoreFocusOut
=
true
;
const
providers
=
model
.
getRemoteProviders
()
.
map
(
provider
=>
({
label
:
(
provider
.
icon
?
`$(
${
provider
.
icon
}
) `
:
''
)
+
(
options
.
providerLabel
?
options
.
providerLabel
(
provider
)
:
provider
.
name
),
alwaysShow
:
true
,
provider
}));
quickpick
.
placeholder
=
providers
.
length
===
0
?
localize
(
'
provide url
'
,
"
Provide repository URL
"
)
:
localize
(
'
provide url or pick
'
,
"
Provide repository URL or pick a repository source.
"
);
const
updatePicks
=
(
value
?:
string
)
=>
{
if
(
value
)
{
quickpick
.
items
=
[{
label
:
options
.
urlLabel
??
localize
(
'
url
'
,
"
URL
"
),
description
:
value
,
alwaysShow
:
true
,
url
:
value
},
...
providers
];
}
else
{
quickpick
.
items
=
providers
;
}
};
quickpick
.
onDidChangeValue
(
updatePicks
);
updatePicks
();
const
result
=
await
getQuickPickResult
(
quickpick
);
if
(
result
)
{
if
(
result
.
url
)
{
return
result
.
url
;
}
else
if
(
result
.
provider
)
{
const
quickpick
=
new
RemoteSourceProviderQuickPick
(
result
.
provider
);
const
remote
=
await
quickpick
.
pick
();
if
(
remote
)
{
if
(
typeof
remote
.
url
===
'
string
'
)
{
return
remote
.
url
;
}
else
if
(
remote
.
url
.
length
>
0
)
{
return
await
window
.
showQuickPick
(
remote
.
url
,
{
ignoreFocusOut
:
true
,
placeHolder
:
localize
(
'
pick url
'
,
"
Choose a URL to clone from.
"
)
});
}
}
}
}
return
undefined
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录