@@ -107,7 +107,10 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error {
107
107
return err
108
108
}
109
109
110
- if err := w .Reset (& ResetOptions {Commit : ref .Hash ()}); err != nil {
110
+ if err := w .Reset (& ResetOptions {
111
+ Mode : MergeReset ,
112
+ Commit : ref .Hash (),
113
+ }); err != nil {
111
114
return err
112
115
}
113
116
@@ -270,65 +273,99 @@ func (w *Worktree) Reset(opts *ResetOptions) error {
270
273
}
271
274
}
272
275
273
- changes , err := w .diffCommitWithStaging (opts .Commit , true )
274
- if err != nil {
276
+ if err := w .setHEADCommit (opts .Commit ); err != nil {
275
277
return err
276
278
}
277
279
278
- idx , err := w .r .Storer .Index ()
279
- if err != nil {
280
- return err
280
+ if opts .Mode == SoftReset {
281
+ return nil
281
282
}
282
283
283
284
t , err := w .getTreeFromCommitHash (opts .Commit )
284
285
if err != nil {
285
286
return err
286
287
}
287
288
288
- for _ , ch := range changes {
289
- if err := w .checkoutChange ( ch , t , idx ); err != nil {
289
+ if opts . Mode == MixedReset || opts . Mode == MergeReset || opts . Mode == HardReset {
290
+ if err := w .resetIndex ( t ); err != nil {
290
291
return err
291
292
}
292
293
}
293
294
294
- if err := w .r .Storer .SetIndex (idx ); err != nil {
295
- return err
295
+ if opts .Mode == MergeReset || opts .Mode == HardReset {
296
+ if err := w .resetWorktree (t ); err != nil {
297
+ return err
298
+ }
296
299
}
297
300
298
- return w . setHEADCommit ( opts . Commit )
301
+ return nil
299
302
}
300
303
301
- func (w * Worktree ) containsUnstagedChanges () ( bool , error ) {
302
- ch , err := w .diffStagingWithWorktree ()
304
+ func (w * Worktree ) resetIndex ( t * object. Tree ) error {
305
+ idx , err := w .r . Storer . Index ()
303
306
if err != nil {
304
- return false , err
307
+ return err
305
308
}
306
309
307
- return len (ch ) != 0 , nil
308
- }
309
-
310
- func (w * Worktree ) setHEADCommit (commit plumbing.Hash ) error {
311
- head , err := w .r .Reference (plumbing .HEAD , false )
310
+ changes , err := w .diffTreeWithStaging (t , true )
312
311
if err != nil {
313
312
return err
314
313
}
315
314
316
- if head .Type () == plumbing .HashReference {
317
- head = plumbing .NewHashReference (plumbing .HEAD , commit )
318
- return w .r .Storer .SetReference (head )
315
+ for _ , ch := range changes {
316
+ a , err := ch .Action ()
317
+ if err != nil {
318
+ return err
319
+ }
320
+
321
+ var name string
322
+ var e * object.TreeEntry
323
+
324
+ switch a {
325
+ case merkletrie .Modify , merkletrie .Insert :
326
+ name = ch .To .String ()
327
+ e , err = t .FindEntry (name )
328
+ if err != nil {
329
+ return err
330
+ }
331
+ case merkletrie .Delete :
332
+ name = ch .From .String ()
333
+ }
334
+
335
+ _ , _ = idx .Remove (name )
336
+ if e == nil {
337
+ continue
338
+ }
339
+
340
+ idx .Entries = append (idx .Entries , & index.Entry {
341
+ Name : name ,
342
+ Hash : e .Hash ,
343
+ Mode : e .Mode ,
344
+ })
345
+
319
346
}
320
347
321
- branch , err := w .r .Reference (head .Target (), false )
348
+ return w .r .Storer .SetIndex (idx )
349
+ }
350
+
351
+ func (w * Worktree ) resetWorktree (t * object.Tree ) error {
352
+ changes , err := w .diffStagingWithWorktree (true )
322
353
if err != nil {
323
354
return err
324
355
}
325
356
326
- if ! branch .Name ().IsBranch () {
327
- return fmt .Errorf ("invalid HEAD target should be a branch, found %s" , branch .Type ())
357
+ idx , err := w .r .Storer .Index ()
358
+ if err != nil {
359
+ return err
328
360
}
329
361
330
- branch = plumbing .NewHashReference (branch .Name (), commit )
331
- return w .r .Storer .SetReference (branch )
362
+ for _ , ch := range changes {
363
+ if err := w .checkoutChange (ch , t , idx ); err != nil {
364
+ return err
365
+ }
366
+ }
367
+
368
+ return w .r .Storer .SetIndex (idx )
332
369
}
333
370
334
371
func (w * Worktree ) checkoutChange (ch merkletrie.Change , t * object.Tree , idx * index.Index ) error {
@@ -351,13 +388,7 @@ func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *ind
351
388
352
389
isSubmodule = e .Mode == filemode .Submodule
353
390
case merkletrie .Delete :
354
- name = ch .From .String ()
355
- ie , err := idx .Entry (name )
356
- if err != nil {
357
- return err
358
- }
359
-
360
- isSubmodule = ie .Mode == filemode .Submodule
391
+ return rmFileAndDirIfEmpty (w .Filesystem , ch .From .String ())
361
392
}
362
393
363
394
if isSubmodule {
@@ -367,6 +398,52 @@ func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *ind
367
398
return w .checkoutChangeRegularFile (name , a , t , e , idx )
368
399
}
369
400
401
+ func (w * Worktree ) containsUnstagedChanges () (bool , error ) {
402
+ ch , err := w .diffStagingWithWorktree (false )
403
+ if err != nil {
404
+ return false , err
405
+ }
406
+
407
+ for _ , c := range ch {
408
+ a , err := c .Action ()
409
+ if err != nil {
410
+ return false , err
411
+ }
412
+
413
+ if a == merkletrie .Insert {
414
+ continue
415
+ }
416
+
417
+ return true , nil
418
+ }
419
+
420
+ return false , nil
421
+ }
422
+
423
+ func (w * Worktree ) setHEADCommit (commit plumbing.Hash ) error {
424
+ head , err := w .r .Reference (plumbing .HEAD , false )
425
+ if err != nil {
426
+ return err
427
+ }
428
+
429
+ if head .Type () == plumbing .HashReference {
430
+ head = plumbing .NewHashReference (plumbing .HEAD , commit )
431
+ return w .r .Storer .SetReference (head )
432
+ }
433
+
434
+ branch , err := w .r .Reference (head .Target (), false )
435
+ if err != nil {
436
+ return err
437
+ }
438
+
439
+ if ! branch .Name ().IsBranch () {
440
+ return fmt .Errorf ("invalid HEAD target should be a branch, found %s" , branch .Type ())
441
+ }
442
+
443
+ branch = plumbing .NewHashReference (branch .Name (), commit )
444
+ return w .r .Storer .SetReference (branch )
445
+ }
446
+
370
447
func (w * Worktree ) checkoutChangeSubmodule (name string ,
371
448
a merkletrie.Action ,
372
449
e * object.TreeEntry ,
@@ -383,17 +460,7 @@ func (w *Worktree) checkoutChangeSubmodule(name string,
383
460
return nil
384
461
}
385
462
386
- if err := w .rmIndexFromFile (name , idx ); err != nil {
387
- return err
388
- }
389
-
390
- if err := w .addIndexFromTreeEntry (name , e , idx ); err != nil {
391
- return err
392
- }
393
-
394
- // TODO: the submodule update should be reviewed as reported at:
395
- // https://github.com/src-d/go-git/issues/415
396
- return sub .update (context .TODO (), & SubmoduleUpdateOptions {}, e .Hash )
463
+ return w .addIndexFromTreeEntry (name , e , idx )
397
464
case merkletrie .Insert :
398
465
mode , err := e .Mode .ToOSFileMode ()
399
466
if err != nil {
@@ -405,12 +472,6 @@ func (w *Worktree) checkoutChangeSubmodule(name string,
405
472
}
406
473
407
474
return w .addIndexFromTreeEntry (name , e , idx )
408
- case merkletrie .Delete :
409
- if err := rmFileAndDirIfEmpty (w .Filesystem , name ); err != nil {
410
- return err
411
- }
412
-
413
- return w .rmIndexFromFile (name , idx )
414
475
}
415
476
416
477
return nil
@@ -424,9 +485,7 @@ func (w *Worktree) checkoutChangeRegularFile(name string,
424
485
) error {
425
486
switch a {
426
487
case merkletrie .Modify :
427
- if err := w .rmIndexFromFile (name , idx ); err != nil {
428
- return err
429
- }
488
+ _ , _ = idx .Remove (name )
430
489
431
490
// to apply perm changes the file is deleted, billy doesn't implement
432
491
// chmod
@@ -446,12 +505,6 @@ func (w *Worktree) checkoutChangeRegularFile(name string,
446
505
}
447
506
448
507
return w .addIndexFromFile (name , e .Hash , idx )
449
- case merkletrie .Delete :
450
- if err := rmFileAndDirIfEmpty (w .Filesystem , name ); err != nil {
451
- return err
452
- }
453
-
454
- return w .rmIndexFromFile (name , idx )
455
508
}
456
509
457
510
return nil
@@ -503,6 +556,7 @@ func (w *Worktree) checkoutFileSymlink(f *object.File) (err error) {
503
556
}
504
557
505
558
func (w * Worktree ) addIndexFromTreeEntry (name string , f * object.TreeEntry , idx * index.Index ) error {
559
+ _ , _ = idx .Remove (name )
506
560
idx .Entries = append (idx .Entries , & index.Entry {
507
561
Hash : f .Hash ,
508
562
Name : name ,
@@ -513,6 +567,7 @@ func (w *Worktree) addIndexFromTreeEntry(name string, f *object.TreeEntry, idx *
513
567
}
514
568
515
569
func (w * Worktree ) addIndexFromFile (name string , h plumbing.Hash , idx * index.Index ) error {
570
+ _ , _ = idx .Remove (name )
516
571
fi , err := w .Filesystem .Lstat (name )
517
572
if err != nil {
518
573
return err
@@ -541,19 +596,6 @@ func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *index.Ind
541
596
return nil
542
597
}
543
598
544
- func (w * Worktree ) rmIndexFromFile (name string , idx * index.Index ) error {
545
- for i , e := range idx .Entries {
546
- if e .Name != name {
547
- continue
548
- }
549
-
550
- idx .Entries = append (idx .Entries [:i ], idx .Entries [i + 1 :]... )
551
- return nil
552
- }
553
-
554
- return nil
555
- }
556
-
557
599
func (w * Worktree ) getTreeFromCommitHash (commit plumbing.Hash ) (* object.Tree , error ) {
558
600
c , err := w .r .CommitObject (commit )
559
601
if err != nil {
0 commit comments