@@ -146,47 +146,61 @@ func AnnexInit(description string) error {
146
146
return nil
147
147
}
148
148
149
+ // parseSyncErrors should be used by all annex sync commands to check the
150
+ // output for common error messages and return the appropriate gin message.
151
+ func parseSyncErrors (messages string ) error {
152
+ if strings .Contains (messages , "Permission denied" ) {
153
+ return fmt .Errorf ("permission denied" )
154
+ } else if strings .Contains (messages , "Host key verification failed" ) {
155
+ // Bad host key configured
156
+ return fmt .Errorf ("server key does not match known host key" )
157
+ }
158
+ return nil
159
+ }
160
+
149
161
// AnnexPull downloads all annexed files. Optionally also downloads all file content.
150
162
// (git annex sync --no-push [--content])
151
163
func AnnexPull (remote string ) error {
152
164
args := []string {"sync" , "--verbose" , "--no-push" , "--no-commit" , remote }
153
165
cmd := AnnexCommand (args ... )
154
166
stdout , stderr , err := cmd .OutputError ()
155
- cmd .Wait ()
156
167
sstdout := string (stdout )
157
168
sstderr := string (stderr )
158
- if err != nil {
159
- log .Write ("Error during AnnexPull." )
169
+
170
+ // some errors don't return with an error status, so we need to check
171
+ // stderr for common error strings
172
+ if err := parseSyncErrors (sstderr ); err != nil {
173
+ return fmt .Errorf ("download failed: %v" , err )
174
+ }
175
+
176
+ // some conflicts are resolved automatically and don't produce an error in some combinations
177
+ if err := checkMergeErrors (sstdout , sstderr ); err != nil {
178
+ mergeAbort () // abort a potential failed merge attempt
179
+ return fmt .Errorf ("download failed: %v" , err )
180
+ }
181
+
182
+ if err != nil { // command actually failed
183
+ log .Write ("Error during AnnexPull" )
160
184
log .Write ("[Error]: %v" , err )
161
185
logstd (stdout , stderr )
162
- mergeAbort () // abort a potential failed merge attempt
163
- // TODO: Use giterror
164
- if strings .Contains (sstderr , "Permission denied" ) {
165
- return fmt .Errorf ("download failed: permission denied" )
166
- } else if strings .Contains (sstderr , "Host key verification failed" ) {
167
- // Bad host key configured
168
- return fmt .Errorf ("download failed: server key does not match known host key" )
169
- } else {
170
- err = checkMergeErrors (sstdout , sstderr )
171
- if err == nil {
172
- err = fmt .Errorf ("failed" )
173
- }
174
- return err
175
- }
186
+ mergeAbort () // abort a potential failed merge attempt (that wasn't caught earlier)
187
+
188
+ // since we don't know what the error was, show the internal annex sync
189
+ // error to the user
190
+ return fmt .Errorf ("download failed: %s" , sstderr )
176
191
}
177
192
178
- // some conflicts are resolved automatically and don't produce an error in some combinations
179
- return checkMergeErrors (sstdout , sstderr )
193
+ return nil
180
194
}
181
195
182
196
func checkMergeErrors (stdout , stderr string ) error {
183
197
messages := strings .ToLower (stdout + stderr )
184
198
if strings .Contains (messages , "would be overwritten by merge" ) {
185
199
// Untracked local file conflicts with file being pulled
186
- return fmt .Errorf ("download failed: local modified or untracked files would be overwritten by download:\n %s" , strings .Join (parseFilesOverwrite (messages ), ", " ))
200
+ return fmt .Errorf ("local modified or untracked files would be overwritten by download:\n %s" , strings .Join (parseFilesOverwrite (messages ), ", " ))
187
201
} else if strings .Contains (messages , "unresolved conflict" ) {
188
202
// Merge conflict in git files
189
- return fmt .Errorf ("download failed: files changed locally and remotely and cannot be automatically merged (merge conflict):\n %s" , strings .Join (parseFilesConflict (messages ), ", " ))
203
+ return fmt .Errorf ("files changed locally and remotely and cannot be automatically merged (merge conflict):\n %s" , strings .Join (parseFilesConflict (messages ), ", " ))
190
204
// abort merge
191
205
} else if strings .Contains (messages , "merge conflict was automatically resolved" ) {
192
206
// Merge conflict in annex files (automatically resolved by keeping both copies)
@@ -206,12 +220,30 @@ func AnnexSync(content bool) error {
206
220
}
207
221
cmd := AnnexCommand (cmdargs ... )
208
222
stdout , stderr , err := cmd .OutputError ()
209
- cmd .Wait ()
210
- if err != nil {
211
- log .Write ("Error during AnnexSync." )
223
+ sstdout := string (stdout )
224
+ sstderr := string (stderr )
225
+
226
+ // some errors don't return with an error status, so we need to check
227
+ // stderr for common error strings
228
+ if err := parseSyncErrors (sstderr ); err != nil {
229
+ return fmt .Errorf ("sync failed: %v" , err )
230
+ }
231
+
232
+ // some conflicts are resolved automatically and don't produce an error in some combinations
233
+ if err := checkMergeErrors (sstdout , sstderr ); err != nil {
234
+ mergeAbort () // abort a potential failed merge attempt
235
+ return fmt .Errorf ("sync failed: %v" , err )
236
+ }
237
+
238
+ if err != nil { // command actually failed
239
+ log .Write ("Error during AnnexSync" )
212
240
log .Write ("[Error]: %v" , err )
213
241
logstd (stdout , stderr )
214
- return fmt .Errorf (string (stderr ))
242
+ mergeAbort () // abort a potential failed merge attempt (that wasn't caught earlier)
243
+
244
+ // since we don't know what the error was, show the internal annex sync
245
+ // error to the user
246
+ return fmt .Errorf ("sync failed: %s" , sstderr )
215
247
}
216
248
return nil
217
249
}
@@ -267,20 +299,24 @@ func AnnexPush(paths []string, remote string, pushchan chan<- RepoFileStatus) {
267
299
defer close (pushchan )
268
300
cmd := AnnexCommand ("sync" , "--verbose" , "--no-pull" , "--no-commit" , remote ) // NEVER commit changes when doing annex-sync
269
301
stdout , stderr , err := cmd .OutputError ()
270
- if err != nil {
271
- log .Write ("Error during AnnexPush (sync --no-pull)" )
302
+ sstderr := string (stderr )
303
+
304
+ // some errors don't return with an error status, so we need to check
305
+ // stderr for common error strings
306
+ if err := parseSyncErrors (sstderr ); err != nil {
307
+ pushchan <- RepoFileStatus {Err : fmt .Errorf ("upload failed: %v" , err )}
308
+ return
309
+ }
310
+
311
+ if err != nil { // command actually failed
312
+ log .Write ("Error during AnnexPush" )
272
313
log .Write ("[Error]: %v" , err )
273
314
logstd (stdout , stderr )
274
- errmsg := "failed"
275
- sstderr := string (stderr )
276
- if strings .Contains (sstderr , "Permission denied" ) {
277
- errmsg = "upload failed: permission denied"
278
- } else if strings .Contains (sstderr , "Host key verification failed" ) {
279
- errmsg = "upload failed: server key does not match known host key"
280
- } else if strings .Contains (sstderr , "rejected" ) {
281
- errmsg = "upload failed: changes were made on the server that have not been downloaded; run 'gin download' to update local copies"
282
- }
283
- pushchan <- RepoFileStatus {Err : fmt .Errorf (errmsg )}
315
+ mergeAbort () // abort a potential failed merge attempt (that wasn't caught earlier)
316
+
317
+ // since we don't know what the error was, show the internal annex sync
318
+ // error to the user
319
+ pushchan <- RepoFileStatus {Err : fmt .Errorf (sstderr )}
284
320
return
285
321
}
286
322
0 commit comments