← Documents Documentation/process/7.AdvancedTopics.rst GitHub 원문 ↗

Linux 6.18.37 · 개발 절차

Git tree 관리와 patch review

Topic branch, 공개 history의 불변성, rebase와 merge, pull request 신뢰, patch review 방법을 설명합니다.

Source pathDocumentation/process/7.AdvancedTopics.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

반복적으로 참여하기 위한 다음 단계

7.AdvancedTopics.rst:3-9

기본 개발 절차를 이해한 뒤에는 patch 수가 늘어날 때 git tree를 관리하는 법과 다른 사람의 patch를 review하는 법이 중요해진다. 두 작업은 커널 개발에 일회성이 아니라 지속적으로 참여하는 기반이다.

Kernel development와 distributed version control

7.AdvancedTopics.rst:11-47

커널의 distributed version control 사용은 2002년 Linus가 proprietary BitKeeper를 쓰기 시작하면서 본격화됐다. BitKeeper 자체는 논쟁적이었지만 repository를 여러 개발자가 분산 관리하는 접근은 개발 속도를 크게 높였다. 이후 free alternative가 등장했고 커널 project는 git을 주 도구로 선택했다.

Git은 patch가 많아질수록 관리 부담을 줄이지만 강력한 만큼 위험도 있다. 이 문서는 git 일반 tutorial이 아니라 커널 개발 절차에서 git이 어떤 역할을 하는지 설명한다.

다른 사람에게 tree를 공개하기 전에 mainline clone, revision history 탐색, commit, branch 사용을 확실히 이해해야 한다. rebase 같은 history rewrite 도구뿐 아니라 ref, remote branch, index, fast-forward merge, push와 pull, detached HEAD 같은 용어와 개념도 익혀야 한다.

Email 제출용 patch를 git으로 생성하는 연습은 git과 kernel workflow를 함께 익히는 좋은 방법이다. 다른 사람이 pull할 tree를 공개하려면 internet에서 접근 가능한 git server나 public hosting이 필요하다. 일정한 활동 기록이 있는 개발자는 kernel.org account를 받을 수도 있지만 쉽게 주어지지는 않는다.

Private development branch와 public topic branch

7.AdvancedTopics.rst:49-68

일반적인 git workflow는 개발 line마다 별도 topic branch를 만든다. Branch는 값싸므로 서로 독립적인 변경을 분리해 관리하는 데 적극적으로 사용한다.

다른 사람에게 pull을 요청할 public branch에서 직접 개발하지 않는다. Development branch에서 patch가 완성되고 제출할 준비가 된 뒤 public branch로 옮긴다.

History rewrite의 이점과 한계

7.AdvancedTopics.rst:70-112

Git은 bisection을 깨뜨리거나 명백한 bug가 있는 patch를 history 안에서 고치고, 오래 작업한 series를 오늘의 mainline 위에서 작성한 것처럼 rebase하며, 변경을 branch 사이로 옮길 수 있다. 적절한 rewrite는 더 깨끗하고 문제 적은 patch set을 만든다.

하지만 rewrite는 이미 test한 tree를 다른 commit으로 바꾸므로 새 tree는 다시 test해야 한다. 공동 작업자는 같은 history를 공유해야 하므로, 다른 사람이 pull한 commit을 rewrite하면 그들의 repository와 작업을 어렵게 만든다.

기본 규칙은 외부로 export한 history를 불변으로 취급하는 것이다. Public server에 push한 뒤에는 rewrite하지 않는다. Git도 non-fast-forward push를 기본적으로 막아 이 규칙을 돕는다.

linux-next conflict를 피하려고 changeset을 tree 사이에서 옮겨야 하는 드문 상황처럼 public rewrite가 불가피할 때도 있지만 예외로 남아야 한다. 이것이 private branch에서 개발하고 충분히 진전된 뒤 public branch로 옮기는 이유다.

Rebase, merge와 rerere

7.AdvancedTopics.rst:103-122

