ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [GIT] - git diff를 통한 patch 파일 생성 및 적용
    Linux/development tool 2023. 8. 3. 02:13

    글의 참고

    - https://git-scm.com/book/ko/v2/%EB%B6%84%EC%82%B0-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C%EC%9D%98-Git-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0

    - https://stackoverflow.com/questions/45584131/how-patching-works-in-yocto


    글의 전제

    - 밑줄로 작성된 글은 강조 표시를 의미한다.

    - 그림 출처는 항시 그림 아래에 표시했다.


    글의 내용

    - 왜 패치 파일을 사용할까 ?

    " 왜 패치 파일을 별도로 사용할까? 그냥 소스 코드를 직접 수정하면 안되나? 내가 개인적으로 중요하다고 생각되는 패치 파일을 소스 파일과 별도로 관리할 때, 어떤 이점이 있는지를 말해보려고 한다. 

     

    " 첫 번째로, 코드가 유연해진다. 예를 들어, A 라는 베이스 라인 소스 코드를 두고 여기에 2가지 기능(A-1, A-2) 이 각각 들어가야 한다고 가정하자. 이 때, 소스 브랜치를 A-1과 A-2로 나눠도 되지만 패치 파일을 A-1, A-2 으로 나눠서 관리해도 된다. 이렇게 하면 베이스 라인 소스 코드를 건드리지 않으면서, 패치 파일로 기능을 추가/제거 할 수 가 있다.

     

    " 두 번째로, 코드 업데이트를 배포할 때, 업데이트된 전체 소스 코드를 배포하기 보다는 간단하게 패치 파일을 배포하는 것이 파일 사이즈가 기존 소스보다 작을 것이기 때문에 전송 속도가 훨씬 빠르다. 그리고 수정된 소스를 주는 것이 아니고 패치 파일을 주는 것이기 때문에, 사용자가 사용하다가 맘에 안들면 롤백하기가 수월하다.  

     

     

     

    -  patch -p[num] ?

    Git을 통해 patch를 할 때, 유의할 점이 있다.

     

    일단 일반적인 patch 순서는 다음과 같다.

    1. git diff ./ > xxxx.patch
    2. patch -p1 < xxxx.patch

    겁나 간단하다그러나 patch  인자중 -p[n] 대해서 주의할 점이 있다.

     

    예시를 들어보자. /workspace/yohda/PMD/platform/poky/meta-tmp-auto-prop 경로에서 conflict 발생했다. 그리고 해당 경로에는 .git 폴더가 있다. 해당 경로에서 ls 치면 다음과 같다. 

     

    yohda@linux:/workspace/yohda/PMD/platform/poky/meta-tmp-auto-prop$ ll
    total 36 
    drwxrwxr-x  8 yohda yohda 4096 Aug 10 14:25 ./ 
    drwxrwxr-x 41 yohda yohda 4096 Apr 22 01:15 ../ 
    drwxrwxr-x  2 yohda yohda 4096 Apr 22 01:15 conf/ 
    drwxrwxr-x  2 yohda yohda 4096 Aug 10 14:26 .git/ 
    drwxrwxr-x 10 yohda yohda 4096 Apr 22 01:15 recipes/ 
    drwxrwxr-x  3 yohda yohda 4096 Apr 22 01:15 recipes-app/ 
    drwxrwxr-x  6 yohda yohda 4096 Apr 22 01:15 recipes-connectivity/ 
    drwxrwxr-x  3 yohda yohda 4096 Apr 22 01:15 recipes-products/

     

    해당 폴더에 .git 있으므로, `git diff` 명령어를 치면 현재 경로를 기준으로 diff 경로를 보여준다. 

     

    yohda@linux:/workspace/yohda/PMD/platform/poky/meta-tmp-auto-prop$ git diff > 1.patch 
    yohda@linux:/workspace/yohda/PMD/platform/poky/meta-tmp-auto-prop$ cat 1.patch 
    diff --git a/recipes/power-manager-daemon/files/powermanager-daemon.service b/recipes/power-manager-daemon/files/powermanager-daemon.service 
    index c6553d8..f9e0757 100755 
    --- a/recipes/power-manager-daemon/files/powermanager-daemon.service 
    +++ b/recipes/power-manager-daemon/files/powermanager-daemon.service 
    @@ -6,7 +6,8 @@ 
     [Unit] 
     Description=powermanager-daemon Service 
     SourcePath=/usr/bin/power_manager_daemon 
    -After=misc_daemon.service evdev_load.service init-can.service 
    +#After=misc_daemon.service evdev_load.service init-can.service 
    +After=misc_daemon.service evdev_load.service 
    
     [Service] 
     User=powermgr 
    diff --git a/recipes/power-manager-daemon/powermanager-daemon_git.bb b/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    index 059bed8..ce798bc 100755 
    --- a/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    +++ b/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    @@ -27,14 +27,19 @@ EXTRA_OECONF = "--with-glib" 
     EXTRA_OECONF += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '--with-systemd', '', d)}" 
    
     EXTRA_OECONF += "--with-canwrapper" 
    -DEPENDS += "canwrapper-hdr canwrapper" 
    +#DEPENDS += "canwrapper-hdr canwrapper" 
    
     EXTRA_OECONF_append_sdxpoorwills-auto += "--enable-target-sdxpoorwills-auto=yes" 
    
     
    
     do_install_append() { 
    +       bbnote " xicvzkopu77 WORKDIR - ${WORKDIR}" 
    +       bbnote " xicvzkopu77 D - ${D}" 
    +       bbnote " xicvzkopu77 systemd_unitdir - ${systemd_unitdir}" 
    +       bbnote " xicvzkopu77 sysconfdir - ${sysconfdir}" 
    + 
         if ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'true', 'false', d)}; then 
            ##Install system-tmpfiles config file 
    -        install -d ${D}${sysconfdir}/tmpfiles.d/ 
    +        install -d ${D}${sysconfdir}/tmpfiles.d/ 
             install -m 0644 ${WORKDIR}/power_manager_daemon-tmpfilesd.conf ${D}${sysconfdir}/tmpfiles.d/power_manager_daemon-tmpfilesd.conf 
    
             ##Install systemd service unit file​

     

     
    여기서 `git diff > xxxx.patch`  만들고, `patch -p0 < xxxx.patch` 만들면 어떻게 될까아래와 같이 나오면서 하나도 적용되지 않는다. 
    yohda@lima20:/workspace02/yohda/PMD/platform/poky/meta-tmp-auto-prop$ patch -p0 < 1.patch 
    can't find file to patch at input line 5 
    Perhaps you used the wrong -p or --strip option? 
    The text leading up to this was: 
    -------------------------- 
    |diff --git a/recipes/power-manager-daemon/files/powermanager-daemon.service b/recipes/power-manager-daemon/files/powermanager-daemon.service 
    |index c6553d8..f9e0757 100755 
    |--- a/recipes/power-manager-daemon/files/powermanager-daemon.service 
    |+++ b/recipes/power-manager-daemon/files/powermanager-daemon.service 
    -------------------------- 
    File to patch: 
    Skip this patch? [y] 
    Skipping patch. 
    1 out of 1 hunk ignored 
    can't find file to patch at input line 19 
    Perhaps you used the wrong -p or --strip option? 
    The text leading up to this was: 
    -------------------------- 
    |diff --git a/recipes/power-manager-daemon/powermanager-daemon_git.bb b/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    |index 059bed8..ce798bc 100755 
    |--- a/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    |+++ b/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    -------------------------- 
    File to patch: 
    Skip this patch? [y] 
    Skipping patch. 
    1 out of 1 hunk ignored 
    yohda@lima20:/workspace02/yohda/PMD/platform/poky/meta-tmp-auto-prop$ 
    yohda@lima20:/workspace02/yohda/PMD/platform/poky/meta-tmp-auto-prop$ patch -p2 < 1.patch 
    can't find file to patch at input line 5 
    Perhaps you used the wrong -p or --strip option? 
    The text leading up to this was: 
    -------------------------- 
    |diff --git a/recipes/power-manager-daemon/files/powermanager-daemon.service b/recipes/power-manager-daemon/files/powermanager-daemon.service 
    |index c6553d8..f9e0757 100755 
    |--- a/recipes/power-manager-daemon/files/powermanager-daemon.service 
    |+++ b/recipes/power-manager-daemon/files/powermanager-daemon.service 
    -------------------------- 
    File to patch: 
    Skip this patch? [y] 
    Skipping patch. 
    1 out of 1 hunk ignored 
    can't find file to patch at input line 19 
    Perhaps you used the wrong -p or --strip option? 
    The text leading up to this was: 
    -------------------------- 
    |diff --git a/recipes/power-manager-daemon/powermanager-daemon_git.bb b/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    |index 059bed8..ce798bc 100755 
    |--- a/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    |+++ b/recipes/power-manager-daemon/powermanager-daemon_git.bb 
    -------------------------- 
    File to patch: 
    Skip this patch? [y] 
    Skipping patch. 
    1 out of 1 hunk ignored

     

    Git diff 하면, patch 파일에서 비교대상이라고 prefix로 a b라는 경로를 앞에다가 붙인다. 

    • a/recipes/power-manager-daemon/files/powermanager-daemon.service  
    • b/recipes/power-manager-daemon/files/powermanager-daemon.service 

    Patch의 인자중 `-p[n]` 앞에 경로를 몇 개를 지울지에 대한 인자이다. 예를 들어서 patch -p3 < xxxx.patch이면 앞에 경로 3개를 지운다. 그래서 아래와 같이 경로가 나온다. 

    • files/powermanager-daemon.service

    위의 문제는 결국 `patch -p0 < xxxx.patch`를 입력했을 때, 현재 경로를 기준으로  a/recipes/power-manager-daemon/files/powermanager-daemon.service과 b/recipes/power-manager-daemon/files/powermanager-daemon.service 파일의 찾지 못했기 때문에 발생한 에러이다.


    그러면 `patch -p1 < xxxx.patch`는 어떨까? recipes/power-manager-daemon/files/powermanager-daemon.service 에는 실제로 파일이 존재하기 때문에 patch가 성공하게 된다. 

     

    사실 가장 심플한 방법은 `git diff --no-prefix > [ patch file ]` 명령어를 입력하면 a/b prefix가 사라진다. 그래서 `patch -p0 < [ patch file ]` 명령어를 쓰면 된다. 

    'Linux > development tool' 카테고리의 다른 글

    [LINUX][VIM] 내가 에디터로 VIM을 쓰는 이유  (0) 2023.08.03
    [운영체제 만들기] xxd  (0) 2023.08.03
    Shell script  (0) 2023.07.10
    dd  (0) 2023.06.10
    [개발 도구] objdump  (0) 2023.06.10
Designed by Tistory.