walkObjectTree walks over all objects and remembers references to them in the objectWalker. This is used instead of the revlist walks because memory usage is tight with huge repos.
(hash plumbing.Hash)
| 52 | // to them in the objectWalker. This is used instead of the revlist |
| 53 | // walks because memory usage is tight with huge repos. |
| 54 | func (p *objectWalker) walkObjectTree(hash plumbing.Hash) error { |
| 55 | // Check if we have already seen, and mark this object |
| 56 | if p.isSeen(hash) { |
| 57 | return nil |
| 58 | } |
| 59 | p.add(hash) |
| 60 | // Fetch the object. |
| 61 | obj, err := object.GetObject(p.Storer, hash) |
| 62 | if err != nil { |
| 63 | return fmt.Errorf("getting object %s failed: %v", hash, err) |
| 64 | } |
| 65 | // Walk all children depending on object type. |
| 66 | switch obj := obj.(type) { |
| 67 | case *object.Commit: |
| 68 | err = p.walkObjectTree(obj.TreeHash) |
| 69 | if err != nil { |
| 70 | return err |
| 71 | } |
| 72 | for _, h := range obj.ParentHashes { |
| 73 | err = p.walkObjectTree(h) |
| 74 | if err != nil { |
| 75 | return err |
| 76 | } |
| 77 | } |
| 78 | case *object.Tree: |
| 79 | for i := range obj.Entries { |
| 80 | // Shortcut for blob objects: |
| 81 | // 'or' the lower bits of a mode and check that it |
| 82 | // it matches a filemode.Executable. The type information |
| 83 | // is in the higher bits, but this is the cleanest way |
| 84 | // to handle plain files with different modes. |
| 85 | // Other non-tree objects are somewhat rare, so they |
| 86 | // are not special-cased. |
| 87 | if obj.Entries[i].Mode|0755 == filemode.Executable { |
| 88 | p.add(obj.Entries[i].Hash) |
| 89 | continue |
| 90 | } |
| 91 | // Normal walk for sub-trees (and symlinks etc). |
| 92 | err = p.walkObjectTree(obj.Entries[i].Hash) |
| 93 | if err != nil { |
| 94 | return err |
| 95 | } |
| 96 | } |
| 97 | case *object.Tag: |
| 98 | return p.walkObjectTree(obj.Target) |
| 99 | default: |
| 100 | // Error out on unhandled object types. |
| 101 | return fmt.Errorf("unknown object %X %s %T", obj.ID(), obj.Type(), obj) |
| 102 | } |
| 103 | return nil |
| 104 | } |