2009. 12. 12. 22:50

diff and patch in linux



'diff'는 두 파일간의 차이를 보여주는 프로그램이다.
원본 파일이 있고, 그 파일을 수정한 다른 파일이 있다면 그 파일간의 바뀐점이 무엇인지 알고 싶을 때 사용할 수 있다. 혹은 여러사람이 작업을 할 때 기존의 파일을 수정하였을 때 어떤 부분이 바뀌었는지도 확인 할 수 있다.

아래와 같이 diff 라면 명령어를 사용하여 확인 할 수 있다.
$ diff a파일 b파일

변화가 있는 부분을 파일로 저장하기 위해선..
$ diff a파일 b파일 > 파일.diff
혹은
$ diff -u a파일 b파일 > 파일.diff
을 사용할 수 있다.

diff 사용 예...
$ vi hello.c
#include <stdio.h>

void main()
{
    printf(hello);
}

$ vi hello2.c
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello \n");
    return 0;
}

$ diff -u hello.c hello2.c > hello.diff
$ cat hello.diff
--- hello.c 2009-12-12 21:46:38.000000000 +0900
+++ hello2.c    2009-12-12 21:48:32.000000000 +0900
@@ -1,6 +1,7 @@
#include <stdio.h>

-void main()
+int main(int argc, char **argv)
{
-    printf(hello);
+    printf("hello \n");
+    return 0;
}

디렉토리를 비교하려면,
$ diff -urN A디렉토리 B디렉토리


'patch' 는 diff 명령을 통해 만들어진 파일을 적용하는 명령이다.
위에서 작성한 hello.c 파일과 hello2.c 파일의 바뀐점이 diff 명령을 통해 hello.diff 파일에 적용되고, hello.diff 파일을 사용하여 hello.c파일을 hello2.c파일과 동일하게 패치 한다.
$ patch -p0 < hello.diff
위와 같이 패치를 하게 되면, hello.c 파일이 hello2.c 와 동일한 파일로 패치되어 있는 것을 확인할 수 있다.

patch 에서 'p0'라는 옵션이 있는데.. 이 옵션은 diff를 할 때 파일이 놓인 경로의 깊이를 나타내는 것으로 볼 수 있다. 위의 diff 명령은 동일한 디렉토리 내에서 파일을 diff 한 것이지만, 일반적으로 프로젝트를 하게 되면 동일한 디렉토리가 아닌 project1/ project2/ 와 같이 다른 디렉토리도 작업을 하게 될 것이다.
$ diff -urN project1/ project2/ > project.diff
$ cat project.diff
diff -urN project1/hello.c project2/hello.c
--- project1/hello.c
+++ project2/hello.c
...

$ cp project.diff project1/
$ cd project1
$ patch -p1 < project.diff

위처럼 경로명이 몇단계로 이루어지느냐에 따라 p0, p1, .. 을 결정 할 수 있게 된다.
경로명을  몇꺼풀 벗길 것인가.. 라는 얘기이다.
위의 예처럼 -p0 옵션을 사용하면, 한 꺼풀도 안벗기고 패치한다. 동일한 디렉토리위 내용을 패치한다고 할 수 있다.  위의 예와 같이 하면 -p1 옵션을 사용해서 패치하게 된다.