1
1
import { debounce } from "debounce" ;
2
2
import * as vscode from "vscode" ;
3
3
import config from "./config" ;
4
- import { ForcePushMode , GitAPI , Repository } from "./git" ;
4
+ import { ForcePushMode , GitAPI , Repository , getSubmodule } from "./git" ; // Import getSubmodule from src/git.ts
5
5
import { DateTime } from "luxon" ;
6
6
import { store } from "./store" ;
7
7
import { reaction } from "mobx" ;
@@ -11,16 +11,26 @@ const REMOTE_NAME = "origin";
11
11
12
12
async function pushRepository (
13
13
repository : Repository ,
14
- forcePush : boolean = false
14
+ forcePush : boolean = false ,
15
+ submodule ?: string // Add a submodule name as an optional parameter
15
16
) {
16
17
store . isPushing = true ;
17
18
18
19
try {
19
20
if ( config . autoPull === "onPush" ) {
20
- await pullRepository ( repository ) ;
21
+ await pullRepository ( repository , submodule ) ; // Pass the submodule name to pullRepository
21
22
}
22
23
23
- const pushArgs : any [ ] = [ REMOTE_NAME , repository . state . HEAD ?. name , false ] ;
24
+ const pushArgs : any [ ] = [ REMOTE_NAME ] ;
25
+
26
+ // If pushing a submodule, use the submodule name as the branch name
27
+ if ( submodule ) {
28
+ pushArgs . push ( submodule ) ;
29
+ } else {
30
+ pushArgs . push ( repository . state . HEAD ?. name ) ;
31
+ }
32
+
33
+ pushArgs . push ( false ) ;
24
34
25
35
if ( forcePush ) {
26
36
pushArgs . push ( ForcePushMode . Force ) ;
@@ -45,15 +55,22 @@ async function pushRepository(
45
55
"Force Push"
46
56
)
47
57
) {
48
- await pushRepository ( repository , true ) ;
58
+ await pushRepository ( repository , true , submodule ) ; // Pass the submodule name to pushRepository
49
59
}
50
60
}
51
61
}
52
62
53
- async function pullRepository ( repository : Repository ) {
63
+ async function pullRepository ( repository : Repository , submodule ?: string ) { // Add a submodule name as an optional parameter
54
64
store . isPulling = true ;
55
65
56
- await repository . pull ( ) ;
66
+ const pullArgs : any [ ] = [ ] ;
67
+
68
+ // If pulling a submodule, use the submodule name as the refspec
69
+ if ( submodule ) {
70
+ pullArgs . push ( REMOTE_NAME , submodule ) ;
71
+ }
72
+
73
+ await repository . pull ( ...pullArgs ) ;
57
74
58
75
store . isPulling = false ;
59
76
}
@@ -70,64 +87,73 @@ export async function commit(repository: Repository, message?: string) {
70
87
] ;
71
88
72
89
if ( changes . length > 0 ) {
73
- const changedUris = changes
74
- . filter ( ( change ) => matches ( change . uri ) )
75
- . map ( ( change ) => change . uri ) ;
76
-
77
- if ( changedUris . length > 0 ) {
78
- if ( config . commitValidationLevel !== "none" ) {
79
- const diagnostics = vscode . languages
80
- . getDiagnostics ( )
81
- . filter ( ( [ uri , diagnostics ] ) => {
82
- const isChanged = changedUris . find (
83
- ( changedUri ) =>
84
- changedUri . toString ( ) . localeCompare ( uri . toString ( ) ) === 0
85
- ) ;
86
-
87
- return isChanged
88
- ? diagnostics . some (
89
- ( diagnostic ) =>
90
- diagnostic . severity === vscode . DiagnosticSeverity . Error ||
91
- ( config . commitValidationLevel === "warning" &&
92
- diagnostic . severity === vscode . DiagnosticSeverity . Warning )
93
- )
94
- : false ;
95
- } ) ;
96
-
97
- if ( diagnostics . length > 0 ) {
98
- return ;
90
+ // Group changes by submodule name, using null for the main repository
91
+ const changesBySubmodule = new Map < string | null , vscode . Uri [ ] > ( ) ;
92
+ for ( const change of changes ) {
93
+ const submodule = change . submodule || null ; // Use the submodule property of the change
94
+ const changedUris = changesBySubmodule . get ( submodule ) || [ ] ;
95
+ changedUris . push ( change . uri ) ;
96
+ changesBySubmodule . set ( submodule , changedUris ) ;
97
+ }
98
+
99
+ // Filter the changes by the file pattern and commit them to each submodule first, then to the main repository
100
+ for ( const [ submodule , changedUris ] of changesBySubmodule ) {
101
+ const filteredUris = changedUris . filter ( ( uri ) => matches ( uri ) ) ;
102
+ if ( filteredUris . length > 0 ) {
103
+ if ( config . commitValidationLevel !== "none" ) {
104
+ const diagnostics = vscode . languages
105
+ . getDiagnostics ( )
106
+ . filter ( ( [ uri , diagnostics ] ) => {
107
+ const isChanged = filteredUris . find (
108
+ ( changedUri ) =>
109
+ changedUri . toString ( ) . localeCompare ( uri . toString ( ) ) === 0
110
+ ) ;
111
+
112
+ return isChanged
113
+ ? diagnostics . some (
114
+ ( diagnostic ) =>
115
+ diagnostic . severity === vscode . DiagnosticSeverity . Error ||
116
+ ( config . commitValidationLevel === "warning" &&
117
+ diagnostic . severity === vscode . DiagnosticSeverity . Warning )
118
+ )
119
+ : false ;
120
+ } ) ;
121
+
122
+ if ( diagnostics . length > 0 ) {
123
+ return ;
124
+ }
99
125
}
100
- }
101
126
102
- // @ts -ignore
103
- await repository . repository . add ( changedUris ) ;
104
- let currentTime = DateTime . now ( ) ;
127
+ // @ts -ignore
128
+ await repository . repository . add ( filteredUris ) ;
129
+ let currentTime = DateTime . now ( ) ;
105
130
106
- // Ensure that the commit dates are formatted
107
- // as UTC, so that other clients can properly
108
- // re-offset them based on the user's locale.
109
- const commitDate = currentTime . toUTC ( ) . toString ( ) ;
110
- process . env . GIT_AUTHOR_DATE = commitDate ;
111
- process . env . GIT_COMMITTER_DATE = commitDate ;
131
+ // Ensure that the commit dates are formatted
132
+ // as UTC, so that other clients can properly
133
+ // re-offset them based on the user's locale.
134
+ const commitDate = currentTime . toUTC ( ) . toString ( ) ;
135
+ process . env . GIT_AUTHOR_DATE = commitDate ;
136
+ process . env . GIT_COMMITTER_DATE = commitDate ;
112
137
113
- if ( config . timeZone ) {
114
- currentTime = currentTime . setZone ( config . timeZone ) ;
115
- }
138
+ if ( config . timeZone ) {
139
+ currentTime = currentTime . setZone ( config . timeZone ) ;
140
+ }
116
141
117
- const commitMessage =
118
- message || currentTime . toFormat ( config . commitMessageFormat ) ;
142
+ const commitMessage =
143
+ message || currentTime . toFormat ( config . commitMessageFormat ) ;
119
144
120
- await repository . commit ( commitMessage ) ;
145
+ await repository . commit ( commitMessage ) ;
121
146
122
- delete process . env . GIT_AUTHOR_DATE ;
123
- delete process . env . GIT_COMMITTER_DATE ;
147
+ delete process . env . GIT_AUTHOR_DATE ;
148
+ delete process . env . GIT_COMMITTER_DATE ;
124
149
125
- if ( config . autoPush === "onCommit" ) {
126
- await pushRepository ( repository ) ;
127
- }
150
+ if ( config . autoPush === "onCommit" ) {
151
+ await pushRepository ( repository , false , submodule ) ; // Pass the submodule name to pushRepository
152
+ }
128
153
129
- if ( config . autoPull === "onCommit" ) {
130
- await pullRepository ( repository ) ;
154
+ if ( config . autoPull === "onCommit" ) {
155
+ await pullRepository ( repository , submodule ) ; // Pass the submodule name to pullRepository
156
+ }
131
157
}
132
158
}
133
159
}
@@ -165,8 +191,11 @@ export function ensureStatusBarItem() {
165
191
166
192
let disposables : vscode . Disposable [ ] = [ ] ;
167
193
export function watchForChanges ( git : GitAPI ) : vscode . Disposable {
168
- const commitAfterDelay = debouncedCommit ( git . repositories [ 0 ] ) ;
169
- disposables . push ( git . repositories [ 0 ] . state . onDidChange ( commitAfterDelay ) ) ;
194
+ // Iterate over all repositories, not just the first one
195
+ for ( const repository of git . repositories ) {
196
+ const commitAfterDelay = debouncedCommit ( repository ) ;
197
+ disposables . push ( repository . state . onDidChange ( commitAfterDelay ) ) ;
198
+ }
170
199
171
200
ensureStatusBarItem ( ) ;
172
201
@@ -198,7 +227,10 @@ export function watchForChanges(git: GitAPI): vscode.Disposable {
198
227
199
228
if ( config . autoPush === "afterDelay" ) {
200
229
const interval = setInterval ( async ( ) => {
201
- pushRepository ( git . repositories [ 0 ] ) ;
230
+ // Push changes to each repository separately
231
+ for ( const repository of git . repositories ) {
232
+ await pushRepository ( repository ) ;
233
+ }
202
234
} , config . autoPushDelay ) ;
203
235
204
236
disposables . push ( {
@@ -209,10 +241,12 @@ export function watchForChanges(git: GitAPI): vscode.Disposable {
209
241
}
210
242
211
243
if ( config . autoPull === "afterDelay" ) {
212
- const interval = setInterval (
213
- async ( ) => pullRepository ( git . repositories [ 0 ] ) ,
214
- config . autoPullDelay
215
- ) ;
244
+ const interval = setInterval ( async ( ) => {
245
+ // Pull changes from each repository separately
246
+ for ( const repository of git . repositories ) {
247
+ await pullRepository ( repository ) ;
248
+ }
249
+ } , config . autoPullDelay ) ;
216
250
217
251
disposables . push ( {
218
252
dispose : ( ) => clearInterval ( interval ) ,
@@ -236,7 +270,10 @@ export function watchForChanges(git: GitAPI): vscode.Disposable {
236
270
} ) ;
237
271
238
272
if ( config . pullOnOpen ) {
239
- pullRepository ( git . repositories [ 0 ] ) ;
273
+ // Pull changes from each repository separately
274
+ for ( const repository of git . repositories ) {
275
+ pullRepository ( repository ) ;
276
+ }
240
277
}
241
278
242
279
return {
0 commit comments