HACKING: rename README-contribution-guidelines
[platform/upstream/coreutils.git] / HACKING
1 Coreutils Contribution Guidelines
2
3
4 Prerequisites
5 =============
6 You will need the "git" version control tools.
7 On Fedora-based systems, do "yum install git".
8 On Debian-based ones install the "git-core" package.
9 Then run "git --version".  If that says it's older than
10 version 1.4.4, then you'd do well to get a newer version.
11 At worst, just download the latest stable release from
12 http://git.or.cz/ and build from source.
13
14 For details on building the programs in this package, see
15 the file, README-hacking.
16
17
18 Use the latest upstream sources
19 ===============================
20 Base any changes you make on the latest upstream sources.
21 You can get a copy of the latest with this command:
22
23     git clone git://git.sv.gnu.org/coreutils
24
25 That downloads the entire repository, including revision control history
26 dating back to 1991.  The repository (the part you download, and which
27 resides in coreutils/.git) currently weighs in at about 30MB.  So you
28 don't want to download it more often than necessary.  Once downloaded,
29 you can get incremental updates by running this command from inside
30 your new coreutils/ directory:
31
32     git pull
33
34
35 *Before* you commit changes
36 ===========================
37
38 In this project, we much prefer patches that automatically record
39 authorship.  That is important not just to give credit where due, but
40 also from a legal standpoint (see below).  To create author-annotated
41 patches with git, you must first tell git who you are.  That information
42 is best recorded in your ~/.gitconfig file.  Edit that file, creating
43 it if needed, and put your name and email address in place of these
44 example values:
45
46 [user]
47   name = Joe X. User
48   email = joe.user@example.com
49
50
51 Your first commit: the quick and dirty way
52 ==========================================
53 First of all, realize that to "commit" a change in git is a purely
54 local operation.  It affects only the local repository (the .git/ dir)
55 in your current coreutils/ hierarchy.
56
57 To try this out, modify a file or two.  If you create a new file, you'll
58 need to tell git about it with "git add new-file.c".  Commit all changes
59 with "git commit -a".  That prompts you for a log message, which should
60 include a one-line summary, a blank line, and ChangeLog-style entries
61 for all affected files.  More on that below.
62
63 Once your change is committed, you can create a proper patch that includes
64 a log message and authorship information as well as any permissions
65 changes.  Use this command to save that single, most-recent change set:
66
67   git format-patch --stdout --signoff HEAD~1 > DIFF
68
69 The trouble with this approach is that you've just checked in a change
70 (remember, it's only local) on the "master" branch, and that's where new
71 changes would normally appear when you pull the latest from "upstream".
72 When you "pull" from a remote repository to get the latest, your local
73 changes on "master" may well induce conflicts.   For this reason, you
74 may want to keep "master" free of any local changes, so that you can
75 use it to track unadulterated upstream sources.
76
77 However, if your cloned directory is for a one-shot patch submission and
78 you're going to remove it right afterwards, then this approach is fine.
79 Otherwise, for a more sustainable (and more generally useful, IMHO)
80 process, read on about "topic" branches.
81
82
83 Make your changes on a private "topic" branch
84 =============================================
85 So you checked out coreutils like this:
86
87   git clone git://git.sv.gnu.org/coreutils
88
89 Now, cd into the coreutils/ directory and run:
90
91   git checkout -b my-topic
92
93 That creates the my-topic branch and puts you on it.
94 To see which branch you're on, type "git branch".
95 Right after the clone, you were on "master" (aka the trunk).
96 To get back to the trunk, do this:
97
98   git checkout master
99
100 Note 1:
101     Be careful to run "git pull" only when on the "master" branch,
102     not when on a branch.  With newer versions of git, you can't cause
103     trouble if you forget, so this is a good reason to ensure you're
104     using 1.5.3.1 or newer.
105
106 Note 2:
107     It's best not to try to switch from one branch to another if
108     you have pending (uncommitted) changes.  Sometimes it works,
109     sometimes the checkout will fail, telling you that your local
110     modifications conflict with changes required to switch branches.
111     However, in any case, you will *not* lose your uncommitted changes.
112
113 Anyhow, get back onto your just-created branch:
114
115   git checkout my-topic
116
117 Now, modify some file and commit it:
118
119   git commit some-file.c
120
121 Personally, no matter what package I'm working on, I find it useful to
122 put the ChangeLog entries *only* in the commit log, initially, unless
123 I plan to commit/push right away.  Otherwise, I tend to get unnecessary
124 merge conflicts with each rebase (see below).  In coreutils, I've gone
125 a step further, and no longer maintain an explicit ChangeLog file in
126 version control.  Instead, in a git working directory, you can view
127 ChangeLog information via "git log".  However, each distribution tarball
128 does include a ChangeLog file that is automatically generated from the
129 git logs.
130
131 So, you've committed a change.  But it's only in your local repository,
132 and only on your "my-topic" branch.  Let's say you wait a day, and
133 then see that someone else changed something and pushed it to the
134 public repository.  Now, you want to update your trunk and "rebase"
135 your changes on the branch so that they are once again relative to the
136 tip of the trunk.  Currently, your branch is attached to the trunk at
137 the next-to-last change set.
138
139 First: update the trunk from the public repo:
140 [you've first made sure that "git diff" produces no output]
141
142   git checkout master
143   git pull
144
145 Now, return to your branch, and "rebase" relative to trunk (master):
146
147   git checkout my-topic
148   git rebase master
149
150 If there are no conflicts, this requires no more work from you.
151 However, let's say there was one in ChangeLog, since you didn't
152 follow my advice and modified it anyway.
153 git rebase will tell you there was a conflict and in which
154 file, and instruct you to resolve it and then resume with
155 "git rebase --continue" once that's done.
156
157 So you resolve as usual, by editing ChangeLog (which has the
158 usual conflict markers), then type "git rebase --continue".
159 That will fail, with a diagnostic telling you to mark
160 the file as "conflict resolved" by doing this:
161
162   git add ChangeLog
163
164 Then, finally, you can proceed (possibly onto more conflict resolution,
165 if there are conflicts in other files):
166
167   git rebase --continue
168
169 Once it finishes, your changes on the branch are now relative to
170 the tip of the trunk.
171
172 Now use git format-patch, as above.
173
174
175 Amending the most recent change on your private branch
176 ======================================================
177 Let's say you've just committed a change on your private
178 branch, and then realize that something about it is not right.
179 It's easy to adjust:
180
181   edit your files # this can include running "git add NEW" or "git rm BAD"
182   git commit --amend -e -a
183   git format-patch --stdout --signoff HEAD~1 > your-branch.diff
184
185 That replaces the most recent commit with the revised one.
186
187
188
189 Coreutils-specific:
190
191 No more ChangeLog files
192 =======================
193 Do not modify any of the ChangeLog files in coreutils.  Starting in
194 2008, the policy changed.  Before, we would insert the exact same text
195 (or worse, sometimes slightly differing) into both the ChangeLog file
196 and the commit log.  Now we put that information only in the commit log,
197 and generate the top-level ChangeLog file from logs at "make dist" time.
198 As such, there are strict requirements on the form of the commit log
199 messages.
200
201
202 Commit log requirements
203 =======================
204 Your commit log should always start with a one-line summary, the second
205 line should be blank, and the remaining lines are usually ChangeLog-style
206 entries for all affected files.  Omit the leading TABs that you're used
207 to seeing in a "real" ChangeLog file.
208
209
210 Use SPACE-only indentation in new files.
211 ========================================
212 In any new file, eliminate all leading TABs (e.g., via running GNU indent
213 with --no-tabs) and put these lines at the end of the file:
214 [FIXME: suggest vim syntax to do same thing, if it can be done safely.
215  Most distros now "set nomodeline" by default for a good reason. ]
216
217 /*
218  * Local variables:
219  * indent-tabs-mode: nil
220  * End:
221  */
222
223 Do not change TABs to spaces or vice versa in any existing file.
224
225
226 Send patches to bug-coreutils@gnu.org
227 =====================================
228
229
230 Add documentation
231 =================
232 If you add a feature or change some user-visible aspect of a program,
233 document it.  If you add an option, document it both in --help output
234 (i.e., in the usage function that generates the --help output) and in
235 doc/coreutils.texi.  The man pages are generated from --help output, so
236 you shouldn't need to change anything under man/.  User-visible changes
237 are usually documented in NEWS, too.
238
239
240 Add tests
241 ==========
242 Nearly every significant change must be accompanied by a test suite
243 addition that exercises it.  If you fix a bug, add at least one test that
244 fails without the patch, but that succeeds once your patch is applied.
245 If you add a feature, add tests to exercise as much of the new code
246 as possible.
247
248 There are hundreds of tests in the tests/ directories.  You can use
249 tests/sample-test as a template, or one of the various Perl-based ones
250 in tests/misc.
251
252 If writing tests is not your thing, don't worry too much about it,
253 but do provide scenarios, input/output pairs, or whatever, along with
254 examples of running the tool to demonstrate the new or changed feature,
255 and someone else will massage that into a test (writing portable tests
256 can be a challenge).
257
258
259 Copyright assignment
260 ====================
261 If your change is significant (i.e., if it adds more than ~10 lines),
262 then you'll have to have a copyright assignment on file with the FSF.
263 Since that involves first an email exchange between you and the FSF,
264 and then the exchange (FSF to you, then back) of an actual sheet of paper
265 with your signature on it, and finally, some administrative processing
266 in Boston, the process can take a few weeks.
267
268 The forms to choose from are in gnulib's doc/Copyright/ directory.
269 If you want to assign a single change, you should use the file,
270 doc/Copyright/request-assign.changes:
271
272     http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=doc/Copyright/request-assign.changes;hb=HEAD
273
274 If you would like to assign past and future coreutils work,
275 you'd use doc/Copyright/request-assign.future:
276
277     http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=doc/Copyright/request-assign.future;hb=HEAD
278
279
280 Run "make syntax-check", or even "make distcheck"
281 ================================================
282 Making either of those targets runs many integrity and
283 coreutils-specific policy-conformance tests.  For example, the former
284 ensures that you add no trailing blanks and no uses of certain deprecated
285 functions.  The latter performs all "syntax-check" tests, and also
286 ensures that the build completes with no warnings when using a certain
287 set of gcc -W... options.  Don't even bother running "make distcheck"
288 unless you have a very up to date installation including recent versions
289 of gcc and the linux kernel, and modern GNU tools.
290
291
292 Ensure that your changes are indented properly.
293 ===============================================
294 Format the code the way GNU indent does.
295 In a file with the "indent-tabs-mode: nil" directive at the end,
296 running "indent --no-tabs" should induce no change.
297 With other files, there will be some existing differences.
298 Try not to add any more.
299
300
301 -------------------------------------------
302
303 Miscellaneous useful git commands
304 =================================
305
306   * gitk: give a graphical view of the revision graph
307   * git log: to get most of the same info in text form
308   * git log -p: same as above, but with diffs
309   * git log -p SOME_FILE: same as above, but limit to SOME_FILE
310   * git reset --soft HEAD^: Commit the delta required to restore
311       state to the revision just before HEAD (i.e., next-to-last).
312   * git rebase -i master: run this from on a branch, and it gives
313       you an interface with which you can reorder and modify arbitrary
314       change sets on that branch.