Skip to content

Don't display error log when .git-blame-ignore-revs doesn't exist #34457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 26 additions & 18 deletions modules/git/blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,22 @@ func (r *BlameReader) Close() error {
}

// CreateBlameReader creates reader for given repository, commit and file
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) {
reader, stdout, err := os.Pipe()
if err != nil {
return nil, err
}
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, err error) {
var ignoreRevsFileName string
var ignoreRevsFileCleanup func()
defer func() {
if err != nil && ignoreRevsFileCleanup != nil {
ignoreRevsFileCleanup()
}
}()

cmd := NewCommandNoGlobals("blame", "--porcelain")

var ignoreRevsFileName string
var ignoreRevsFileCleanup func() // TODO: maybe it should check the returned err in a defer func to make sure the cleanup could always be executed correctly
if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
ignoreRevsFileName, ignoreRevsFileCleanup = tryCreateBlameIgnoreRevsFile(commit)
ignoreRevsFileName, ignoreRevsFileCleanup, err = tryCreateBlameIgnoreRevsFile(commit)
if err != nil {
return nil, err
}
if ignoreRevsFileName != "" {
// Possible improvement: use --ignore-revs-file /dev/stdin on unix
// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
Expand All @@ -154,6 +158,11 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
cmd.AddDynamicArguments(commit.ID.String()).AddDashesAndList(file)

done := make(chan error, 1)
// use err1 to not override err
reader, stdout, err1 := os.Pipe()
if err1 != nil {
return nil, err1
}
go func() {
stderr := bytes.Buffer{}
// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
Expand Down Expand Up @@ -182,33 +191,32 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
}, nil
}

func tryCreateBlameIgnoreRevsFile(commit *Commit) (string, func()) {
func tryCreateBlameIgnoreRevsFile(commit *Commit) (string, func(), error) {
entry, err := commit.GetTreeEntryByPath(".git-blame-ignore-revs")
if err != nil {
log.Error("Unable to get .git-blame-ignore-revs file: GetTreeEntryByPath: %v", err)
return "", nil
if IsErrNotExist(err) {
return "", nil, nil
}
return "", nil, err
}

r, err := entry.Blob().DataAsync()
if err != nil {
log.Error("Unable to get .git-blame-ignore-revs file data: DataAsync: %v", err)
return "", nil
return "", nil, err
}
defer r.Close()

f, cleanup, err := setting.AppDataTempDir("git-repo-content").CreateTempFileRandom("git-blame-ignore-revs")
if err != nil {
log.Error("Unable to get .git-blame-ignore-revs file data: CreateTempFileRandom: %v", err)
return "", nil
return "", nil, err
}
filename := f.Name()
_, err = io.Copy(f, r)
_ = f.Close()
if err != nil {
cleanup()
log.Error("Unable to get .git-blame-ignore-revs file data: Copy: %v", err)
return "", nil
return "", nil, err
}

return filename, cleanup
return filename, cleanup, nil
}