mirror of
https://github.com/go-gitea/gitea.git
synced 2025-12-07 11:04:05 +09:00
94 lines
2.3 KiB
Go
94 lines
2.3 KiB
Go
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package gitrepo
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
|
|
"code.gitea.io/gitea/modules/git/gitcmd"
|
|
"code.gitea.io/gitea/modules/log"
|
|
)
|
|
|
|
// CommitFileStatus represents status of files in a commit.
|
|
type CommitFileStatus struct {
|
|
Added []string
|
|
Removed []string
|
|
Modified []string
|
|
}
|
|
|
|
// NewCommitFileStatus creates a CommitFileStatus
|
|
func NewCommitFileStatus() *CommitFileStatus {
|
|
return &CommitFileStatus{
|
|
[]string{}, []string{}, []string{},
|
|
}
|
|
}
|
|
|
|
func parseCommitFileStatus(fileStatus *CommitFileStatus, stdout io.Reader) {
|
|
rd := bufio.NewReader(stdout)
|
|
peek, err := rd.Peek(1)
|
|
if err != nil {
|
|
if err != io.EOF {
|
|
log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err)
|
|
}
|
|
return
|
|
}
|
|
if peek[0] == '\n' || peek[0] == '\x00' {
|
|
_, _ = rd.Discard(1)
|
|
}
|
|
for {
|
|
modifier, err := rd.ReadString('\x00')
|
|
if err != nil {
|
|
if err != io.EOF {
|
|
log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err)
|
|
}
|
|
return
|
|
}
|
|
file, err := rd.ReadString('\x00')
|
|
if err != nil {
|
|
if err != io.EOF {
|
|
log.Error("Unexpected error whilst reading from git log --name-status. Error: %v", err)
|
|
}
|
|
return
|
|
}
|
|
file = file[:len(file)-1]
|
|
switch modifier[0] {
|
|
case 'A':
|
|
fileStatus.Added = append(fileStatus.Added, file)
|
|
case 'D':
|
|
fileStatus.Removed = append(fileStatus.Removed, file)
|
|
case 'M':
|
|
fileStatus.Modified = append(fileStatus.Modified, file)
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetCommitFileStatus returns file status of commit in given repository.
|
|
func GetCommitFileStatus(ctx context.Context, repo Repository, commitID string) (*CommitFileStatus, error) {
|
|
stdout, w := io.Pipe()
|
|
done := make(chan struct{})
|
|
fileStatus := NewCommitFileStatus()
|
|
go func() {
|
|
parseCommitFileStatus(fileStatus, stdout)
|
|
close(done)
|
|
}()
|
|
|
|
stderr := new(bytes.Buffer)
|
|
err := gitcmd.NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1").
|
|
AddDynamicArguments(commitID).
|
|
WithDir(repoPath(repo)).
|
|
WithStdout(w).
|
|
WithStderr(stderr).
|
|
Run(ctx)
|
|
w.Close() // Close writer to exit parsing goroutine
|
|
if err != nil {
|
|
return nil, gitcmd.ConcatenateError(err, stderr.String())
|
|
}
|
|
|
|
<-done
|
|
return fileStatus, nil
|
|
}
|