summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doPatch.findByPatchId.go117
-rw-r--r--doPatch.go15
2 files changed, 129 insertions, 3 deletions
diff --git a/doPatch.findByPatchId.go b/doPatch.findByPatchId.go
new file mode 100644
index 0000000..6882055
--- /dev/null
+++ b/doPatch.findByPatchId.go
@@ -0,0 +1,117 @@
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "strings"
+)
+
+func searchAllCommits(targetPatchID string) (string, error) {
+ revListArgs := []string{"--all"}
+ cmdRevList := exec.Command("git", append([]string{"rev-list"}, revListArgs...)...)
+
+ // We'll read the commit hashes from the command's standard output.
+ revListStdout, err := cmdRevList.StdoutPipe()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error creating rev-list stdout pipe: %v\n", err)
+ return "", err
+ }
+
+ // Start the command but don't wait for it to finish yet.
+ if err := cmdRevList.Start(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error starting git rev-list: %v\n", err)
+ return "", err
+ }
+
+ var commitHash string
+ // 3. Process the stream of commit hashes line by line.
+ scanner := bufio.NewScanner(revListStdout)
+ found := false
+ for scanner.Scan() {
+ commitHash = scanner.Text()
+
+ // 4. For each commit, calculate its patch ID.
+ calculatedIDs, err := getPatchIDForCommit(commitHash)
+ if err != nil {
+ // Log the error but continue trying other commits.
+ fmt.Fprintf(os.Stderr, "Warning: could not get patch-id for %s: %v\n", commitHash, err)
+ continue
+ }
+
+ // 5. Compare the calculated IDs with our target.
+ for _, id := range calculatedIDs {
+ if id == targetPatchID {
+ fmt.Printf("Found matching commit: %s\n", commitHash)
+ found = true
+ return commitHash, nil
+ // We could exit here, but continuing will find all duplicates (e.g., from cherry-picks).
+ }
+ }
+ }
+
+ // Wait for the rev-list command to finish and check for errors.
+ if err := cmdRevList.Wait(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error running git rev-list: %v\n", err)
+ return "", err
+ }
+ if err := scanner.Err(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error reading commit hashes: %v\n", err)
+ return "", err
+ }
+
+ if !found {
+ fmt.Fprintf(os.Stderr, "No commit found with patch ID: %s\n", targetPatchID)
+ return "not found", errors.New("patchId not found")
+ }
+ return commitHash, nil
+}
+
+// getPatchIDForCommit runs `git show <commit> | git patch-id --stable`
+// and returns the stable and unstable patch IDs.
+func getPatchIDForCommit(commitHash string) ([]string, error) {
+ // Command to get the commit's diff
+ cmdShow := exec.Command("git", "show", commitHash)
+
+ // Command to calculate the patch-id from stdin
+ cmdPatchID := exec.Command("git", "patch-id", "--stable")
+
+ // Create a pipe to connect the output of cmdShow to the input of cmdPatchID.
+ r, w := io.Pipe()
+ cmdShow.Stdout = w
+ cmdPatchID.Stdin = r
+
+ var patchIDOutput bytes.Buffer
+ cmdPatchID.Stdout = &patchIDOutput
+
+ // Start both commands.
+ if err := cmdShow.Start(); err != nil {
+ return nil, fmt.Errorf("failed to start git-show: %w", err)
+ }
+ if err := cmdPatchID.Start(); err != nil {
+ return nil, fmt.Errorf("failed to start git-patch-id: %w", err)
+ }
+
+ // Wait for 'show' to finish writing to the pipe, then close the writer.
+ // This will signal EOF to the 'patch-id' command's stdin.
+ errShow := cmdShow.Wait()
+ w.Close()
+ if errShow != nil {
+ return nil, fmt.Errorf("git-show failed: %w", errShow)
+ }
+
+ // Now wait for 'patch-id' to finish reading and processing.
+ errPatchID := cmdPatchID.Wait()
+ if errPatchID != nil {
+ return nil, fmt.Errorf("git-patch-id failed: %w", errPatchID)
+ }
+
+ // The output is typically "<stable_id> <unstable_id>".
+ // We split the string by whitespace to get both.
+ ids := strings.Fields(patchIDOutput.String())
+ return ids, nil
+}
diff --git a/doPatch.go b/doPatch.go
index 72af28e..3d92337 100644
--- a/doPatch.go
+++ b/doPatch.go
@@ -108,11 +108,16 @@ func doPatchList() error {
}
if newId != patch.PatchId {
log.Info(patch.PatchId, "probably duplicate subject", patch.Comment)
+ // try this. it should compute every patch id in the repo
+ // os.Chdir(repo.FullPath)
+ // newNewId, err := searchAllCommits(targetPatchID string) (string, error) {
}
log.Info("new patch", patch.PatchId, patch.Comment)
if !argv.Fix {
log.Info("use --fix to attempt to apply new patches")
} else {
+ log.Info(string(patch.Data))
+ log.Info("repo:", repo.FullPath, "patch header:", patch.Comment, patch.CommitHash)
if fhelp.QuestionUser("apply this patch?") {
newhash, err := applyPatch(repo, patch)
log.Info("apply results:", newhash, err)
@@ -208,7 +213,7 @@ func isPatchIdApplied(repo *gitpb.Repo, patch *forgepb.Patch) (string, string, e
comment := cleanSubject(patch.Comment)
os.Chdir(repo.GetFullPath())
- newhash, err := findCommitBySubject(comment)
+ newhash, err := findCommitBySubject(repo, comment, patch)
if err != nil {
return "", "", ErrorGitPullOnDirty
}
@@ -260,7 +265,7 @@ func cleanSubject(line string) string {
// jcarr@framebook:~/go/src/go.wit.com/lib/protobuf/forgepb$ git merge-base --is-ancestor "4a27e7702b9b975b066ec9d2ee7ac932d86552e3" "jcarr" ; echo $?
// 0
-func findCommitBySubject(subject string) (string, error) {
+func findCommitBySubject(repo *gitpb.Repo, subject string, newpatch *forgepb.Patch) (string, error) {
cmd := exec.Command("git", "log", "--pretty=format:%H %s", "--grep="+subject, "-i")
var out bytes.Buffer
cmd.Stdout = &out
@@ -272,7 +277,11 @@ func findCommitBySubject(subject string) (string, error) {
lines := strings.Split(out.String(), "\n")
for _, line := range lines {
if strings.Contains(strings.ToLower(line), strings.ToLower(subject)) {
- return strings.Fields(line)[0], nil // return the commit hash
+ parts := strings.Fields(line)
+ patchId, _ := repo.FindPatchIdByHash(parts[0])
+ if patchId == newpatch.PatchId {
+ return strings.Fields(line)[0], nil // return the commit hash
+ }
}
}
return "", fmt.Errorf("no commit found for subject: %s", subject)