기반 mainline이 전진하면 최신 상태를 따라가기 위해 자주 merge하고 싶어진다. Private branch는 rebase할 수 있지만 이미 공개한 tree는 rebase할 수 없으므로 full merge를 사용해야 한다.

필요한 merge는 타당하지만 지나치게 자주 하면 history가 불필요하게 복잡해진다. 보통 mainline -rc release 같은 명확한 지점에서 드물게 merge하는 편이 좋다. 특정 변경이 걱정되면 private branch에서 test merge를 먼저 수행한다.

git rerere는 merge conflict를 어떻게 해결했는지 기억해 동일한 conflict를 다시 해결하는 일을 줄인다.

Pull을 받을 수 있는 신뢰 만들기

7.AdvancedTopics.rst:124-149

Repository 사이에서 patch를 대량 이동하면 review를 피한 변경이 mainline에 섞일 수 있다. Review되지 않았거나 branch 주제와 무관한 patch를 넣으면 나중에 tree pull을 받기 어려워진다.

Linus의 요지는 git tree를 pull하려면 모든 개별 변경을 다시 손으로 검사하지 않아도 될 만큼 tree 관리자와 절차를 신뢰할 수 있어야 한다는 것이다.

  • 한 branch의 모든 patch를 branch 주제에 밀접하게 유지한다. driver-fixes branch에서 core MM을 바꾸지 않는다.
  • Git tree를 review 절차 우회 수단으로 쓰지 않는다.
  • 관련 mailing list에 tree 요약을 주기적으로 게시한다.
  • 적절한 시점에 linux-next 포함을 요청한다.
  • 다른 사람의 patch를 tree에 받을 때 반드시 review하고 authorship 정보를 보존한다.
  • 제3자를 거쳐 전달된 patch는 필요하면 From: line을 추가해 실제 저자를 기록한다.
  • Pull request에는 repository, branch, pull 결과를 명확히 적고 git request-pull로 형식과 public push 여부를 확인한다.

Patch review

7.AdvancedTopics.rst:151-197

Patch review는 고급 개발자만의 일이 아니다. 다른 사람이 게시한 code를 읽는 것은 kernel programming을 배우는 가장 좋은 방법 가운데 하나이며, reviewer는 항상 부족하므로 초보자도 중요한 기여를 할 수 있다.

경험 많은 개발자의 code를 public하게 질문하기가 부담스러울 수 있지만 누구의 code든 개선될 수 있다. Comment는 비난보다 질문으로 표현하는 편이 좋다. 예를 들어 locking이 틀렸다고 단정하기보다 특정 path에서 lock이 어떻게 release되는지 묻는다.

몇 차례 대화 뒤에도 의견 차이가 멈추면 다른 reviewer나 maintainer에게 의견을 요청한다. 동의하는 사람도 명시적으로 요청받기 전에는 침묵하는 경우가 많고, 여러 사람의 의견은 훨씬 큰 무게를 가진다.

  • coding style과 trailing whitespace
  • 변경 전체가 커널에 바람직한지
  • locking 문제와 excessive stack usage
  • security issue와 기존 code 중복
  • 문서가 충분한지
  • performance 악영향
  • user-space ABI 변경

특정 tag 사용은 의무가 아니다. Reviewed-by만 붙이기보다 어떤 관점 A, B, C를 살펴봤고 괜찮았다는 평문 review가 더 많은 정보를 준다. Maintainer가 review 사실을 알 수 있도록 최소한 reply는 남겨야 한다.

