Refactor git command context & pipeline (#36406)

Less and simpler code, fewer bugs
This commit is contained in:
wxiaoguang
2026-01-21 09:35:14 +08:00
committed by GitHub
parent f6db180a80
commit 9ea91e036f
36 changed files with 286 additions and 434 deletions
+9 -23
View File
@@ -206,16 +206,6 @@ func prepareTemporaryRepoForMerge(ctx *mergeContext) error {
// getDiffTree returns a string containing all the files that were changed between headBranch and baseBranch
// the filenames are escaped so as to fit the format required for .git/info/sparse-checkout
func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string, out io.Writer) error {
diffOutReader, diffOutWriter, err := os.Pipe()
if err != nil {
log.Error("Unable to create os.Pipe for %s", repoPath)
return err
}
defer func() {
_ = diffOutReader.Close()
_ = diffOutWriter.Close()
}()
scanNullTerminatedStrings := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
@@ -229,27 +219,23 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string, o
return 0, nil, nil
}
err = gitcmd.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").
var diffOutReader io.ReadCloser
err := gitcmd.NewCommand("diff-tree", "--no-commit-id", "--name-only", "-r", "-r", "-z", "--root").
AddDynamicArguments(baseBranch, headBranch).
WithDir(repoPath).
WithStdout(diffOutWriter).
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
// Close the writer end of the pipe to begin processing
_ = diffOutWriter.Close()
defer func() {
// Close the reader on return to terminate the git command if necessary
_ = diffOutReader.Close()
}()
WithStdoutReader(&diffOutReader).
WithPipelineFunc(func(ctx gitcmd.Context) error {
// Now scan the output from the command
scanner := bufio.NewScanner(diffOutReader)
scanner.Split(scanNullTerminatedStrings)
for scanner.Scan() {
filepath := scanner.Text()
treePath := scanner.Text()
// escape '*', '?', '[', spaces and '!' prefix
filepath = escapedSymbols.ReplaceAllString(filepath, `\$1`)
treePath = escapedSymbols.ReplaceAllString(treePath, `\$1`)
// no necessary to escape the first '#' symbol because the first symbol is '/'
fmt.Fprintf(out, "/%s\n", filepath)
if _, err := fmt.Fprintf(out, "/%s\n", treePath); err != nil {
return err
}
}
return scanner.Err()
}).