Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
3d6b1b71
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,发现更多精彩内容 >>
提交
3d6b1b71
编写于
2月 16, 2017
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
git: wrap up nogit state
上级
ac703e0d
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
107 addition
and
73 deletion
+107
-73
extensions/git/src/main.ts
extensions/git/src/main.ts
+2
-1
extensions/git/src/model.ts
extensions/git/src/model.ts
+99
-67
extensions/git/src/scmProvider.ts
extensions/git/src/scmProvider.ts
+2
-2
extensions/git/src/statusbar.ts
extensions/git/src/statusbar.ts
+2
-3
extensions/git/src/util.ts
extensions/git/src/util.ts
+2
-0
未找到文件。
extensions/git/src/main.ts
浏览文件 @
3d6b1b71
...
...
@@ -65,7 +65,8 @@ async function init(disposables: Disposable[]): Promise<void> {
checkoutStatusBar
,
syncStatusBar
,
autoFetcher
,
mergeDecorator
mergeDecorator
,
model
);
}
...
...
extensions/git/src/model.ts
浏览文件 @
3d6b1b71
...
...
@@ -7,7 +7,7 @@
import
{
Uri
,
EventEmitter
,
Event
,
SCMResource
,
SCMResourceDecorations
,
SCMResourceGroup
,
Disposable
,
window
,
workspace
}
from
'
vscode
'
;
import
{
Repository
,
Ref
,
Branch
,
Remote
,
PushOptions
,
Commit
,
GitErrorCodes
}
from
'
./git
'
;
import
{
anyEvent
,
eventToPromise
,
filterEvent
,
mapEvent
}
from
'
./util
'
;
import
{
anyEvent
,
eventToPromise
,
filterEvent
,
mapEvent
,
EmptyDisposable
,
combinedDisposable
}
from
'
./util
'
;
import
{
memoize
,
throttle
,
debounce
}
from
'
./decorators
'
;
import
{
watch
}
from
'
./watch
'
;
import
*
as
path
from
'
path
'
;
...
...
@@ -20,6 +20,12 @@ function getIconUri(iconName: string, theme: string): Uri {
return
Uri
.
file
(
path
.
join
(
iconsRootPath
,
theme
,
`
${
iconName
}
.svg`
));
}
export
enum
State
{
Uninitialized
,
Idle
,
NotAGitRepository
}
export
enum
Status
{
INDEX_MODIFIED
,
INDEX_ADDED
,
...
...
@@ -139,7 +145,7 @@ export class MergeGroup extends ResourceGroup {
static
readonly
ID
=
'
merge
'
;
constructor
(
resources
:
Resource
[])
{
constructor
(
resources
:
Resource
[]
=
[]
)
{
super
(
MergeGroup
.
ID
,
localize
(
'
merge changes
'
,
"
Merge Changes
"
),
resources
);
}
}
...
...
@@ -148,7 +154,7 @@ export class IndexGroup extends ResourceGroup {
static
readonly
ID
=
'
index
'
;
constructor
(
resources
:
Resource
[])
{
constructor
(
resources
:
Resource
[]
=
[]
)
{
super
(
IndexGroup
.
ID
,
localize
(
'
staged changes
'
,
"
Staged Changes
"
),
resources
);
}
}
...
...
@@ -157,7 +163,7 @@ export class WorkingTreeGroup extends ResourceGroup {
static
readonly
ID
=
'
workingTree
'
;
constructor
(
resources
:
Resource
[])
{
constructor
(
resources
:
Resource
[]
=
[]
)
{
super
(
WorkingTreeGroup
.
ID
,
localize
(
'
changes
'
,
"
Changes
"
),
resources
);
}
}
...
...
@@ -176,6 +182,7 @@ export enum Operation {
Push
=
1
<<
10
,
Sync
=
1
<<
11
,
Init
=
1
<<
12
,
UpdateModel
=
1
<<
13
}
export
interface
Operations
{
...
...
@@ -212,16 +219,18 @@ export interface CommitOptions {
signoff
?:
boolean
;
}
export
enum
State
{
Uninitialized
,
Idle
,
NotAGitRepository
}
export
class
Model
implements
Disposable
{
export
class
Model
{
private
_onDidChangeState
=
new
EventEmitter
<
State
>
();
readonly
onDidChangeState
:
Event
<
State
>
=
this
.
_onDidChangeState
.
event
;
private
_onDidChange
=
new
EventEmitter
<
SCMResourceGroup
[]
>
();
readonly
onDidChange
:
Event
<
SCMResourceGroup
[]
>
=
this
.
_onDidChange
.
event
;
private
_onDidChangeResources
=
new
EventEmitter
<
SCMResourceGroup
[]
>
();
readonly
onDidChangeResources
:
Event
<
SCMResourceGroup
[]
>
=
this
.
_onDidChangeResources
.
event
;
@
memoize
get
onDidChange
():
Event
<
void
>
{
return
anyEvent
<
any
>
(
this
.
onDidChangeState
,
this
.
onDidChangeResources
);
}
private
_onRunOperation
=
new
EventEmitter
<
Operation
>
();
readonly
onRunOperation
:
Event
<
Operation
>
=
this
.
_onRunOperation
.
event
;
...
...
@@ -229,9 +238,6 @@ export class Model {
private
_onDidRunOperation
=
new
EventEmitter
<
Operation
>
();
readonly
onDidRunOperation
:
Event
<
Operation
>
=
this
.
_onDidRunOperation
.
event
;
private
_onDidChangeState
=
new
EventEmitter
<
State
>
();
readonly
onDidChangeState
:
Event
<
State
>
=
this
.
_onDidChangeState
.
event
;
@
memoize
get
onDidChangeOperations
():
Event
<
void
>
{
return
anyEvent
(
this
.
onRunOperation
as
Event
<
any
>
,
this
.
onDidRunOperation
as
Event
<
any
>
);
...
...
@@ -262,6 +268,21 @@ export class Model {
return
result
;
}
private
_HEAD
:
Branch
|
undefined
;
get
HEAD
():
Branch
|
undefined
{
return
this
.
_HEAD
;
}
private
_refs
:
Ref
[]
=
[];
get
refs
():
Ref
[]
{
return
this
.
_refs
;
}
private
_remotes
:
Remote
[]
=
[];
get
remotes
():
Remote
[]
{
return
this
.
_remotes
;
}
private
_operations
=
new
OperationsImpl
();
get
operations
():
Operations
{
return
this
.
_operations
;
}
...
...
@@ -272,65 +293,33 @@ export class Model {
set
state
(
state
:
State
)
{
this
.
_state
=
state
;
this
.
_onDidChangeState
.
fire
(
state
);
this
.
_HEAD
=
undefined
;
this
.
_refs
=
[];
this
.
_remotes
=
[];
this
.
_mergeGroup
=
new
MergeGroup
();
this
.
_indexGroup
=
new
IndexGroup
();
this
.
_workingTreeGroup
=
new
WorkingTreeGroup
();
this
.
_onDidChangeResources
.
fire
(
this
.
resources
);
}
private
disposables
:
Disposable
[]
=
[]
;
private
repositoryDisposable
:
Disposable
=
EmptyDisposable
;
constructor
(
private
repository
:
Repository
,
private
onWorkspaceChange
:
Event
<
Uri
>
)
{
this
.
initialize
().
catch
(
err
=>
console
.
error
(
err
));
}
private
async
initialize
():
Promise
<
void
>
{
try
{
this
.
repositoryRoot
=
await
this
.
repository
.
getRoot
();
this
.
state
=
State
.
Idle
;
/* We use the native Node `watch` for faster, non debounced events.
* That way we hopefully get the events during the operations we're
* performing, thus sparing useless `git status` calls to refresh
* the model's state.
*/
const
gitPath
=
path
.
join
(
this
.
repositoryRoot
,
'
.git
'
);
const
{
event
,
disposable
}
=
watch
(
gitPath
);
const
onGitChange
=
mapEvent
(
event
,
({
filename
})
=>
Uri
.
file
(
path
.
join
(
gitPath
,
filename
)));
const
onRelevantGitChange
=
filterEvent
(
onGitChange
,
uri
=>
!
/
\/\.
git
\/
index
\.
lock$/
.
test
(
uri
.
fsPath
));
onRelevantGitChange
(
this
.
onFSChange
,
this
,
this
.
disposables
);
this
.
disposables
.
push
(
disposable
);
const
onNonGitChange
=
filterEvent
(
this
.
onWorkspaceChange
,
uri
=>
!
/
\/\.
git
\/
/
.
test
(
uri
.
fsPath
));
onNonGitChange
(
this
.
onFSChange
,
this
,
this
.
disposables
);
this
.
status
();
}
catch
(
err
)
{
if
(
err
.
gitErrorCode
===
GitErrorCodes
.
NotAGitRepository
)
{
this
.
state
=
State
.
NotAGitRepository
;
}
else
{
throw
err
;
}
}
}
private
_HEAD
:
Branch
|
undefined
;
get
HEAD
():
Branch
|
undefined
{
return
this
.
_HEAD
;
}
private
_refs
:
Ref
[]
=
[];
get
refs
():
Ref
[]
{
return
this
.
_refs
;
}
private
_remotes
:
Remote
[]
=
[];
get
remotes
():
Remote
[]
{
return
this
.
_remotes
;
this
.
status
();
}
@
throttle
async
init
():
Promise
<
void
>
{
await
this
.
run
(
Operation
.
Init
,
()
=>
this
.
repository
.
init
());
if
(
this
.
state
!==
State
.
NotAGitRepository
)
{
return
;
}
await
this
.
repository
.
init
();
await
this
.
status
();
}
@
throttle
...
...
@@ -432,14 +421,23 @@ export class Model {
await
this
.
run
(
Operation
.
Sync
,
()
=>
this
.
repository
.
sync
());
}
private
async
run
(
operation
:
Operation
,
f
n
:
()
=>
Promise
<
void
>
=
()
=>
Promise
.
resolve
()):
Promise
<
void
>
{
private
async
run
(
operation
:
Operation
,
runOperatio
n
:
()
=>
Promise
<
void
>
=
()
=>
Promise
.
resolve
()):
Promise
<
void
>
{
return
window
.
withScmProgress
(
async
()
=>
{
this
.
_operations
=
this
.
_operations
.
start
(
operation
);
this
.
_onRunOperation
.
fire
(
operation
);
try
{
await
fn
();
await
this
.
assertIdleState
();
await
runOperation
();
await
this
.
update
();
}
catch
(
err
)
{
if
(
err
.
gitErrorCode
===
GitErrorCodes
.
NotAGitRepository
)
{
// TODO@Joao!
this
.
repositoryDisposable
.
dispose
();
this
.
state
=
State
.
NotAGitRepository
;
}
else
{
throw
err
;
}
}
finally
{
this
.
_operations
=
this
.
_operations
.
end
(
operation
);
this
.
_onDidRunOperation
.
fire
(
operation
);
...
...
@@ -447,6 +445,37 @@ export class Model {
});
}
/* We use the native Node `watch` for faster, non debounced events.
* That way we hopefully get the events during the operations we're
* performing, thus sparing useless `git status` calls to refresh
* the model's state.
*/
private
async
assertIdleState
():
Promise
<
void
>
{
if
(
this
.
state
===
State
.
Idle
)
{
return
;
}
const
repositoryRoot
=
await
this
.
repository
.
getRoot
();
this
.
repositoryDisposable
.
dispose
();
this
.
repositoryRoot
=
repositoryRoot
;
const
disposables
:
Disposable
[]
=
[];
const
gitPath
=
path
.
join
(
repositoryRoot
,
'
.git
'
);
const
{
event
,
disposable
:
watcher
}
=
watch
(
gitPath
);
disposables
.
push
(
watcher
);
const
onGitChange
=
mapEvent
(
event
,
({
filename
})
=>
Uri
.
file
(
path
.
join
(
gitPath
,
filename
)));
const
onRelevantGitChange
=
filterEvent
(
onGitChange
,
uri
=>
!
/
\/\.
git
\/
index
\.
lock$/
.
test
(
uri
.
fsPath
));
onRelevantGitChange
(
this
.
onFSChange
,
this
,
disposables
);
const
onNonGitChange
=
filterEvent
(
this
.
onWorkspaceChange
,
uri
=>
!
/
\/\.
git
\/
/
.
test
(
uri
.
fsPath
));
onNonGitChange
(
this
.
onFSChange
,
this
,
disposables
);
this
.
repositoryDisposable
=
combinedDisposable
(
disposables
);
this
.
state
=
State
.
Idle
;
}
@
throttle
private
async
update
():
Promise
<
void
>
{
const
status
=
await
this
.
repository
.
getStatus
();
...
...
@@ -511,8 +540,7 @@ export class Model {
this
.
_mergeGroup
=
new
MergeGroup
(
merge
);
this
.
_indexGroup
=
new
IndexGroup
(
index
);
this
.
_workingTreeGroup
=
new
WorkingTreeGroup
(
workingTree
);
this
.
_onDidChange
.
fire
(
this
.
resources
);
this
.
_onDidChangeResources
.
fire
(
this
.
resources
);
}
private
onFSChange
(
uri
:
Uri
):
void
{
...
...
@@ -547,4 +575,8 @@ export class Model {
await
eventToPromise
(
this
.
onDidRunOperation
);
}
}
dispose
():
void
{
this
.
repositoryDisposable
.
dispose
();
}
}
\ No newline at end of file
extensions/git/src/scmProvider.ts
浏览文件 @
3d6b1b71
...
...
@@ -8,7 +8,7 @@
import
{
scm
,
Uri
,
Disposable
,
SCMProvider
,
SCMResourceGroup
,
Event
,
ProviderResult
,
workspace
}
from
'
vscode
'
;
import
{
Model
,
Resource
,
ResourceGroup
,
State
}
from
'
./model
'
;
import
{
CommandCenter
}
from
'
./commands
'
;
import
{
anyEvent
,
mapEvent
}
from
'
./util
'
;
import
{
mapEvent
}
from
'
./util
'
;
export
class
GitSCMProvider
implements
SCMProvider
{
...
...
@@ -17,7 +17,7 @@ export class GitSCMProvider implements SCMProvider {
get
resources
():
SCMResourceGroup
[]
{
return
this
.
model
.
resources
;
}
get
onDidChange
():
Event
<
SCMResourceGroup
[]
>
{
return
mapEvent
(
anyEvent
<
any
>
(
this
.
model
.
onDidChange
,
this
.
model
.
onDidChangeState
)
,
()
=>
this
.
model
.
resources
);
return
mapEvent
(
this
.
model
.
onDidChange
,
()
=>
this
.
model
.
resources
);
}
get
label
():
string
{
return
'
Git
'
;
}
...
...
extensions/git/src/statusbar.ts
浏览文件 @
3d6b1b71
...
...
@@ -30,9 +30,7 @@ export class CheckoutStatusBar {
const
HEAD
=
this
.
model
.
HEAD
;
if
(
!
HEAD
)
{
this
.
raw
.
command
=
''
;
this
.
raw
.
color
=
'
rgb(100, 100, 100)
'
;
this
.
raw
.
text
=
'
unknown
'
;
this
.
raw
.
hide
();
return
;
}
...
...
@@ -48,6 +46,7 @@ export class CheckoutStatusBar {
(
this
.
model
.
workingTreeGroup
.
resources
.
length
>
0
?
'
*
'
:
''
)
+
(
this
.
model
.
indexGroup
.
resources
.
length
>
0
?
'
+
'
:
''
)
+
(
this
.
model
.
mergeGroup
.
resources
.
length
>
0
?
'
!
'
:
''
);
this
.
raw
.
show
();
}
dispose
():
void
{
...
...
extensions/git/src/util.ts
浏览文件 @
3d6b1b71
...
...
@@ -28,6 +28,8 @@ export function combinedDisposable(disposables: IDisposable[]): IDisposable {
return
toDisposable
(()
=>
dispose
(
disposables
));
}
export
const
EmptyDisposable
=
toDisposable
(()
=>
null
);
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
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录