Review가 문제 지적에만 집중하는 부정적인 과정이 되기 쉬우므로, 특히 새 contributor에게는 잘한 부분도 때때로 명시적으로 말하는 것이 좋다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. _development_advancedtopics:
2
3 Advanced topics
4 ===============
5
6 At this point, hopefully, you have a handle on how the development process
7 works. There is still more to learn, however! This section will cover a
8 number of topics which can be helpful for developers wanting to become a
9 regular part of the Linux kernel development process.
10
11 Managing patches with git
12 -------------------------
13
14 The use of distributed version control for the kernel began in early 2002,
15 when Linus first started playing with the proprietary BitKeeper
16 application. While BitKeeper was controversial, the approach to software
17 version management it embodied most certainly was not. Distributed version
18 control enabled an immediate acceleration of the kernel development
19 project. In current times, there are several free alternatives to
20 BitKeeper. For better or for worse, the kernel project has settled on git
21 as its tool of choice.
22
23 Managing patches with git can make life much easier for the developer,
24 especially as the volume of those patches grows. Git also has its rough
25 edges and poses certain hazards; it is a young and powerful tool which is
26 still being civilized by its developers. This document will not attempt to
27 teach the reader how to use git; that would be sufficient material for a
28 long document in its own right. Instead, the focus here will be on how git
29 fits into the kernel development process in particular. Developers who
30 wish to come up to speed with git will find more information at:
31
32 https://git-scm.com/
33
34 https://www.kernel.org/pub/software/scm/git/docs/user-manual.html
35
36 and on various tutorials found on the web.
37
38 The first order of business is to read the above sites and get a solid
39 understanding of how git works before trying to use it to make patches
40 available to others. A git-using developer should be able to obtain a copy
41 of the mainline repository, explore the revision history, commit changes to
42 the tree, use branches, etc. An understanding of git's tools for the
43 rewriting of history (such as rebase) is also useful. Git comes with its
44 own terminology and concepts; a new user of git should know about refs,
45 remote branches, the index, fast-forward merges, pushes and pulls, detached
46 heads, etc. It can all be a little intimidating at the outset, but the
47 concepts are not that hard to grasp with a bit of study.
48
49 Using git to generate patches for submission by email can be a good
50 exercise while coming up to speed.
51
52 When you are ready to start putting up git trees for others to look at, you
53 will, of course, need a server that can be pulled from. Setting up such a
54 server with git-daemon is relatively straightforward if you have a system
55 which is accessible to the Internet. Otherwise, free, public hosting sites
56 (Github, for example) are starting to appear on the net. Established
57 developers can get an account on kernel.org, but those are not easy to come
58 by; see https://kernel.org/faq/ for more information.
59
60 The normal git workflow involves the use of a lot of branches. Each line
61 of development can be separated into a separate "topic branch" and
62 maintained independently. Branches in git are cheap, there is no reason to
63 not make free use of them. And, in any case, you should not do your
64 development in any branch which you intend to ask others to pull from.
65 Publicly-available branches should be created with care; merge in patches
66 from development branches when they are in complete form and ready to go -
67 not before.
68
69 Git provides some powerful tools which can allow you to rewrite your
70 development history. An inconvenient patch (one which breaks bisection,
71 say, or which has some other sort of obvious bug) can be fixed in place or
72 made to disappear from the history entirely. A patch series can be
73 rewritten as if it had been written on top of today's mainline, even though
74 you have been working on it for months. Changes can be transparently
75 shifted from one branch to another. And so on. Judicious use of git's
76 ability to revise history can help in the creation of clean patch sets with
77 fewer problems.
78
79 Excessive use of this capability can lead to other problems, though, beyond
80 a simple obsession for the creation of the perfect project history.
81 Rewriting history will rewrite the changes contained in that history,
82 turning a tested (hopefully) kernel tree into an untested one. But, beyond
83 that, developers cannot easily collaborate if they do not have a shared
84 view of the project history; if you rewrite history which other developers
85 have pulled into their repositories, you will make life much more difficult
86 for those developers. So a simple rule of thumb applies here: history
87 which has been exported to others should generally be seen as immutable
88 thereafter.
89
90 So, once you push a set of changes to your publicly-available server, those
91 changes should not be rewritten. Git will attempt to enforce this rule if
92 you try to push changes which do not result in a fast-forward merge
93 (i.e. changes which do not share the same history). It is possible to
94 override this check, and there may be times when it is necessary to rewrite
95 an exported tree. Moving changesets between trees to avoid conflicts in
96 linux-next is one example. But such actions should be rare. This is one
97 of the reasons why development should be done in private branches (which
98 can be rewritten if necessary) and only moved into public branches when
99 it's in a reasonably advanced state.
100
101 As the mainline (or other tree upon which a set of changes is based)
102 advances, it is tempting to merge with that tree to stay on the leading
103 edge. For a private branch, rebasing can be an easy way to keep up with
104 another tree, but rebasing is not an option once a tree is exported to the
105 world. Once that happens, a full merge must be done. Merging occasionally
106 makes good sense, but overly frequent merges can clutter the history
107 needlessly. Suggested technique in this case is to merge infrequently, and
108 generally only at specific release points (such as a mainline -rc
109 release). If you are nervous about specific changes, you can always
110 perform test merges in a private branch. The git "rerere" tool can be
111 useful in such situations; it remembers how merge conflicts were resolved
112 so that you don't have to do the same work twice.
113
114 One of the biggest recurring complaints about tools like git is this: the
115 mass movement of patches from one repository to another makes it easy to
116 slip in ill-advised changes which go into the mainline below the review
117 radar. Kernel developers tend to get unhappy when they see that kind of
118 thing happening; putting up a git tree with unreviewed or off-topic patches
119 can affect your ability to get trees pulled in the future. Quoting Linus:
120
121 ::
122
123 You can send me patches, but for me to pull a git patch from you, I
124 need to know that you know what you're doing, and I need to be able
125 to trust things *without* then having to go and check every
126 individual change by hand.
127
128 (https://lwn.net/Articles/224135/).
129
130 To avoid this kind of situation, ensure that all patches within a given
131 branch stick closely to the associated topic; a "driver fixes" branch
132 should not be making changes to the core memory management code. And, most
133 importantly, do not use a git tree to bypass the review process. Post an
134 occasional summary of the tree to the relevant list, and, when the time is
135 right, request that the tree be included in linux-next.
136
137 If and when others start to send patches for inclusion into your tree,
138 don't forget to review them. Also ensure that you maintain the correct
139 authorship information; the git "am" tool does its best in this regard, but
140 you may have to add a "From:" line to the patch if it has been relayed to
141 you via a third party.
142
143 When requesting a pull, be sure to give all the relevant information: where
144 your tree is, what branch to pull, and what changes will result from the
145 pull. The git request-pull command can be helpful in this regard; it will
146 format the request as other developers expect, and will also check to be
147 sure that you have remembered to push those changes to the public server.
148
149 .. _development_advancedtopics_reviews:
150
151 Reviewing patches
152 -----------------
153
154 Some readers will certainly object to putting this section with "advanced
155 topics" on the grounds that even beginning kernel developers should be
156 reviewing patches. It is certainly true that there is no better way to
157 learn how to program in the kernel environment than by looking at code
158 posted by others. In addition, reviewers are forever in short supply; by
159 looking at code you can make a significant contribution to the process as a
160 whole.
161
162 Reviewing code can be an intimidating prospect, especially for a new kernel
163 developer who may well feel nervous about questioning code - in public -
164 which has been posted by those with more experience. Even code written by
165 the most experienced developers can be improved, though. Perhaps the best
166 piece of advice for reviewers (all reviewers) is this: phrase review
167 comments as questions rather than criticisms. Asking "how does the lock
168 get released in this path?" will always work better than stating "the
169 locking here is wrong."
170
171 Another technique that is useful in case of a disagreement is to ask for others
172 to chime in. If a discussion reaches a stalemate after a few exchanges,
173 then call for opinions of other reviewers or maintainers. Often those in
174 agreement with a reviewer remain silent unless called upon.
175 The opinion of multiple people carries exponentially more weight.
176
177 Different developers will review code from different points of view. Some
178 are mostly concerned with coding style and whether code lines have trailing
179 white space. Others will focus primarily on whether the change implemented
180 by the patch as a whole is a good thing for the kernel or not. Yet others
181 will check for problematic locking, excessive stack usage, possible
182 security issues, duplication of code found elsewhere, adequate
183 documentation, adverse effects on performance, user-space ABI changes, etc.
184 All types of review, if they lead to better code going into the kernel, are
185 welcome and worthwhile.
186
187 There is no strict requirement to use specific tags like ``Reviewed-by``.
188 In fact reviews in plain English are more informative and encouraged
189 even when a tag is provided, e.g. "I looked at aspects A, B and C of this
190 submission and it looks good to me."
191 Some form of a review message or reply is obviously necessary otherwise
192 maintainers will not know that the reviewer has looked at the patch at all!
193
194 Last but not least patch review may become a negative process, focused
195 on pointing out problems. Please throw in a compliment once in a while,
196 particularly for newbies!
197

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Kernel 개발의 고급 주제

1-9

개발 절차의 기본을 익힌 뒤 정기적으로 Linux kernel 개발에 참여하려는 developer에게 도움이 되는 Git tree 관리와 patch review 주제를 다룬다.

분산 version control과 Git

11-36

Kernel의 분산 version control 사용은 Linus가 proprietary BitKeeper를 시험한 2002년 초에 시작되었다. BitKeeper 자체는 논란이 있었지만 분산 version 관리 방식은 kernel 개발을 즉시 가속했다. 이후 여러 free 대안이 등장했고 kernel project는 Git을 표준 도구로 선택했다.

Patch 수가 늘어날수록 Git은 developer의 작업을 크게 단순화하지만 강력한 만큼 위험과 거친 부분도 있다. 이 문서는 Git 사용법 자체보다 Git이 kernel 개발 절차에 어떻게 들어가는지 설명한다.

공개 tree를 만들기 전에 익힐 개념

38-58

다른 사람이 사용할 patch를 Git으로 제공하기 전에 mainline repository 복제, revision history 탐색, commit, branch를 확실히 익혀야 한다. Rebase 같은 history rewriting 도구와 ref, remote branch, index, fast-forward merge, push, pull, detached HEAD 같은 용어도 이해해야 한다.

처음에는 email 제출용 patch를 Git으로 생성하는 연습이 좋다. 다른 사람이 pull할 tree를 공개하려면 Internet에서 접근할 Git server가 필요하다. git-daemon으로 직접 구성하거나 public hosting을 사용할 수 있다. Established developer는 kernel.org account를 얻을 수 있지만 쉽지는 않으며 https://kernel.org/faq/를 참고한다.

Private development branch와 public topic branch

60-67

일반적인 Git workflow는 개발 line마다 독립적인 topic branch를 많이 사용한다. Git branch는 비용이 작으므로 적극적으로 활용한다.

다른 사람에게 pull을 요청할 public branch에서 직접 개발해서는 안 된다. Public branch는 신중하게 만들고 development branch의 patch가 완전하고 제출 가능한 상태가 된 뒤에만 merge한다.

History rewriting의 이익과 경계

69-99

Git은 bisection을 깨는 patch나 명백한 bug를 고치거나 history에서 제거하고, 수개월 개발한 patch series를 최신 mainline 위에서 작성한 것처럼 다시 구성하며, branch 사이에 변경을 옮길 수 있다. 신중한 history revision은 깨끗한 patch set을 만드는 데 유용하다.

하지만 history를 다시 쓰면 시험한 tree가 새로운 미시험 tree로 바뀐다. 다른 developer가 이미 pull한 history를 바꾸면 공통 history view가 사라져 협업이 매우 어려워진다. 따라서 외부에 공개한 history는 원칙적으로 immutable하게 취급한다.

Public server에 push한 변경은 다시 쓰지 않는다. Git은 fast-forward가 아닌 push를 기본적으로 거부해 이 규칙을 돕는다. linux-next conflict를 피하려고 changeset을 tree 사이에 옮기는 예외가 있을 수 있지만 드물어야 한다. 개발은 rewrite 가능한 private branch에서 하고 충분히 성숙한 뒤 public branch로 옮긴다.

Rebase, merge, rerere

101-112

Base tree가 발전할 때 private branch는 rebase로 따라갈 수 있지만 공개한 tree에는 rebase를 사용할 수 없고 full merge를 해야 한다. Merge 자체는 필요하지만 너무 자주 하면 history가 불필요하게 복잡해진다.

Mainline -rc release 같은 특정 지점에서 드물게 merge하는 방식을 권한다. 불안한 변경은 private branch에서 test merge할 수 있고 Git rerere는 이전 merge conflict 해결법을 기억해 같은 작업의 반복을 줄인다.

Pull의 전제는 review와 신뢰

114-135

Repository 사이에서 patch를 대량 이동하면 review를 피한 부적절한 변경이 mainline에 섞이기 쉽다. Unreviewed patch나 topic과 무관한 patch가 든 Git tree를 공개하면 앞으로 tree가 pull될 가능성까지 떨어질 수 있다.

Linus의 설명을 옮기면 다음과 같다. Patch를 직접 보낼 수는 있지만 Git tree를 pull하려면 상대가 무엇을 하는지 알고 있으며 모든 변경을 일일이 다시 검사하지 않아도 될 만큼 신뢰할 수 있어야 한다. 출처는 https://lwn.net/Articles/224135/ 이다.

Branch의 모든 patch는 topic에 밀접하게 맞아야 한다. Driver fix branch가 core memory management를 바꾸어서는 안 된다. Git tree로 review 절차를 우회하지 말고 관련 list에 tree 요약을 주기적으로 게시하며 적절한 시점에 linux-next 포함을 요청한다.

다른 사람의 patch와 pull request 관리

137-147

다른 사람이 tree 포함을 요청하며 patch를 보내기 시작하면 maintainer도 patch를 검토해야 한다. Git am이 authorship 보존을 돕지만 third party를 거쳐 전달된 patch에는 올바른 저자를 표시하기 위해 From: line을 직접 추가해야 할 수 있다.

Pull을 요청할 때는 tree 위치, pull할 branch, pull로 생기는 변경을 모두 제공한다. git request-pull은 kernel developer가 기대하는 형식으로 요청을 만들고 변경을 public server에 push했는지도 검사한다.

Patch review는 초보자에게도 필요한 활동

149-169

Patch review를 advanced topic으로 분류하는 데 이견이 있을 수 있다. 다른 사람이 게시한 code를 읽는 것보다 kernel programming을 잘 배우는 방법은 드물고 reviewer는 늘 부족하므로 초보 developer도 review로 큰 기여를 할 수 있다.

경험 많은 developer의 공개 code에 질문하는 일은 부담스러울 수 있지만 어떤 code도 개선될 수 있다. Review comment는 비난보다 질문으로 표현하는 것이 좋다. '여기 locking은 틀렸다'보다 '이 path에서는 lock이 어떻게 release되는가?'가 더 효과적이다.

의견 충돌과 다양한 review 관점

171-185

몇 차례 대화 뒤 논의가 교착되면 다른 reviewer나 maintainer에게 의견을 요청한다. 동의하는 사람은 요청받기 전까지 조용히 있는 경우가 많고 여러 사람의 의견은 훨씬 큰 무게를 갖는다.

Developer마다 coding style, trailing whitespace, 변경 자체의 타당성, locking, stack 사용량, security, code 중복, documentation, 성능, userspace ABI 등 서로 다른 관점에서 검토한다. 더 나은 code가 kernel에 들어가게 한다면 모든 종류의 review가 가치 있다.

Review message와 긍정적 feedback

187-196

Reviewed-by 같은 특정 tag를 반드시 사용할 필요는 없다. Tag를 주더라도 '이 제출의 A, B, C 측면을 살펴보았고 문제가 없어 보인다'처럼 plain English로 검토 범위를 설명하는 것이 더 유익하다.

어떤 형태로든 review message나 reply가 있어야 maintainer가 review 사실을 알 수 있다. Patch review는 문제 지적에 치우쳐 부정적인 과정이 되기 쉬우므로 가끔은 잘한 점도 말하며 특히 초보 contributor에게 긍정적 feedback을 제공한다.