1

I have written an automated code to apply git patches via git python library. However I want to know is there a possibility that some of the patches are applied and some give error.

    try:
        repo.git.execute(["git", "am", "patch")
    except Exception as e:
        for stat in status:
            stat.update({"status": "failure"})
        repo.git.execute(["git", "am", "--abort"])
        return status
Romain Valeri
  • 19,645
  • 3
  • 36
  • 61
sky
  • 260
  • 3
  • 12

2 Answers2

1

You're going to have to define more precisely what you mean by "atomic" here. In particular, though:

[What] I want to know is [whether] there [is] a possibility that some of the patches are applied and some give error

It is certainly possible for git am path to fail, and the git am documentation describes what happens in that case. If the mailbox-formatted patches contain, say, seven parts, and the first three applied cleanly but the fourth had a merge conflict or other failure, the first three will indeed be applied and the fourth will indeed be not-yet-applied. If the reason it failed was due to a merge conflict, the index and work-tree will be in the partially-merged state. If the patch simply did not apply at all, the index and work-tree will match the state produced by applying the third commit. Either way, git am will exit nonzero. (You may, at this point, use git am --abort to put everything back the way it was before you started, with no patches applied, or manually fix the problem and then run git am --continue to resume the process.)

The gitpython documentation mentions that git.exc.GitCommandError is raised if the underlying Git command exits nonzero. You would therefore catch an exception here.

Side note: except Exception is generally far too broad in Python. You should typically catch the specific exception(s) you expect here, which in this case might be git.exc.GitCommandError (for git am exists and ran, but reported failure) and git.exc.GitError (for something in general went wrong, such as the Git binary is not installed, or Git claims that this is not a repository at all, etc.).

torek
  • 448,244
  • 59
  • 642
  • 775
0

Make sure to use Git 2.34 for your atomic process involving git am --abort:

When "git am --abort"(man) fails to abort correctly, it still exited with exit status of 0, which has been corrected with Git 2.34 (Q4 2021).

See commit c5ead19, commit 42b5e09, commit ea7dc01 (10 Sep 2021) by Elijah Newren (newren).
(Merged by Junio C Hamano -- gitster -- in commit 6c84b00, 23 Sep 2021)

am: fix incorrect exit status on am fail to abort

Signed-off-by: Elijah Newren

So in your python function:

        repo.git.execute(["git", "am", "--abort"])
        return status

This would have returned "always true" before Git 2.34, even when the am abort failed.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250