github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/repo_commit_nogogit.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 //go:build !gogit 7 8 package git 9 10 import ( 11 "bufio" 12 "errors" 13 "io" 14 "strings" 15 16 "github.com/gitbundle/modules/log" 17 ) 18 19 // ResolveReference resolves a name to a reference 20 func (repo *Repository) ResolveReference(name string) (string, error) { 21 stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--hash", name).RunStdString(&RunOpts{Dir: repo.Path}) 22 if err != nil { 23 if strings.Contains(err.Error(), "not a valid ref") { 24 return "", ErrNotExist{name, ""} 25 } 26 return "", err 27 } 28 stdout = strings.TrimSpace(stdout) 29 if stdout == "" { 30 return "", ErrNotExist{name, ""} 31 } 32 33 return stdout, nil 34 } 35 36 // GetRefCommitID returns the last commit ID string of given reference (branch or tag). 37 func (repo *Repository) GetRefCommitID(name string) (string, error) { 38 wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) 39 defer cancel() 40 _, err := wr.Write([]byte(name + "\n")) 41 if err != nil { 42 return "", err 43 } 44 shaBs, _, _, err := ReadBatchLine(rd) 45 if IsErrNotExist(err) { 46 return "", ErrNotExist{name, ""} 47 } 48 49 return string(shaBs), nil 50 } 51 52 // SetReference sets the commit ID string of given reference (e.g. branch or tag). 53 func (repo *Repository) SetReference(name, commitID string) error { 54 _, _, err := NewCommand(repo.Ctx, "update-ref", name, commitID).RunStdString(&RunOpts{Dir: repo.Path}) 55 return err 56 } 57 58 // RemoveReference removes the given reference (e.g. branch or tag). 59 func (repo *Repository) RemoveReference(name string) error { 60 _, _, err := NewCommand(repo.Ctx, "update-ref", "--no-deref", "-d", name).RunStdString(&RunOpts{Dir: repo.Path}) 61 return err 62 } 63 64 // IsCommitExist returns true if given commit exists in current repository. 65 func (repo *Repository) IsCommitExist(name string) bool { 66 _, _, err := NewCommand(repo.Ctx, "cat-file", "-e", name).RunStdString(&RunOpts{Dir: repo.Path}) 67 return err == nil 68 } 69 70 func (repo *Repository) getCommit(id SHA1) (*Commit, error) { 71 wr, rd, cancel := repo.CatFileBatch(repo.Ctx) 72 defer cancel() 73 74 _, _ = wr.Write([]byte(id.String() + "\n")) 75 76 return repo.getCommitFromBatchReader(rd, id) 77 } 78 79 func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Commit, error) { 80 _, typ, size, err := ReadBatchLine(rd) 81 if err != nil { 82 if errors.Is(err, io.EOF) || IsErrNotExist(err) { 83 return nil, ErrNotExist{ID: id.String()} 84 } 85 return nil, err 86 } 87 88 switch typ { 89 case "missing": 90 return nil, ErrNotExist{ID: id.String()} 91 case "tag": 92 // then we need to parse the tag 93 // and load the commit 94 data, err := io.ReadAll(io.LimitReader(rd, size)) 95 if err != nil { 96 return nil, err 97 } 98 _, err = rd.Discard(1) 99 if err != nil { 100 return nil, err 101 } 102 tag, err := parseTagData(data) 103 if err != nil { 104 return nil, err 105 } 106 107 commit, err := tag.Commit(repo) 108 if err != nil { 109 return nil, err 110 } 111 112 commit.CommitMessage = strings.TrimSpace(tag.Message) 113 commit.Author = tag.Tagger 114 commit.Signature = tag.Signature 115 116 return commit, nil 117 case "commit": 118 commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size)) 119 if err != nil { 120 return nil, err 121 } 122 _, err = rd.Discard(1) 123 if err != nil { 124 return nil, err 125 } 126 127 return commit, nil 128 default: 129 log.Debug("Unknown typ: %s", typ) 130 _, err = rd.Discard(int(size) + 1) 131 if err != nil { 132 return nil, err 133 } 134 return nil, ErrNotExist{ 135 ID: id.String(), 136 } 137 } 138 } 139 140 // ConvertToSHA1 returns a Hash object from a potential ID string 141 func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { 142 if len(commitID) == 40 && SHAPattern.MatchString(commitID) { 143 sha1, err := NewIDFromString(commitID) 144 if err == nil { 145 return sha1, nil 146 } 147 } 148 149 wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) 150 defer cancel() 151 _, err := wr.Write([]byte(commitID + "\n")) 152 if err != nil { 153 return SHA1{}, err 154 } 155 sha, _, _, err := ReadBatchLine(rd) 156 if err != nil { 157 if IsErrNotExist(err) { 158 return SHA1{}, ErrNotExist{commitID, ""} 159 } 160 return SHA1{}, err 161 } 162 163 return MustIDFromString(string(sha)), nil 164 }