Git am some_patch применяется атомарным способом?

Я написал автоматизированный код для применения патчей git через библиотеку git python. Однако я хочу знать, есть ли вероятность того, что некоторые исправления будут применены, а другие приведут к ошибке.

    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

2 ответа

Решение

Вам нужно будет более точно определить, что вы подразумеваете под "атомным". В частности, хотя:

[Что] я хочу знать, есть ли вероятность того, что некоторые исправления будут применены, а некоторые из них приведут к ошибке

Это конечно возможно для git am path потерпеть неудачу, и git am Документация описывает, что происходит в этом случае. Если исправления, отформатированные в почтовом ящике, содержат, скажем, семь частей, а первые три применены корректно, но у четвертого возник конфликт слияния или другой сбой, первые три действительно будут применены, а четвертый действительно еще не применен. Если причиной сбоя является конфликт слияния, индекс и рабочее дерево будут в состоянии частично слияния. Если патч просто не был применен вообще, индекс и рабочее дерево будут соответствовать состоянию, созданному путем применения третьего коммита. В любом случае, git am выйдет ненулевой. (В этот момент вы можете использовать git am --abort вернуть все обратно, как было до начала, без применения исправлений, или вручную исправить проблему, а затем запустить git am --continue возобновить процесс.)

В документации gitpython упоминается, что git.exc.GitCommandError возникает, если основная команда Git выходит из нуля. Поэтому вы бы поймали исключение здесь.

Примечание: except Exception как правило, слишком широк в Python. Как правило, вы должны поймать конкретные исключения, которые вы ожидаете здесь, которые в этом случае могут быть git.exc.GitCommandError (за git amсуществует и работает, но сообщил о неудаче) и git.exc.GitError (что-то пошло не так, например, бинарный файл Git не установлен, или Git утверждает, что это вообще не репозиторий и т. д.).

Обязательно используйте Git 2.34 для вашего атомарного процесса, включающего:

Когда "git am --abort" (man ) не удалось правильно прервать, он по-прежнему завершался со статусом выхода 0 , что было исправлено в Git 2.34 (4 квартал 2021 г.).

См. , коммит 42b5e09, коммит ea7dc01 (10 сентября 2021 г.) от Элайджи Ньюрена ( newren) .
(Объединено Junio ​​C Hamano -- gitster-- в коммите 6c84b00 , 23 сентября 2021 г.)

коммит c5ead19am: исправлен неверный статус выхода при невозможности прервать

Подписал: Элайджа Ньюрен

Итак, в вашей функции Python:

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

Это вернуло бы «всегда верно» до Git 2.34, даже если прерывание не удалось.

Другие вопросы по тегам