// Copyright 2025 The Forgejo Authors. All rights reserved.// SPDX-License-Identifier: GPL-3.0-or-laterpackage git import ( "bytes" "context" "fmt" "os" "forgejo.org/modules/log" "forgejo.org/modules/util") // CheckIfDiffDiffers returns if the diff of the newCommitID and// oldCommitID with the merge base of the base branch has changed.//// Informally it checks if the following two diffs are exactly the same in their// contents, thus ignoring different commit IDs, headers and messages:// 1. git diff --merge-base baseReference newCommitID// 2. git diff --merge-base baseReference oldCommitIDfunc (repo *Repository) CheckIfDiffDiffers(base, oldCommitID, newCommitID string, env []string) (hasChanged bool, err error) { cmd := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base) stdoutReader, stdoutWriter, err := os.Pipe() if err != nil { return false, fmt.Errorf("unable to open pipe for to run diff: %w", err) } stderr := new(bytes.Buffer) if err := cmd.Run(&RunOpts{ Dir: repo.Path, Stdout: stdoutWriter, Stderr: stderr, PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { _ = stdoutWriter.Close() defer func() { _ = stdoutReader.Close() }() return util.IsEmptyReader(stdoutReader) }, }); err != nil { if err == util.ErrNotEmpty { return true, nil } err = ConcatenateError(err, stderr.String()) log.Error("Unable to run git diff on %s %s %s in %q: Error: %v", newCommitID, oldCommitID, base, repo.Path, err) return false, fmt.Errorf("Unable to run git diff --name-only -z %s %s %s: %w", newCommitID, oldCommitID, base, err) } return false, nil}
// Copyright 2025 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package git
import (
"bytes"
"context"
"fmt"
"os"
"forgejo.org/modules/log"
"forgejo.org/modules/util"
)
// CheckIfDiffDiffers returns if the diff of the newCommitID and
// oldCommitID with the merge base of the base branch has changed.
//
// Informally it checks if the following two diffs are exactly the same in their
// contents, thus ignoring different commit IDs, headers and messages:
// 1. git diff --merge-base baseReference newCommitID
// 2. git diff --merge-base baseReference oldCommitID
func (repo *Repository) CheckIfDiffDiffers(base, oldCommitID, newCommitID string, env []string) (hasChanged bool, err error) {
cmd := NewCommand(repo.Ctx, "diff", "--name-only", "-z").AddDynamicArguments(newCommitID, oldCommitID, base)
stdoutReader, stdoutWriter, err := os.Pipe()
if err != nil {
return false, fmt.Errorf("unable to open pipe for to run diff: %w", err)
}
stderr := new(bytes.Buffer)
if err := cmd.Run(&RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: stderr,
PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error {
_ = stdoutWriter.Close()
defer func() {
_ = stdoutReader.Close()
}()
return util.IsEmptyReader(stdoutReader)
},
}); err != nil {
if err == util.ErrNotEmpty {
return true, nil
}
err = ConcatenateError(err, stderr.String())
log.Error("Unable to run git diff on %s %s %s in %q: Error: %v",
newCommitID, oldCommitID, base,
repo.Path,
err)
return false, fmt.Errorf("Unable to run git diff --name-only -z %s %s %s: %w", newCommitID, oldCommitID, base, err)
}
return false, nil
}