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 г.)
коммит c5ead19
am
: исправлен неверный статус выхода при невозможности прерватьПодписал: Элайджа Ньюрен
Итак, в вашей функции Python:
repo.git.execute(["git", "am", "--abort"])
return status
Это вернуло бы «всегда верно» до Git 2.34, даже если прерывание не удалось.