@@ -1106,12 +1106,14 @@ endfunction
1106
1106
function ! s: checkout (spec)
1107
1107
let sha = a: spec .commit
1108
1108
let output = s: git_revision (a: spec .dir )
1109
+ let error = 0
1109
1110
if ! empty (output) && ! s: hash_match (sha, s: lines (output)[0 ])
1110
1111
let credential_helper = s: git_version_requirement (2 ) ? ' -c credential.helper= ' : ' '
1111
1112
let output = s: system (
1112
1113
\ ' git ' .credential_helper.' fetch --depth 999999 && git checkout ' .plug#shellescape (sha).' --' , a: spec .dir )
1114
+ let error = v: shell_error
1113
1115
endif
1114
- return output
1116
+ return [ output, error ]
1115
1117
endfunction
1116
1118
1117
1119
function ! s: finish (pull)
@@ -1172,7 +1174,7 @@ function! s:update_impl(pull, force, args) abort
1172
1174
let threads = (len (args ) > 0 && args [-1 ] = ~ ' ^[1-9][0-9]*$' ) ?
1173
1175
\ remove (args , -1 ) : get (g: , ' plug_threads' , 16 )
1174
1176
1175
- let managed = filter (copy (g: plugs ), ' s:is_managed(v:key)' )
1177
+ let managed = filter (deepcopy (g: plugs ), ' s:is_managed(v:key)' )
1176
1178
let todo = empty (args ) ? filter (managed, ' !v:val.frozen || !isdirectory(v:val.dir)' ) :
1177
1179
\ filter (managed, ' index(args, v:key) >= 0' )
1178
1180
@@ -1306,9 +1308,11 @@ function! s:update_finish()
1306
1308
if ! pos
1307
1309
continue
1308
1310
endif
1311
+ let out = ' '
1312
+ let error = 0
1309
1313
if has_key (spec, ' commit' )
1310
1314
call s: log4 (name, ' Checking out ' .spec.commit)
1311
- let out = s: checkout (spec)
1315
+ let [ out, error ] = s: checkout (spec)
1312
1316
elseif has_key (spec, ' tag' )
1313
1317
let tag = spec.tag
1314
1318
if tag = ~ ' \*'
@@ -1321,19 +1325,16 @@ function! s:update_finish()
1321
1325
endif
1322
1326
call s: log4 (name, ' Checking out ' .tag )
1323
1327
let out = s: system (' git checkout -q ' .plug#shellescape (tag ).' -- 2>&1' , spec.dir )
1324
- else
1325
- let branch = s: git_origin_branch (spec)
1326
- call s: log4 (name, ' Merging origin/' .s: esc (branch))
1327
- let out = s: system (' git checkout -q ' .plug#shellescape (branch).' -- 2>&1'
1328
- \. (has_key (s: update .new , name) ? ' ' : (' && git merge --ff-only ' .plug#shellescape (' origin/' .branch).' 2>&1' )), spec.dir )
1328
+ let error = v: shell_error
1329
1329
endif
1330
- if ! v: shell_error && filereadable (spec.dir .' /.gitmodules' ) &&
1330
+ if ! error && filereadable (spec.dir .' /.gitmodules' ) &&
1331
1331
\ (s: update .force || has_key (s: update .new , name) || s: is_updated (spec.dir ))
1332
1332
call s: log4 (name, ' Updating submodules. This may take a while.' )
1333
1333
let out .= s: bang (' git submodule update --init --recursive' .s: submodule_opt .' 2>&1' , spec.dir )
1334
+ let error = v: shell_error
1334
1335
endif
1335
1336
let msg = s: format_message (v: shell_error ? ' x' : ' -' , name, out)
1336
- if v: shell_error
1337
+ if error
1337
1338
call add (s: update .errors, name)
1338
1339
call s: regress_bar ()
1339
1340
silent execute pos ' d _'
@@ -1396,7 +1397,9 @@ function! s:job_out_cb(self, data) abort
1396
1397
if ! self .running || self .tick % len (s: jobs ) == 0
1397
1398
let bullet = self .running ? (self .new ? ' +' : ' *' ) : (self .error ? ' x' : ' -' )
1398
1399
let result = self .error ? join (self .lines , " \n " ) : s: last_non_empty_line (self .lines )
1399
- call s: log (bullet, self .name, result)
1400
+ if len (result)
1401
+ call s: log (bullet, self .name, result)
1402
+ endif
1400
1403
endif
1401
1404
endfunction
1402
1405
@@ -1420,16 +1423,17 @@ function! s:nvim_cb(job_id, data, event) dict abort
1420
1423
\ s: job_cb (' s:job_exit_cb' , self , 0 , a: data )
1421
1424
endfunction
1422
1425
1423
- function ! s: spawn (name, cmd, opts)
1424
- let job = { ' name' : a: name , ' running' : 1 , ' error' : 0 , ' lines' : [' ' ],
1425
- \ ' new' : get (a: opts , ' new' , 0 ) }
1426
+ function ! s: spawn (name, spec, queue, opts)
1427
+ let job = { ' name' : a: name , ' spec' : a: spec , ' running' : 1 , ' error' : 0 , ' lines' : [' ' ],
1428
+ \ ' new' : get (a: opts , ' new' , 0 ), ' queue' : copy (a: queue ) }
1429
+ let Item = remove (job.queue, 0 )
1430
+ let argv = type (Item) == s: TYPE .funcref ? call (Item, [a: spec ]) : Item
1426
1431
let s: jobs [a: name ] = job
1427
1432
1428
1433
if s: nvim
1429
1434
if has_key (a: opts , ' dir' )
1430
1435
let job.cwd = a: opts .dir
1431
1436
endif
1432
- let argv = a: cmd
1433
1437
call extend (job, {
1434
1438
\ ' on_stdout' : function (' s:nvim_cb' ),
1435
1439
\ ' on_stderr' : function (' s:nvim_cb' ),
@@ -1445,7 +1449,7 @@ function! s:spawn(name, cmd, opts)
1445
1449
\ ' Invalid arguments (or job table is full)' ]
1446
1450
endif
1447
1451
elseif s: vim8
1448
- let cmd = join (map (copy (a: cmd ), ' plug#shellescape(v:val, {"script": 0})' ))
1452
+ let cmd = join (map (copy (argv ), ' plug#shellescape(v:val, {"script": 0})' ))
1449
1453
if has_key (a: opts , ' dir' )
1450
1454
let cmd = s: with_cd (cmd, a: opts .dir , 0 )
1451
1455
endif
@@ -1465,27 +1469,34 @@ function! s:spawn(name, cmd, opts)
1465
1469
let job.lines = [' Failed to start job' ]
1466
1470
endif
1467
1471
else
1468
- let job.lines = s: lines (call (' s:system' , has_key (a: opts , ' dir' ) ? [a: cmd , a: opts .dir ] : [a: cmd ]))
1472
+ let job.lines = s: lines (call (' s:system' , has_key (a: opts , ' dir' ) ? [argv , a: opts .dir ] : [argv ]))
1469
1473
let job.error = v: shell_error != 0
1470
1474
let job.running = 0
1471
1475
endif
1472
1476
endfunction
1473
1477
1474
1478
function ! s: reap (name)
1475
- let job = s: jobs[ a: name]
1479
+ let job = remove ( s: jobs, a: name)
1476
1480
if job.error
1477
1481
call add (s: update .errors, a: name )
1478
1482
elseif get (job, ' new' , 0 )
1479
1483
let s: update .new [a: name ] = 1
1480
1484
endif
1481
- let s: update .bar .= job.error ? ' x' : ' ='
1482
1485
1483
- let bullet = job.error ? ' x' : ' -'
1486
+ let more = len (get (job, ' queue' , []))
1487
+ let bullet = job.error ? ' x' : more ? (job.new ? ' +' : ' *' ) : ' -'
1484
1488
let result = job.error ? join (job.lines , " \n " ) : s: last_non_empty_line (job.lines )
1485
- call s: log (bullet, a: name , empty (result) ? ' OK' : result)
1486
- call s: bar ()
1489
+ if len (result)
1490
+ call s: log (bullet, a: name , result)
1491
+ endif
1487
1492
1488
- call remove (s: jobs , a: name )
1493
+ if ! job.error && more
1494
+ let job.spec.queue = job.queue
1495
+ let s: update .todo [a: name ] = job.spec
1496
+ else
1497
+ let s: update .bar .= job.error ? ' x' : ' ='
1498
+ call s: bar ()
1499
+ endif
1489
1500
endfunction
1490
1501
1491
1502
function ! s: bar ()
@@ -1538,6 +1549,16 @@ function! s:update_vim()
1538
1549
call s: tick ()
1539
1550
endfunction
1540
1551
1552
+ function ! s: checkout_command (spec)
1553
+ let a: spec .branch = s: git_origin_branch (a: spec )
1554
+ return [' git' , ' checkout' , ' -q' , a: spec .branch, ' --' ]
1555
+ endfunction
1556
+
1557
+ function ! s: merge_command (spec)
1558
+ let a: spec .branch = s: git_origin_branch (a: spec )
1559
+ return [' git' , ' merge' , ' --ff-only' , ' origin/' .a: spec .branch]
1560
+ endfunction
1561
+
1541
1562
function ! s: tick ()
1542
1563
let pull = s: update .pull
1543
1564
let prog = s: progress_opt (s: nvim || s: vim8 )
@@ -1552,13 +1573,18 @@ while 1 " Without TCO, Vim stack is bound to explode
1552
1573
1553
1574
let name = keys (s: update .todo )[0 ]
1554
1575
let spec = remove (s: update .todo , name)
1555
- let new = empty (globpath (spec.dir , ' .git' , 1 ))
1576
+ let queue = get (spec, ' queue' , [])
1577
+ let new = empty (globpath (spec.dir , ' .git' , 1 ))
1556
1578
1557
- call s: log (new ? ' +' : ' *' , name, pull ? ' Updating ...' : ' Installing ...' )
1558
- redraw
1579
+ if empty (queue)
1580
+ call s: log (new ? ' +' : ' *' , name, pull ? ' Updating ...' : ' Installing ...' )
1581
+ redraw
1582
+ endif
1559
1583
1560
1584
let has_tag = has_key (spec, ' tag' )
1561
- if ! new
1585
+ if len (queue)
1586
+ call s: spawn (name, spec, queue, { ' dir' : spec.dir })
1587
+ elseif ! new
1562
1588
let [error , _] = s: git_validate (spec, 0 )
1563
1589
if empty (error )
1564
1590
if pull
@@ -1569,7 +1595,11 @@ while 1 " Without TCO, Vim stack is bound to explode
1569
1595
if ! empty (prog)
1570
1596
call add (cmd, prog)
1571
1597
endif
1572
- call s: spawn (name, cmd, { ' dir' : spec.dir })
1598
+ let queue = [cmd, split (' git remote set-head origin -a' )]
1599
+ if ! has_tag && ! has_key (spec, ' commit' )
1600
+ call extend (queue, [function (' s:checkout_command' ), function (' s:merge_command' )])
1601
+ endif
1602
+ call s: spawn (name, spec, queue, { ' dir' : spec.dir })
1573
1603
else
1574
1604
let s: jobs [name] = { ' running' : 0 , ' lines' : [' Already installed' ], ' error' : 0 }
1575
1605
endif
@@ -1584,7 +1614,7 @@ while 1 " Without TCO, Vim stack is bound to explode
1584
1614
if ! empty (prog)
1585
1615
call add (cmd, prog)
1586
1616
endif
1587
- call s: spawn (name, extend (cmd, [spec.uri, s: trim (spec.dir )]), { ' new' : 1 })
1617
+ call s: spawn (name, spec, [ extend (cmd, [spec.uri, s: trim (spec.dir )]), function ( ' s:checkout_command ' ), function ( ' s:merge_command ' )] , { ' new' : 1 })
1588
1618
endif
1589
1619
1590
1620
if ! s: jobs [name].running
0 commit comments