GetAllNotes reads the contents of the notes under the given ref for every commit. The returned value is a mapping from commit hash to the list of notes for that commit. This is the batch version of the corresponding GetNotes(...) method.
(notesRef string)
| 875 | // |
| 876 | // This is the batch version of the corresponding GetNotes(...) method. |
| 877 | func (repo *GitRepo) GetAllNotes(notesRef string) (map[string][]Note, error) { |
| 878 | // This code is unfortunately quite complicated, but it needs to be so. |
| 879 | // |
| 880 | // Conceptually, this is equivalent to: |
| 881 | // result := make(map[string][]Note) |
| 882 | // for _, commit := range repo.ListNotedRevisions(notesRef) { |
| 883 | // result[commit] = repo.GetNotes(notesRef, commit) |
| 884 | // } |
| 885 | // return result, nil |
| 886 | // |
| 887 | // However, that logic would require separate executions of the 'git' |
| 888 | // command for every annotated commit. For a repo with 10s of thousands |
| 889 | // of reviews, that would mean calling Cmd.Run(...) 10s of thousands of |
| 890 | // times. That, in turn, would take so long that the tool would be unusable. |
| 891 | // |
| 892 | // This method avoids that by taking advantage of the 'git cat-file --batch="..."' |
| 893 | // command. That allows us to use a single invocation of Cmd.Run(...) to |
| 894 | // inspect multiple git objects at once. |
| 895 | // |
| 896 | // As such, regardless of the number of reviews in a repo, we can get all |
| 897 | // of the notes using a total of three invocations of Cmd.Run(...): |
| 898 | // 1. One to list all the annotated objects (and their notes hash) |
| 899 | // 2. A second one to filter out all of the annotated objects that are not commits. |
| 900 | // 3. A final one to get the contents of all of the notes blobs. |
| 901 | overview, err := repo.notesOverview(notesRef) |
| 902 | if err != nil { |
| 903 | return nil, err |
| 904 | } |
| 905 | isCommit, err := overview.getIsCommitMap(repo) |
| 906 | if err != nil { |
| 907 | return nil, fmt.Errorf("Failure building the set of commit objects: %v", err) |
| 908 | } |
| 909 | noteContentsMap, err := overview.getNoteContentsMap(repo) |
| 910 | if err != nil { |
| 911 | return nil, fmt.Errorf("Failure building the mapping from notes hash to contents: %v", err) |
| 912 | } |
| 913 | commitNotesMap := make(map[string][]Note) |
| 914 | for _, notesMapping := range overview.NotesMappings { |
| 915 | if !isCommit[*notesMapping.ObjectHash] { |
| 916 | continue |
| 917 | } |
| 918 | noteBytes := noteContentsMap[*notesMapping.NotesHash] |
| 919 | byteSlices := bytes.Split(noteBytes, []byte("\n")) |
| 920 | var notes []Note |
| 921 | for _, slice := range byteSlices { |
| 922 | notes = append(notes, Note(slice)) |
| 923 | } |
| 924 | commitNotesMap[*notesMapping.ObjectHash] = notes |
| 925 | } |
| 926 | |
| 927 | return commitNotesMap, nil |
| 928 | } |
| 929 | |
| 930 | // AppendNote appends a note to a revision under the given ref. |
| 931 | func (repo *GitRepo) AppendNote(notesRef, revision string, note Note) error { |
nothing calls this directly
no test coverage detected