forked from tangled.org/core
this repo has no description

knotserver: git: rework commitsBetween to use rev-list

the previous commit iterator approach was faulty in cases of merge
commits, as it only uses the first parent returned by .Parents().

this also makes use of the --no-merges flag when preparing commits for
format-patch.

Signed-off-by: oppiliappan <me@oppi.li>

authored by oppi.li and committed by Tangled 1e4fe088 d0a83d20

Changed files
+15 -13
knotserver
git
+15 -13
knotserver/git/diff.go
··· 205 205 206 206 func (g *GitRepo) commitsBetween(newCommit, oldCommit *object.Commit) ([]*object.Commit, error) { 207 207 var commits []*object.Commit 208 - current := newCommit 209 208 210 - for { 211 - if current.Hash == oldCommit.Hash { 212 - break 213 - } 214 - 215 - commits = append(commits, current) 209 + output, err := g.revList( 210 + "--no-merges", // format-patch explicitly prepares only non-merges 211 + fmt.Sprintf("%s..%s", oldCommit.Hash.String(), newCommit.Hash.String()), 212 + ) 213 + if err != nil { 214 + return nil, fmt.Errorf("revlist: %w", err) 215 + } 216 216 217 - if len(current.ParentHashes) == 0 { 218 - return nil, fmt.Errorf("old commit %s not found in history of new commit %s", oldCommit.Hash, newCommit.Hash) 219 - } 217 + lines := strings.Split(strings.TrimSpace(string(output)), "\n") 218 + if len(lines) == 1 && lines[0] == "" { 219 + return commits, nil 220 + } 220 221 221 - parent, err := current.Parents().Next() 222 + for _, item := range lines { 223 + obj, err := g.r.CommitObject(plumbing.NewHash(item)) 222 224 if err != nil { 223 - return nil, fmt.Errorf("error getting parent: %w", err) 225 + continue 224 226 } 225 227 226 - current = parent 228 + commits = append(commits, obj) 227 229 } 228 230 229 231 return commits, nil