diff patch 사용법


diff patch 사용법
리눅스 diff 사용법 그리고 patch 명령어 사용법에 대해서 설명드립니다. 예제를 통해서 patch 파일을 만들어서 적용하는 방법과 기존 patch 파일을 이용하여 원래 파일로 되돌리는 방법을 함께 설명드리도록 하겠습니다.

linux diff patch 명령어

diff 명령어는 2개의 파일을 라인 단위로 차이를 비교하는 명령어입니다.
git을 이용 하여 소스코드를 관리하다가 수정된 내용을 확인 하기 위해서 git diff라는 명령어를 사용해 본 경험이 있을 거라 생각합니다. 소스코드의 수정된 내용이 있을 경우 아래와 같이 비슷한 내용이 나타날 것입니다.

diff --git a/main.c b/main.c
index 1394ce8..2ce6036 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,6 @@
 #include <stdio.h>
 
 int main() {
+  printf("hello, world");
   return 0;
 }

리눅스에서 diff 라는 명령어는 git에서 diff 라는 명령어처럼 2개의 파일의 차이를 출력합니다. 그리고 그 차이를 파일로 저장하여 patch 명령어로 수정 내용을 적용할 수도 있습니다.

diff patch 예제

diff patch 사용법을 예제를 통해서 설명드리도록 하겠습니다. 아래의 디렉터리 구조로 2개의 main.c 파일을 만들도록 하겠습니다.

├── a
│   └── main.c
└── b
    └── main.c

2 directories, 2 files

먼저 a/main.c 파일의 내용은 아래와 같습니다.

#include <stdio.h>

int main() {
  return 0;
}

그리고 b/main.c 파일의 내용은 아래와 같습니다.

#include <stdio.h>

int main() {
  printf("hello, world");
  return 0;
}

b/main.c 파일의 내용중에서 printf 함수의 내용이 추가된 것을 알 수 있습니다.

이 글에서는 git diff 라는 명령어 처럼 원래의 버전을 a라고하고 수정된 버전을 b라고 하여 설명드리도록 하겠습니다.
초기버전인 a버전에서 어떠한 수정내용(patch)이 더해져서 최종 b버전이 된다고 생각하시면 됩니다.

그리고 패치파일은 아래와 같이 만들어 진다고 생각하시면, 기억하기 쉬우실겁니다.

diff 사용법

먼저 2개의 파일의 차이를 출력해 보도록하겠습니다. diff 명령어는 아래와 같이 사용할 수 있습니다.

$ diff -Naur a b

a는 이전버전의 디렉터리 또는 파일이고, b는 이후 버전의 파일 또는 디렉터리 입니다.
모든 내용을 텍스트로 처리하는 옵션, 그리고 서브 디렉터리를 재귀적으로 순회하는 옵션등이 추가되어 사용됩니다.

위의 명령어에서 출력 결과는 아래와 같습니다.

--- a/main.c	2018-07-05 00:02:56.962570740 +0900
+++ b/main.c	2018-07-05 00:02:51.874801135 +0900
@@ -1,5 +1,6 @@
 #include <stdio.h>
 
 int main() {
+  printf("hello, world");
   return 0;
 }

diff patch 만들기
출력되는 내용을 아래의 명령어를 사용하여 패치 파일로 만들 수 있습니다.

$ diff -Naur a b > main.patch

patch 명령어

위에서 생성한 main.patch 패치 파일을 적용하는 방법에 대해서 설명드리도록 하겠습니다. 패치 파일이 적용되는 위치에 따라 patch 명령어 옵션이 달라지는데 이점 주의하셔야 합니다. 먼저 아래의 위치에서 다음과 같은 파일들이 존재하는 것을 가정하여 설명드리도록 하겠습니다.

├── a
│   └── main.c
├── b
│   └── main.c
└── main.patch

2 directories, 3 files

패치 적용
위에서 생성한 패치파일을 적용하기 위해서는 아래의 명령어를 사용합니다.

$ patch -p0 < main.patch 
patching file a/main.c

패치 파일을 적용할 때에 가장 중요한 옵션이 위의 -p 옵션입니다. 패치 파일에서 파일 이름 경로를 얼마나 제거해서 적용하는지 나타냅니다.
위의 내용은 파일 경로를 제거하지 않고 적용한다는 의미로, diff 명령어로 패치파일이 생성될때 동일한 위치일 경우 -p0 옵션을 사용하여 패치를 합니다.

그리고 패치가 제대로 적용되었는지 확인 하기 위해서 다시 아래의 명령어를 실행하도록 하겠습니다.

$ diff -Naur a b

아무런 실행결과가 없는데, 패치 내용이 a 에 적용되어 a b 디렉터리의 내용이 동일한 것을 나타냅니다.

패치 제거
patch 는 패치 파일을 적용할 수도 있지만, 거꾸로 적용된 패치를 제거하는데도 사용됩니다.
아래의 이미지 처럼 적용된 버전에서 patch 파일의 내용을 빼버리면 패치가 적용되기 전 버전이 나타나게 됩니다.

적용된 패치를 제거하는데는 reverse의 의미인 -R 옵션을 추가하여 명령어를 실행하면 됩니다.

$ patch -p0 -R < main.patch 
patching file a/main.c

다시 두 개의 디렉터리 a b를 비교하면 차이가 있는 것을 알 수 있습니다.

$ diff -Naur a b
diff -Naur a/main.c b/main.c
--- a/main.c	2018-07-05 00:23:39.958369075 +0900
+++ b/main.c	2018-07-05 00:02:51.874801135 +0900
@@ -1,5 +1,6 @@
 #include <stdio.h>
 
 int main() {
+  printf("hello, world");
   return 0;
 }

디렉터리 안에서 패치
마지막으로 -p 옵션을 달리하여, a 디렉터리 안에서 직접 패치를 해보도록 하겠습니다. -p1 옵션이 의미 하는 것은 main.patch 파일의 내부의 경로에서 1단계를 제거하여 적용한다는 의미입니다.

a$ patch -p1 < ../main.patch 
patching file main.c

그리고 아래의 명령어로 파일을 비교하면, 성공적으로 패치가 되어 차이가 없음을 알 수 있습니다.

$ diff -Naur main.c ../b/main.c

C/C++ 프로그램 개발과 관련하여 Google Test 프레임워크 사용법과 관련해서는 다음 글을 참고해 주시기 바랍니다.

Google Test 사용법 예제

( 본문 인용시 출처를 밝혀 주시면 감사하겠습니다.)