Git add -p 로 수정사항 분리하기


git commit 은 하나의 수정 사항을 반영 하는 것이 Kernel 과 같은 대형 project 에 merge 될 확률이 높다. 이는 kernel에 Documentation/SumittingPatches 의 3번(Separate your changes.)의 내용을 보면 알 수 있다.


하지만 수정을 하다 보면, 하나의 commit 내부에 두 개 이상의 bug 수정이 있을 수 있다. 이런 경우 여러 개의 Commit 으로 분리하는 방법을 작성해 본다.


최근 Kernel patch 를 만드는 과정에서 Maintainer 가 두 개로 분리해달라는 요청이 있었고, 이를 위해 고민하다 검색으로 찾아낸 방법이다.


이미 하나의 commit 으로 내 local branch 에 있다. 이 commit 을 두 개로 분리했던 과정을 살펴본다.


1. 내 commit 이전으로 돌아간다.

  - 이 때, 분리하려는 commit 이 최상위에 있어야 한다. 만약 최상위가 아니라면 http://woodz.tistory.com/75 여기를 참고하시면 된다.

$ git reset HEAD^

이렇게 하면, 최상위에서 바로 전의 commit 으로 reset 이 되고 내 수정 사항은 un-stage 된다.


현재 상황은, 아래와 같다. 아래서 위쪽 code block 과 아래쪽을 분리하여 commit 할 것이다.

$ git diff

diff --git a/kernel/workqueue.c b/kernel/workqueue.c

index 0ee63af..0679854 100644

--- a/kernel/workqueue.c

+++ b/kernel/workqueue.c

@@ -4087,10 +4087,7 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu,

                if (cpumask_equal(cpumask, pwq->pool->attrs->cpumask))

                        goto out_unlock;

        } else {

-               if (pwq == wq->dfl_pwq)

-                       goto out_unlock;

-               else

-                       goto use_dfl_pwq;

+               goto use_dfl_pwq;

        }


        mutex_unlock(&wq->mutex);

