Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
303dd117
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,发现更多精彩内容 >>
提交
303dd117
编写于
8月 15, 2017
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
git multirepo stage
上级
16e81896
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
148 addition
and
111 deletion
+148
-111
extensions/git/src/commands.ts
extensions/git/src/commands.ts
+10
-33
extensions/git/src/main.ts
extensions/git/src/main.ts
+5
-5
extensions/git/src/model.ts
extensions/git/src/model.ts
+114
-0
extensions/git/src/modelRegistry.ts
extensions/git/src/modelRegistry.ts
+0
-70
extensions/git/src/repository.ts
extensions/git/src/repository.ts
+5
-1
extensions/git/src/util.ts
extensions/git/src/util.ts
+14
-2
未找到文件。
extensions/git/src/commands.ts
浏览文件 @
303dd117
...
...
@@ -8,7 +8,7 @@
import
{
Uri
,
commands
,
scm
,
Disposable
,
window
,
workspace
,
QuickPickItem
,
OutputChannel
,
Range
,
WorkspaceEdit
,
Position
,
LineChange
,
SourceControlResourceState
,
TextDocumentShowOptions
,
ViewColumn
}
from
'
vscode
'
;
import
{
Ref
,
RefType
,
Git
,
GitErrorCodes
,
Branch
}
from
'
./git
'
;
import
{
Repository
,
Resource
,
Status
,
CommitOptions
,
WorkingTreeGroup
,
IndexGroup
,
MergeGroup
}
from
'
./repository
'
;
import
{
Model
Registry
}
from
'
./modelRegistry
'
;
import
{
Model
}
from
'
./model
'
;
import
{
toGitUri
,
fromGitUri
}
from
'
./uri
'
;
import
{
applyLineChanges
,
intersectDiffWithRange
,
toLineRanges
,
invertLineChange
}
from
'
./staging
'
;
import
*
as
path
from
'
path
'
;
...
...
@@ -130,7 +130,7 @@ export class CommandCenter {
constructor
(
private
git
:
Git
,
private
model
Registry
:
ModelRegistry
,
private
model
:
Model
,
private
outputChannel
:
OutputChannel
,
private
telemetryReporter
:
TelemetryReporter
)
{
...
...
@@ -145,21 +145,6 @@ export class CommandCenter {
});
}
private
groupByModel
(
resources
:
Uri
[]):
[
Repository
|
undefined
,
Uri
[]][]
{
return
resources
.
reduce
((
result
,
resource
)
=>
{
const
model
=
this
.
modelRegistry
.
getModel
(
resource
);
const
pair
=
result
.
filter
(
p
=>
p
[
0
]
===
model
)[
0
];
if
(
pair
)
{
pair
[
1
].
push
(
resource
);
}
else
{
result
.
push
([
model
,
[
resource
]]);
}
return
result
;
},
[]
as
[
Repository
|
undefined
,
Uri
[]][]);
}
@
command
(
'
git.refresh
'
,
{
model
:
true
})
async
refresh
(
model
:
Repository
):
Promise
<
void
>
{
await
model
.
status
();
...
...
@@ -450,15 +435,7 @@ export class CommandCenter {
}
const
resources
=
scmResources
.
map
(
r
=>
r
.
resourceUri
);
const
resourcesByModel
=
this
.
groupByModel
(
resources
);
await
Promise
.
all
(
resourcesByModel
.
map
(
async
([
model
,
resources
])
=>
{
if
(
!
model
)
{
return
;
// TODO@joao
}
await
model
.
add
(...
resources
);
}));
await
this
.
model
.
add
(...
resources
);
}
@
command
(
'
git.stageAll
'
,
{
model
:
true
})
...
...
@@ -1237,12 +1214,12 @@ export class CommandCenter {
if
(
!
options
.
model
)
{
result
=
Promise
.
resolve
(
method
.
apply
(
this
,
args
));
}
else
{
result
=
this
.
model
Registry
.
pickModel
().
then
(
model
=>
{
if
(
!
model
)
{
result
=
this
.
model
.
pickRepository
().
then
(
repository
=>
{
if
(
!
repository
)
{
return
Promise
.
reject
(
localize
(
'
modelnotfound
'
,
"
Git model not found
"
));
}
return
Promise
.
resolve
(
method
.
apply
(
this
,
[
model
,
...
args
]));
return
Promise
.
resolve
(
method
.
apply
(
this
,
[
repository
,
...
args
]));
});
}
...
...
@@ -1309,14 +1286,14 @@ export class CommandCenter {
if
(
uri
.
scheme
===
'
file
'
)
{
const
uriString
=
uri
.
toString
();
const
model
=
this
.
modelRegistry
.
getModel
(
uri
);
const
repository
=
this
.
model
.
getRepository
(
uri
);
if
(
!
model
)
{
if
(
!
repository
)
{
return
undefined
;
}
return
model
.
workingTreeGroup
.
resources
.
filter
(
r
=>
r
.
resourceUri
.
toString
()
===
uriString
)[
0
]
||
model
.
indexGroup
.
resources
.
filter
(
r
=>
r
.
resourceUri
.
toString
()
===
uriString
)[
0
];
return
repository
.
workingTreeGroup
.
resources
.
filter
(
r
=>
r
.
resourceUri
.
toString
()
===
uriString
)[
0
]
||
repository
.
indexGroup
.
resources
.
filter
(
r
=>
r
.
resourceUri
.
toString
()
===
uriString
)[
0
];
}
}
...
...
extensions/git/src/main.ts
浏览文件 @
303dd117
...
...
@@ -10,7 +10,7 @@ const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
import
{
ExtensionContext
,
workspace
,
window
,
Disposable
,
commands
,
Uri
}
from
'
vscode
'
;
import
{
findGit
,
Git
,
IGit
}
from
'
./git
'
;
import
{
Repository
}
from
'
./repository
'
;
import
{
Model
Registry
}
from
'
./modelRegistry
'
;
import
{
Model
}
from
'
./model
'
;
import
{
GitSCMProvider
}
from
'
./scmProvider
'
;
import
{
CommandCenter
}
from
'
./commands
'
;
import
{
StatusBarCommands
}
from
'
./statusbar
'
;
...
...
@@ -37,17 +37,17 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
const
askpass
=
new
Askpass
();
const
env
=
await
askpass
.
getEnv
();
const
git
=
new
Git
({
gitPath
:
info
.
path
,
version
:
info
.
version
,
env
});
const
model
Registry
=
new
ModelRegistry
();
const
model
=
new
Model
();
if
(
!
workspaceRootPath
||
!
enabled
)
{
const
commandCenter
=
new
CommandCenter
(
git
,
model
Registry
,
outputChannel
,
telemetryReporter
);
const
commandCenter
=
new
CommandCenter
(
git
,
model
,
outputChannel
,
telemetryReporter
);
disposables
.
push
(
commandCenter
);
return
;
}
const
workspaceRoot
=
Uri
.
file
(
workspaceRootPath
);
const
repository
=
new
Repository
(
git
,
workspaceRoot
);
model
Registry
.
register
(
workspaceRoot
,
repository
);
model
.
register
(
workspaceRoot
,
repository
);
outputChannel
.
appendLine
(
localize
(
'
using git
'
,
"
Using git {0} from {1}
"
,
info
.
version
,
info
.
path
));
...
...
@@ -55,7 +55,7 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
git
.
onOutput
.
addListener
(
'
log
'
,
onOutput
);
disposables
.
push
(
toDisposable
(()
=>
git
.
onOutput
.
removeListener
(
'
log
'
,
onOutput
)));
const
commandCenter
=
new
CommandCenter
(
git
,
model
Registry
,
outputChannel
,
telemetryReporter
);
const
commandCenter
=
new
CommandCenter
(
git
,
model
,
outputChannel
,
telemetryReporter
);
const
statusBarCommands
=
new
StatusBarCommands
(
repository
);
const
provider
=
new
GitSCMProvider
(
repository
,
statusBarCommands
);
const
contentProvider
=
new
GitContentProvider
(
repository
);
...
...
extensions/git/src/model.ts
0 → 100644
浏览文件 @
303dd117
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Uri
,
window
,
QuickPickItem
,
Disposable
}
from
'
vscode
'
;
import
{
GitErrorCodes
}
from
'
./git
'
;
import
{
Repository
,
IRepository
,
State
}
from
'
./repository
'
;
import
{
memoize
}
from
'
./decorators
'
;
import
{
toDisposable
,
filterEvent
,
once
}
from
'
./util
'
;
import
*
as
path
from
'
path
'
;
import
*
as
nls
from
'
vscode-nls
'
;
const
localize
=
nls
.
loadMessageBundle
();
class
RepositoryPick
implements
QuickPickItem
{
@
memoize
get
label
():
string
{
return
path
.
basename
(
this
.
repositoryRoot
.
fsPath
);
}
@
memoize
get
description
():
string
{
return
path
.
dirname
(
this
.
repositoryRoot
.
fsPath
);
}
constructor
(
protected
repositoryRoot
:
Uri
,
public
readonly
repository
:
Repository
)
{
}
}
export
class
Model
implements
IRepository
{
private
repositories
:
Map
<
Uri
,
Repository
>
=
new
Map
<
Uri
,
Repository
>
();
register
(
uri
:
Uri
,
repository
:
Repository
):
Disposable
{
if
(
this
.
repositories
.
has
(
uri
))
{
// TODO@Joao: what should happen?
throw
new
Error
(
'
Cant register repository with the same URI
'
);
}
this
.
repositories
.
set
(
uri
,
repository
);
const
onDidDisappearRepository
=
filterEvent
(
repository
.
onDidChangeState
,
state
=>
state
===
State
.
NotAGitRepository
);
const
listener
=
onDidDisappearRepository
(()
=>
disposable
.
dispose
());
const
disposable
=
toDisposable
(
once
(()
=>
{
this
.
repositories
.
delete
(
uri
);
listener
.
dispose
();
}));
return
disposable
;
}
async
pickRepository
():
Promise
<
Repository
|
undefined
>
{
const
picks
=
Array
.
from
(
this
.
repositories
.
entries
(),
([
uri
,
model
])
=>
new
RepositoryPick
(
uri
,
model
));
const
placeHolder
=
localize
(
'
pick repo
'
,
"
Choose a repository
"
);
const
pick
=
await
window
.
showQuickPick
(
picks
,
{
placeHolder
});
return
pick
&&
pick
.
repository
;
}
getRepository
(
resource
:
Uri
):
Repository
|
undefined
{
const
resourcePath
=
resource
.
fsPath
;
for
(
let
[
repositoryRoot
,
model
]
of
this
.
repositories
)
{
const
repositoryRootPath
=
repositoryRoot
.
fsPath
;
const
relativePath
=
path
.
relative
(
repositoryRootPath
,
resourcePath
);
if
(
!
/^
\.
/
.
test
(
relativePath
))
{
return
model
;
}
}
return
undefined
;
}
private
async
runByRepository
<
T
>
(
resources
:
Uri
[],
fn
:
(
repository
:
Repository
,
resources
:
Uri
[])
=>
Promise
<
T
>
):
Promise
<
T
[]
>
{
const
groups
=
resources
.
reduce
((
result
,
resource
)
=>
{
const
repository
=
this
.
getRepository
(
resource
);
// TODO@Joao: what should happen?
if
(
!
repository
)
{
console
.
warn
(
'
Could not find git repository for
'
,
resource
);
return
result
;
}
const
tuple
=
result
.
filter
(
p
=>
p
[
0
]
===
repository
)[
0
];
if
(
tuple
)
{
tuple
.
resources
.
push
(
resource
);
}
else
{
result
.
push
({
repository
,
resources
:
[
resource
]
});
}
return
result
;
},
[]
as
{
repository
:
Repository
,
resources
:
Uri
[]
}[]);
const
promises
=
groups
.
map
(({
repository
,
resources
})
=>
this
.
run
(
repository
,
()
=>
fn
(
repository
as
Repository
,
resources
)));
return
Promise
.
all
(
promises
);
}
private
async
run
<
T
>
(
repository
:
Repository
,
fn
:
()
=>
Promise
<
T
>
):
Promise
<
T
>
{
try
{
return
fn
();
}
catch
(
err
)
{
if
(
err
.
gitErrorCode
===
GitErrorCodes
.
NotAGitRepository
)
{
// do something about it
}
throw
err
;
}
}
// IRepository
async
add
(...
resources
:
Uri
[]):
Promise
<
void
>
{
await
this
.
runByRepository
(
resources
,
async
(
repository
,
resources
)
=>
repository
.
add
(...
resources
));
}
}
\ No newline at end of file
extensions/git/src/modelRegistry.ts
已删除
100644 → 0
浏览文件 @
16e81896
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
Uri
,
window
,
QuickPickItem
}
from
'
vscode
'
;
import
{
Repository
}
from
'
./repository
'
;
import
{
memoize
}
from
'
./decorators
'
;
import
*
as
path
from
'
path
'
;
import
*
as
nls
from
'
vscode-nls
'
;
const
localize
=
nls
.
loadMessageBundle
();
class
ModelPick
implements
QuickPickItem
{
@
memoize
get
label
():
string
{
return
path
.
basename
(
this
.
repositoryRoot
.
fsPath
);
}
@
memoize
get
description
():
string
{
return
path
.
dirname
(
this
.
repositoryRoot
.
fsPath
);
}
constructor
(
protected
repositoryRoot
:
Uri
,
public
readonly
model
:
Repository
)
{
}
}
export
class
ModelRegistry
{
private
models
:
Map
<
Uri
,
Repository
>
=
new
Map
<
Uri
,
Repository
>
();
register
(
uri
:
Uri
,
model
):
void
{
this
.
models
.
set
(
uri
,
model
);
}
async
pickModel
():
Promise
<
Repository
|
undefined
>
{
const
picks
=
Array
.
from
(
this
.
models
.
entries
(),
([
uri
,
model
])
=>
new
ModelPick
(
uri
,
model
));
const
placeHolder
=
localize
(
'
pick repo
'
,
"
Choose a repository
"
);
const
pick
=
await
window
.
showQuickPick
(
picks
,
{
placeHolder
});
return
pick
&&
pick
.
model
;
}
getModel
(
resource
:
Uri
):
Repository
|
undefined
{
const
resourcePath
=
resource
.
fsPath
;
for
(
let
[
repositoryRoot
,
model
]
of
this
.
models
)
{
const
repositoryRootPath
=
repositoryRoot
.
fsPath
;
const
relativePath
=
path
.
relative
(
repositoryRootPath
,
resourcePath
);
if
(
!
/^
\.
/
.
test
(
relativePath
))
{
return
model
;
}
}
return
undefined
;
}
async
resolve
(
resource
:
Uri
):
Promise
<
Repository
|
undefined
>
{
const
model
=
this
.
getModel
(
resource
);
if
(
model
)
{
return
model
;
}
const
picks
=
Array
.
from
(
this
.
models
.
entries
(),
([
uri
,
model
])
=>
new
ModelPick
(
uri
,
model
));
const
placeHolder
=
localize
(
'
pick repo
'
,
"
Choose a repository
"
);
const
pick
=
await
window
.
showQuickPick
(
picks
,
{
placeHolder
});
if
(
pick
)
{
return
pick
.
model
;
}
return
undefined
;
}
}
extensions/git/src/repository.ts
浏览文件 @
303dd117
...
...
@@ -295,7 +295,11 @@ export interface CommitOptions {
signCommit
?:
boolean
;
}
export
class
Repository
implements
Disposable
{
export
interface
IRepository
{
add
(...
resources
:
Uri
[]):
Promise
<
void
>
;
}
export
class
Repository
implements
IRepository
,
Disposable
{
private
_onDidChangeRepository
=
new
EventEmitter
<
Uri
>
();
readonly
onDidChangeRepository
:
Event
<
Uri
>
=
this
.
_onDidChangeRepository
.
event
;
...
...
extensions/git/src/util.ts
浏览文件 @
303dd117
...
...
@@ -56,7 +56,7 @@ export function done<T>(promise: Promise<T>): Promise<void> {
return
promise
.
then
<
void
>
(()
=>
void
0
);
}
export
function
once
<
T
>
(
event
:
Event
<
T
>
):
Event
<
T
>
{
export
function
once
Event
<
T
>
(
event
:
Event
<
T
>
):
Event
<
T
>
{
return
(
listener
,
thisArgs
=
null
,
disposables
?)
=>
{
const
result
=
event
(
e
=>
{
result
.
dispose
();
...
...
@@ -68,7 +68,19 @@ export function once<T>(event: Event<T>): Event<T> {
}
export
function
eventToPromise
<
T
>
(
event
:
Event
<
T
>
):
Promise
<
T
>
{
return
new
Promise
<
T
>
(
c
=>
once
(
event
)(
c
));
return
new
Promise
<
T
>
(
c
=>
onceEvent
(
event
)(
c
));
}
export
function
once
(
fn
:
(...
args
:
any
[])
=>
any
):
(...
args
:
any
[])
=>
any
{
let
didRun
=
false
;
return
(...
args
)
=>
{
if
(
didRun
)
{
return
;
}
return
fn
(...
args
);
};
}
// TODO@Joao: replace with Object.assign
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录