#TIL git patch를 적용하는 apply 명령과 am 명령
GitHub에 있는 커밋을 내 저장소에 적용하고 싶다. 리모트 저장소로 등록을 안 한 상태라서 git cherry-pick
명령은 사용하지 못한다. 어떻게 하면 될까?
프로젝트를 운영하는 것은 크게 두 가지로 이루어진다. 하나는 format-patch 명령으로 생성한 Patch를 이메일로 받아서 프로젝트에 Patch를 적용하는 것이다.
patch를 받아서 적용하면 된다. GitHub은 커밋 URL 끝에 .patch
를 붙이면 format-patch
명령으로 만든 형식으로 커밋을 보여주는 기능을 제공한다.
GitHub Doom Emacs 저장소에 있는 9620bb45ac4c 커밋을 적용해 보자
$ curl https://github.com/doomemacs/doomemacs/commit/9620bb45ac4cd7b0274c497b2d9d93c4ad9364ee.patch | git apply --verbose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1187 100 1187 0 0 1916 0 --:--:-- --:--:-- --:--:-- 1917
Checking patch modules/editor/evil/autoload/unimpaired.el...
Applied patch modules/editor/evil/autoload/unimpaired.el cleanly.
git diff
명령으로 patch가 적용됐는지 확인한다.
$ git diff
diff --git a/modules/editor/evil/autoload/unimpaired.el b/modules/editor/evil/autoload/unimpaired.el
index 0e64d427b..b698b56ea 100644
--- a/modules/editor/evil/autoload/unimpaired.el
+++ b/modules/editor/evil/autoload/unimpaired.el
@@ -113,7 +113,7 @@ See `+evil/next-preproc-directive' for details."
(user-error "Must be called from a file-visiting buffer"))
(let* ((directory (file-name-directory buffer-file-name))
(filename (file-name-nondirectory buffer-file-name))
- (files (cl-remove-if #'file-directory-p (doom-glob (file-name-directory buffer-file-name) "[!.]*")))
+ (files (cl-remove-if-not #'file-regular-p (doom-glob (file-name-directory buffer-file-name) "[!.]*")))
(index (cl-position filename files :test #'file-equal-p)))
(when (null index)
(user-error "Couldn't find this file in current directory"))
잘 된다. 하지만 기여자의 이름이라든지 커밋 메시지는 적용되지 않는다. diff만 적용된다. git format-patch
명령으로 만들면 커밋 메시지를 포함해 기여자의 정보까지 다 기록되어 있다. 이것까지 적용하려면 어떻게 하면 될까?
format-patch 명령으로 생성한 Patch 파일은 git am 명령으로 적용한다(am 은 “apply a series of patches from a mailbox”의 약자다). git am 은 mbox 파일을 읽어 그 안에 이메일 메시지가 한 개가 있든 여러 개가 있든 처리할 수 있다.
git am
명령을 사용하면 된다. 이 명령으로 다시 적용해보자.
$ curl https://github.com/doomemacs/doomemacs/commit/9620bb45ac4cd7b0274c497b2d9d93c4ad9364ee.patch | git am
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1187 100 1187 0 0 2026 0 --:--:-- --:--:-- --:--:-- 2029
Applying: fix(evil): ]f/[f opening broken symlinks
git apply
명령과 다르게 바로 커밋을 만들어준다.
$ git log -n 1
commit e632775ed333e8ed2088287c2de519463e697c87 (HEAD -> master)
Author: Henrik Lissner <git@henrik.io>
Date: Thu Apr 18 13:50:28 2024 -0400
fix(evil): ]f/[f opening broken symlinks
diff외 정보도 잘 보존된다.