@@ -4100,7 +4097,8 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu,

        if (!pwq) {

                pr_warning("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n",

                           wq->name);

-               goto out_unlock;

+               mutex_lock(&wq->mutex);

+               goto use_dfl_pwq;

        }


        /*


이 상태에서 "git add -p" 를 입력하면, 

$ git add -p

diff --git a/kernel/workqueue.c b/kernel/workqueue.c

index 0ee63af..0679854 100644

--- a/kernel/workqueue.c

+++ b/kernel/workqueue.c

@@ -4087,10 +4087,7 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu,

                if (cpumask_equal(cpumask, pwq->pool->attrs->cpumask))

                        goto out_unlock;

        } else {

-               if (pwq == wq->dfl_pwq)

-                       goto out_unlock;

-               else

-                       goto use_dfl_pwq;

+               goto use_dfl_pwq;

        }


        mutex_unlock(&wq->mutex);

Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? n


알아서 한 블럭씩 분리하여 더 나눌 것인지, 아니면 이부분을 하나의 Commit 으로 만들 것인지 물어본다.

나는 아래의 block 을 먼저 commit 하고 이 부분을 나중에 commit 하려고 한다. 그래서 "n" 을 입력했다.

n 을 입력하면, 

@@ -4100,7 +4097,8 @@ static void wq_update_unbound_numa(struct workqueue_struct *wq, int cpu,

        if (!pwq) {

                pr_warning("workqueue: allocation failed while updating NUMA affinity of \"%s\"\n",

                           wq->name);

-               goto out_unlock;

+               mutex_lock(&wq->mutex);

+               goto use_dfl_pwq;

        }


        /*

Stage this hunk [y,n,q,a,d,/,K,g,e,?]? y

다음 block 의 code를 할 것인지 연속적으로 물어본다. 여기서 "y" 를 입력하면 이 부분만 git add 가 된다.


확인을 해보면,

$ git status

# Not currently on any branch.

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#       modified:   kernel/workqueue.c

#

# Changes not staged for commit:

#   (use "git add <file>..." to update what will be committed)

#   (use "git checkout -- <file>..." to discard changes in working directory)

#

#       modified:   kernel/workqueue.c

#

위에서 처럼 일부는 add 가 되고 나머지는 un-stage 상태가 된다. 


그 다음에

$ git commit -s

제목 쓰고.. 내용 쓰고.. 저장 하고 나온다.


또 그 다음에 나머지 수정 사항을 기록 한다.

$ git add

$ git commit -s

제목 쓰고.. 내용 쓰고.. 저장하고 나온다.


그렇게 하면 의도했던 대로 하나였던 commit 이 두 개로 분리가 된다.


사실 이렇게 하지 않아도 되는데, 지저분하거나 혹은 새로 작성해야 하는 문제가 발생한다. 물론 위와 같은 예제는 간단해서 다시 작성해도 되긴 하지만, 이와 같은 방법을 사용하면 이미 잘 작성된 code 에 실수 등이 발생하지 않을 것이다.(code는 건들지도 않으니.. 물론 분리를 잘못하면 발생하는 문제는 있긴 하다. :-) )


이렇게 해서 patch 를 보내면 된다. 



'Development Tip' 카테고리의 다른 글

VIM 에서 spelling 확인하기  (0) 2016.07.08
Git: 특정 commit 으로 이동 후, amend 하기  (0) 2014.02.28
const char* vs. char const*  (0) 2014.02.19
Fish shell environment  (0) 2013.12.03
Kernel mailing list 활용 방법  (0) 2013.11.08
요즘은 참고할 만한 좋은 사이트와 블로그가 참 많이 있는 것같습니다. 

직접 블로그를 쓰는 것도 좋지만, 더 잘된 곳을 소개하는 것이 효과적인 듯하다. ^^

네이버 블로그 입니다. ID가 johnforstar 이시네요~

http://blog.naver.com/PostView.nhn?blogId=johnforstar&logNo=30095262027

Android Application 개발을 위해 source 버전 관리를 같이 해보는 것도 좋은 방법인 듯 하여, 
Project Hosting을 해주는 곳을 찾아보았다. 

1. Naver 개발자 센터
   - 무료
   - svn version 관리 tool 지원
   - 마일스톤, 게시판 및 issue 등을 관리 할 수 있도록 지원한다.
   - Project member 관리 지원
   - 무료이면서 게시판등을 사용할 수 있고, 공개 및 비공개 Project로 진행 할 수 있다. 게시판등이 사용 및 보기에 편리한 듯. 
아래의 이미지는 Naver 개발 센터에서 가장 인기 있는 CUBRID Project를 Capture함. 


2. Google Project Hosting
   - 무료
   - svn, mercurial 을 지원한다.(mercurial 은 사용해본적이 없어, 잘모른다. 
      mercurial 참고 사이트 : http://mercurial.selenic.com/wiki/UnderstandingMercurial) 
   - mercurial은 다시 사용법을 익혀야 한다는 점에서 패스. 
   - naver 개발자 센터와 마찬가지로 issue 및 게시판을 제공(Wiki 사용법을 익혀야 한다.)
아래의 이미지는 project hosting(google) 에서 "안드로이드"로 검색하여 제일 처음 뜨는 사이트를 capture 한 것임. 

3. bettercodes
   - 무료
   - svn, git 을 제공
   - git repository를 무료로 제공해준다(2GB - Project 개수는 제한이 있는 듯.)
   - 물론 게시판도.. git을 제공해준다는데에 큰 장점이 있어 가입하고 사용해보는 중..
   - 단점이라면.. 영문 사이트라는 것임. 국내에도 git을 지원해주는 곳이 있다면 사용해 봐야 겠음. 

4. Git 지원 사이트 소개 Wiki 

+ Recent posts