1 Coreutils Contribution Guidelines
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.
14 For details on building the programs in this package, see
15 the file, README-hacking.
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:
23 git clone git://git.sv.gnu.org/coreutils
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 one of these commands from
30 inside your new coreutils/ directory:
32 If you have made *no* changes:
35 If you *have* made changes and mistakenly committed them to "master",
36 do the following to put your changes on a private branch, "br", and
37 to restore master to its unmodified (relative-to-upstream) state:
40 git reset --hard origin
42 Then "git pull" should work.
45 *Before* you commit changes
46 ===========================
48 In this project, we much prefer patches that automatically record
49 authorship. That is important not just to give credit where due, but
50 also from a legal standpoint (see below). To create author-annotated
51 patches with git, you must first tell git who you are. That information
52 is best recorded in your ~/.gitconfig file. Edit that file, creating
53 it if needed, and put your name and email address in place of these
58 email = joe.user@example.com
61 Your first commit: the quick and dirty way
62 ==========================================
63 First of all, realize that to "commit" a change in git is a purely
64 local operation. It affects only the local repository (the .git/ dir)
65 in your current coreutils/ hierarchy.
67 To try this out, modify a file or two. If you create a new file, you'll
68 need to tell git about it with "git add new-file.c". Commit all changes
69 with "git commit -a". That prompts you for a log message, which should
70 include a one-line summary, a blank line, and ChangeLog-style entries
71 for all affected files. More on that below.
73 Once your change is committed, you can create a proper patch that includes
74 a log message and authorship information as well as any permissions
75 changes. Use this command to save that single, most-recent change set:
77 git format-patch --stdout -1 > DIFF
79 The trouble with this approach is that you've just checked in a change
80 (remember, it's only local) on the "master" branch, and that's where new
81 changes would normally appear when you pull the latest from "upstream".
82 When you "pull" from a remote repository to get the latest, your local
83 changes on "master" may well induce conflicts. For this reason, you
84 may want to keep "master" free of any local changes, so that you can
85 use it to track unadulterated upstream sources.
87 However, if your cloned directory is for a one-shot patch submission and
88 you're going to remove it right afterwards, then this approach is fine.
89 Otherwise, for a more sustainable (and more generally useful, IMHO)
90 process, read on about "topic" branches.
93 Make your changes on a private "topic" branch
94 =============================================
95 So you checked out coreutils like this:
97 git clone git://git.sv.gnu.org/coreutils
99 Now, cd into the coreutils/ directory and run:
101 git checkout -b my-topic
103 That creates the my-topic branch and puts you on it.
104 To see which branch you're on, type "git branch".
105 Right after the clone, you were on "master" (aka the trunk).
106 To get back to the trunk, do this:
111 Be careful to run "git pull" only when on the "master" branch,
112 not when on a branch. With newer versions of git, you can't cause
113 trouble if you forget, so this is a good reason to ensure you're
114 using 1.5.3.1 or newer.
117 It's best not to try to switch from one branch to another if
118 you have pending (uncommitted) changes. Sometimes it works,
119 sometimes the checkout will fail, telling you that your local
120 modifications conflict with changes required to switch branches.
121 However, in any case, you will *not* lose your uncommitted changes.
123 Anyhow, get back onto your just-created branch:
125 git checkout my-topic
127 Now, modify some file and commit it:
129 git commit some-file.c
131 Personally, no matter what package I'm working on, I find it useful to
132 put the ChangeLog entries *only* in the commit log, initially, unless
133 I plan to commit/push right away. Otherwise, I tend to get unnecessary
134 merge conflicts with each rebase (see below). In coreutils, I've gone
135 a step further, and no longer maintain an explicit ChangeLog file in
136 version control. Instead, in a git working directory, you can view
137 ChangeLog information via "git log". However, each distribution tarball
138 does include a ChangeLog file that is automatically generated from the
141 So, you've committed a change. But it's only in your local repository,
142 and only on your "my-topic" branch. Let's say you wait a day, and
143 then see that someone else changed something and pushed it to the
144 public repository. Now, you want to update your trunk and "rebase"
145 your changes on the branch so that they are once again relative to the
146 tip of the trunk. Currently, your branch is attached to the trunk at
147 the next-to-last change set.
149 First: update the trunk from the public repo:
150 [you've first made sure that "git diff" produces no output]
155 Now, return to your branch, and "rebase" relative to trunk (master):
157 git checkout my-topic
160 If there are no conflicts, this requires no more work from you.
161 However, let's say there was one in ChangeLog, since you didn't
162 follow my advice and modified it anyway.
163 git rebase will tell you there was a conflict and in which
164 file, and instruct you to resolve it and then resume with
165 "git rebase --continue" once that's done.
167 So you resolve as usual, by editing ChangeLog (which has the
168 usual conflict markers), then type "git rebase --continue".
169 That will fail, with a diagnostic telling you to mark
170 the file as "conflict resolved" by doing this:
174 Then, finally, you can proceed (possibly onto more conflict resolution,
175 if there are conflicts in other files):
177 git rebase --continue
179 Once it finishes, your changes on the branch are now relative to
180 the tip of the trunk.
182 Now use git format-patch, as above.
185 Amending the most recent change on your private branch
186 ======================================================
187 Let's say you've just committed a change on your private
188 branch, and then realize that something about it is not right.
191 edit your files # this can include running "git add NEW" or "git rm BAD"
192 git commit --amend -a
193 git format-patch --stdout -1 > your-branch.diff
195 That replaces the most recent change-set with the revised one.
201 No more ChangeLog files
202 =======================
203 Do not modify any of the ChangeLog files in coreutils. Starting in
204 2008, the policy changed. Before, we would insert the exact same text
205 (or worse, sometimes slightly differing) into both the ChangeLog file
206 and the commit log. Now we put that information only in the commit log,
207 and generate the top-level ChangeLog file from logs at "make dist" time.
208 As such, there are strict requirements on the form of the commit log
212 Commit log requirements
213 =======================
214 Your commit log should always start with a one-line summary, the second
215 line should be blank, and the remaining lines are usually ChangeLog-style
216 entries for all affected files. Omit the leading TABs that you're used
217 to seeing in a "real" ChangeLog file, but keep the maximum line length
218 at 72 or smaller, so that the generated ChangeLog lines, each with its
219 leading TAB, will not exceed 80 columns.
221 Try to make the summary line fit one of the following forms:
223 program_name: change-description
224 prog1, prog2: change-description
225 doc: change-description
226 tests: change-description
227 build: change-description
228 maint: change-description
231 Use SPACE-only indentation in new files.
232 ========================================
233 In any new file, eliminate all leading TABs (e.g., via running GNU indent
234 with --no-tabs) and put these lines at the end of the file:
235 [FIXME: suggest vim syntax to do same thing, if it can be done safely.
236 Most distros now "set nomodeline" by default for a good reason. ]
240 * indent-tabs-mode: nil
244 Do not change TABs to spaces or vice versa in any existing file.
247 Send patches to the address listed in --help output
248 ===================================================
249 Please follow the guidelines in the "Sending your patches." section of
250 git's own SubmittingPatches:
252 http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches
257 If you add a feature or change some user-visible aspect of a program,
258 document it. If you add an option, document it both in --help output
259 (i.e., in the usage function that generates the --help output) and in
260 doc/*.texi. The man pages are generated from --help output, so
261 you shouldn't need to change anything under man/. User-visible changes
262 are usually documented in NEWS, too.
264 When writing prose (documentation, comments, log entries), use an
265 active voice, not a passive one. I.e., say "print the frobnozzle",
266 not "the frobnozzle will be printed".
268 Please add comments per the GNU Coding Standard:
269 http://www.gnu.org/prep/standards/html_node/Comments.html
272 Minor syntactic preferences
273 ===========================
274 [I hesitate to write this one down, because it appears to be an
275 acquired taste, at least for native-English speakers. It seems odd
276 (if not truly backwards) to nearly anyone who doesn't have a strong
277 mathematics background and perhaps a streak of something odd in their
279 In writing arithmetic comparisons, use "<" and "<=" rather than
280 ">" and ">=". For some justification, read this:
281 http://thread.gmane.org/gmane.comp.version-control.git/3903/focus=4126
284 Write "Type const *var", not "const Type *var".
285 FIXME: dig up justification
288 Be nice to translators
289 ======================
290 Don't change translatable strings if you can avoid it.
291 If you must rearrange individual lines (e.g., in multi-line --help
292 strings), extract and create new strings, rather than extracting
293 and moving into existing blocks. This avoids making unnecessary
294 work for translators.
299 Nearly every significant change must be accompanied by a test suite
300 addition that exercises it. If you fix a bug, add at least one test that
301 fails without the patch, but that succeeds once your patch is applied.
302 If you add a feature, add tests to exercise as much of the new code
303 as possible. Note to run tests/misc/newtest in isolation you can do:
305 (cd tests && make check TESTS=misc/newtest VERBOSE=yes)
307 There are hundreds of tests in the tests/ directories. You can use
308 tests/sample-test as a template, or one of the various Perl-based ones
311 If writing tests is not your thing, don't worry too much about it,
312 but do provide scenarios, input/output pairs, or whatever, along with
313 examples of running the tool to demonstrate the new or changed feature,
314 and someone else will massage that into a test (writing portable tests
320 If your change is significant (i.e., if it adds more than ~10 lines),
321 then you'll have to have a copyright assignment on file with the FSF.
322 Since that involves first an email exchange between you and the FSF,
323 and then the exchange (FSF to you, then back) of an actual sheet of paper
324 with your signature on it, and finally, some administrative processing
325 in Boston, the process can take a few weeks.
327 The forms to choose from are in gnulib's doc/Copyright/ directory.
328 If you want to assign a single change, you should use the file,
329 doc/Copyright/request-assign.changes:
331 http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=doc/Copyright/request-assign.changes;hb=HEAD
333 If you would like to assign past and future contributions to a project,
334 you'd use doc/Copyright/request-assign.future:
336 http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=doc/Copyright/request-assign.future;hb=HEAD
338 You may make assignments for up to four projects at a time.
340 In case you're wondering why we bother with all of this, read this:
342 http://www.gnu.org/licenses/why-assign.html
345 Run "make syntax-check", or even "make distcheck"
346 ================================================
347 Making either of those targets runs many integrity and
348 project-specific policy-conformance tests. For example, the former
349 ensures that you add no trailing blanks and no uses of certain deprecated
350 functions. The latter performs all "syntax-check" tests, and also
351 ensures that the build completes with no warnings when using a certain
352 set of gcc -W... options. Don't even bother running "make distcheck"
353 unless you have a reasonably up to date installation including recent
354 versions of gcc and the linux kernel, and modern GNU tools.
357 Ensure that your changes are indented properly.
358 ===============================================
359 Format the code the way GNU indent does.
360 In a file with the "indent-tabs-mode: nil" directive at the end,
361 running "indent --no-tabs" should induce no change.
362 With other files, there will be some existing differences.
363 Try not to add any more.
366 Avoid trailing white space
367 ==========================
368 You may notice that the only trailing blanks in coreutils'
369 version-controlled files are in a single directory: tests/pr,
370 which contains expected output from various invocations of pr.
372 Do not add any more trailing blanks anywhere. While "make syntax-check"
373 will alert you if you slip up, it's better to nip any problem in the
374 bud, as you're typing. A good way to help you adapt to this rule is
375 to configure your editor to highlight any offending characters in the
376 files you edit. If you use Emacs, customize its font-lock mode (FIXME:
377 provide more detail) or try one of its whitespace packages. This appears
378 to be the one that will end up in emacs 23:
380 http://www.emacswiki.org/emacs/WhiteSpace
382 [that page says its version also works with emacs 21 and 22]
383 If you use vim, add this to ~/.vimrc:
386 highlight RedundantSpaces ctermbg=red guibg=red
387 match RedundantSpaces /\s\+$\| \+\ze\t/
390 Git can help too, by stopping you from committing any change that would
391 add trailing blanks. The example pre-commit hook contains code to check
392 for trailing whitespace and spaces before tabs; enable it by moving it
393 to the right place and making sure it is executable:
395 mv .git/hooks/pre-commit.sample .git/hooks/pre-commit
397 With a repository created by git-1.5.6 or older, use this command:
399 chmod +x .git/hooks/pre-commit
401 To manually check for whitespace errors before committing, you can use
405 Git also has some settings to enable suitable internal whitespace checks.
406 See the manpage for git-apply for details.
409 -------------------------------------------
411 Miscellaneous useful git commands
412 =================================
414 * gitk: give a graphical view of the revision graph of the current branch
415 * gitk --all: same, but display all branches
416 * git log: to get most of the same info in text form
417 * git log -p: same as above, but with diffs
418 * git log -p SOME_FILE: same as above, but limit to SOME_FILE
419 * git log -p -2 SOME_FILE: same as above, but print only two deltas
420 * git log -p -1: print the most recently committed change set
421 * git format-patch --stdout -1 > FILE: output the most recently committed
422 change set, in a format suitable to be submitted and/or applied via
424 * git reset --soft HEAD^: Commit the delta required to restore
425 state to the revision just before HEAD (i.e., next-to-last).
426 * git rebase -i master: run this from on a branch, and it gives
427 you an interface with which you can reorder and modify arbitrary
428 change sets on that branch.
430 * if you "misplace" a change set, i.e., via git reset --hard ..., so that
431 it's no longer reachable by any branch, you can use "git fsck" to find
432 its SHA1 and then tag it or cherry-pick it onto an existing branch.
433 For example, run this:
434 git fsck --lost-found HEAD && cd .git/lost-found/commit \
435 && for i in *; do git show $i|grep SOME_IDENTIFYING_STRING \
437 The "git fsck ..." command creates the .git/lost-found/... hierarchy
438 listing all unreachable objects. Then the for loop
439 print SHA1s for commits that match via log or patch.
440 For example, say that found 556fbb57216b119155cdda824c98dc579b8121c8,
441 you could run "git show 556fbb57216b119" to examine the change set,
442 or "git checkout -b found 556fbb5721" to give it a branch name.
443 Finally, you might run "git checkout master && git cherry-pick 556fbb5721"
444 to put that change on the tip of "master".
446 -------------------------------------------
450 If you don't know where to start, check out the TODO file for projects
451 that look like they're at your skill-/interest-level. Another good
452 option is always to improve tests. You never know what you might
453 uncover when you improve test coverage, and even if you don't find
454 any bugs your contribution is sure to be appreciated.
456 A good way to quickly assess current test coverage is to use "lcov"
457 to generate HTML coverage reports. Follow these steps:
459 # configure with coverage information
460 ./configure CFLAGS="-g -fprofile-arcs -ftest-coverage"
462 # run whatever tests you want, i.e.:
465 lcov -t coreutils -q -d lib -b lib -o lib.lcov -c
466 lcov -t coreutils -q -d src -b src -o src.lcov -c
467 # generate HTML from the output
468 genhtml -p `pwd` -t coreutils -q --output-directory lcov-html *.lcov
470 Then just open the index.html file (in the generated lcov-html directory)
471 in your favorite web browser.
473 ========================================================================
474 Copyright (C) 2009 Free Software Foundation, Inc.
476 Permission is granted to copy, distribute and/or modify this document
477 under the terms of the GNU Free Documentation License, Version 1.2 or
478 any later version published by the Free Software Foundation; with no
479 Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
480 Texts. A copy of the license is included in the ``GNU Free
481 Documentation License'' file as part of this distribution.