You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

difftree.go 3.1KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package object
  2. import (
  3. "bytes"
  4. "context"
  5. "github.com/go-git/go-git/v5/utils/merkletrie"
  6. "github.com/go-git/go-git/v5/utils/merkletrie/noder"
  7. )
  8. // DiffTree compares the content and mode of the blobs found via two
  9. // tree objects.
  10. // DiffTree does not perform rename detection, use DiffTreeWithOptions
  11. // instead to detect renames.
  12. func DiffTree(a, b *Tree) (Changes, error) {
  13. return DiffTreeContext(context.Background(), a, b)
  14. }
  15. // DiffTreeContext compares the content and mode of the blobs found via two
  16. // tree objects. Provided context must be non-nil.
  17. // An error will be returned if context expires.
  18. func DiffTreeContext(ctx context.Context, a, b *Tree) (Changes, error) {
  19. return DiffTreeWithOptions(ctx, a, b, nil)
  20. }
  21. // DiffTreeOptions are the configurable options when performing a diff tree.
  22. type DiffTreeOptions struct {
  23. // DetectRenames is whether the diff tree will use rename detection.
  24. DetectRenames bool
  25. // RenameScore is the threshold to of similarity between files to consider
  26. // that a pair of delete and insert are a rename. The number must be
  27. // exactly between 0 and 100.
  28. RenameScore uint
  29. // RenameLimit is the maximum amount of files that can be compared when
  30. // detecting renames. The number of comparisons that have to be performed
  31. // is equal to the number of deleted files * the number of added files.
  32. // That means, that if 100 files were deleted and 50 files were added, 5000
  33. // file comparisons may be needed. So, if the rename limit is 50, the number
  34. // of both deleted and added needs to be equal or less than 50.
  35. // A value of 0 means no limit.
  36. RenameLimit uint
  37. // OnlyExactRenames performs only detection of exact renames and will not perform
  38. // any detection of renames based on file similarity.
  39. OnlyExactRenames bool
  40. }
  41. // DefaultDiffTreeOptions are the default and recommended options for the
  42. // diff tree.
  43. var DefaultDiffTreeOptions = &DiffTreeOptions{
  44. DetectRenames: true,
  45. RenameScore: 60,
  46. RenameLimit: 0,
  47. OnlyExactRenames: false,
  48. }
  49. // DiffTreeWithOptions compares the content and mode of the blobs found
  50. // via two tree objects with the given options. The provided context
  51. // must be non-nil.
  52. // If no options are passed, no rename detection will be performed. The
  53. // recommended options are DefaultDiffTreeOptions.
  54. // An error will be returned if the context expires.
  55. // This function will be deprecated and removed in v6 so the default
  56. // behaviour of DiffTree is to detect renames.
  57. func DiffTreeWithOptions(
  58. ctx context.Context,
  59. a, b *Tree,
  60. opts *DiffTreeOptions,
  61. ) (Changes, error) {
  62. from := NewTreeRootNode(a)
  63. to := NewTreeRootNode(b)
  64. hashEqual := func(a, b noder.Hasher) bool {
  65. return bytes.Equal(a.Hash(), b.Hash())
  66. }
  67. merkletrieChanges, err := merkletrie.DiffTreeContext(ctx, from, to, hashEqual)
  68. if err != nil {
  69. if err == merkletrie.ErrCanceled {
  70. return nil, ErrCanceled
  71. }
  72. return nil, err
  73. }
  74. changes, err := newChanges(merkletrieChanges)
  75. if err != nil {
  76. return nil, err
  77. }
  78. if opts == nil {
  79. opts = new(DiffTreeOptions)
  80. }
  81. if opts.DetectRenames {
  82. return DetectRenames(changes, opts)
  83. }
  84. return changes, nil
  85. }