Search code examples
pythongitgitpythongit-am

Does git am some_patch apply in an atomic way?


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

Solution

  • 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.).