Skip to content
Browse files
fix(submodules): auto handle "commits not present" patch creation error
When "commits not present" error occurs during patch creation between FROM and TO commits,
then reset service git worktree to the FROM commit (which in turn fetches lost submodule commit)
and retry patch creation procedure.

Signed-off-by: Timofey Kirillov <>
  • Loading branch information
distorhead committed Jun 24, 2022
1 parent 6837bda commit 91a829b341fe3da2064f8e3e25d3394783089c2e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
@@ -225,7 +225,31 @@ func (repo *Base) createPatch(ctx context.Context, repoPath, gitDir, repoID, wor

var desc *true_git.PatchDescriptor
if hasSubmodules {
var retryCount int

desc, err = true_git.PatchWithSubmodules(ctx, fileHandler, gitDir, workTreeCacheDir, true_git.PatchOptions(opts))

if true_git.IsCommitsNotPresentError(err) && retryCount == 0 {
logboek.Context(ctx).Default().LogF("Detected not present commits when creating patch: %s\n", err)
logboek.Context(ctx).Default().LogF("Will switch worktree to original commit %q and retry\n", opts.FromCommit)

if err := fileHandler.Truncate(0); err != nil {
return nil, fmt.Errorf("unable to truncate file %s: %w", tmpFile, err)
if _, err := fileHandler.Seek(0, 0); err != nil {
return nil, fmt.Errorf("unable to reset file %s: %w", tmpFile, err)

if err := true_git.WithWorkTree(ctx, gitDir, workTreeCacheDir, opts.FromCommit, true_git.WithWorkTreeOptions{HasSubmodules: true}, func(workTreeDir string) error {
return nil
}); err != nil {
return nil, fmt.Errorf("unable to switch worktree to commit %q: %w", opts.FromCommit, err)

goto TryCreatePatch
} else {
desc, err = true_git.Patch(ctx, fileHandler, gitDir, true_git.PatchOptions(opts))
@@ -2,6 +2,7 @@ package true_git

import (
@@ -13,6 +14,12 @@ import (

var ErrCommitsNotPresent = errors.New("commits not present")

func IsCommitsNotPresentError(err error) bool {
return err != nil && strings.HasSuffix(err.Error(), ErrCommitsNotPresent.Error())

func makeDiffParser(out io.Writer, pathScope string, pathMatcher path_matcher.PathMatcher, fileRenames map[string]string) *diffParser {
return &diffParser{
PathScope: pathScope,
@@ -379,7 +386,7 @@ func (p *diffParser) handleModifyFilePathB(line string) error {
func (p *diffParser) handleSubmoduleLine(line string) error {
p.state = unrecognized
if strings.HasSuffix(line, " (commits not present)") {
return fmt.Errorf("cannot handle \"commits not present\" in git diff line %q, check specified submodule commits are correct", line)
return fmt.Errorf("cannot handle git diff line %q, check specified commits are correct: %w", line, ErrCommitsNotPresent)
return nil

0 comments on commit 91a829b

Please sign in to comment.