at 18.03-beta 24 kB view raw
1<chapter xmlns="http://docbook.org/ns/docbook" 2 xmlns:xlink="http://www.w3.org/1999/xlink" 3 xml:id="chap-conventions"> 4 5<title>Coding conventions</title> 6 7 8<section xml:id="sec-syntax"><title>Syntax</title> 9 10<itemizedlist> 11 12 <listitem><para>Use 2 spaces of indentation per indentation level in 13 Nix expressions, 4 spaces in shell scripts.</para></listitem> 14 15 <listitem><para>Do not use tab characters, i.e. configure your 16 editor to use soft tabs. For instance, use <literal>(setq-default 17 indent-tabs-mode nil)</literal> in Emacs. Everybody has different 18 tab settings so it’s asking for trouble.</para></listitem> 19 20 <listitem><para>Use <literal>lowerCamelCase</literal> for variable 21 names, not <literal>UpperCamelCase</literal>. Note, this rule does 22 not apply to package attribute names, which instead follow the rules 23 in <xref linkend="sec-package-naming"/>.</para></listitem> 24 25 <listitem><para>Function calls with attribute set arguments are 26 written as 27 28<programlisting> 29foo { 30 arg = ...; 31} 32</programlisting> 33 34 not 35 36<programlisting> 37foo 38{ 39 arg = ...; 40} 41</programlisting> 42 43 Also fine is 44 45<programlisting> 46foo { arg = ...; } 47</programlisting> 48 49 if it's a short call.</para></listitem> 50 51 <listitem><para>In attribute sets or lists that span multiple lines, 52 the attribute names or list elements should be aligned: 53 54<programlisting> 55# A long list. 56list = 57 [ elem1 58 elem2 59 elem3 60 ]; 61 62# A long attribute set. 63attrs = 64 { attr1 = short_expr; 65 attr2 = 66 if true then big_expr else big_expr; 67 }; 68 69# Alternatively: 70attrs = { 71 attr1 = short_expr; 72 attr2 = 73 if true then big_expr else big_expr; 74}; 75</programlisting> 76 77 </para></listitem> 78 79 <listitem><para>Short lists or attribute sets can be written on one 80 line: 81 82<programlisting> 83# A short list. 84list = [ elem1 elem2 elem3 ]; 85 86# A short set. 87attrs = { x = 1280; y = 1024; }; 88</programlisting> 89 90 </para></listitem> 91 92 <listitem><para>Breaking in the middle of a function argument can 93 give hard-to-read code, like 94 95<programlisting> 96someFunction { x = 1280; 97 y = 1024; } otherArg 98 yetAnotherArg 99</programlisting> 100 101 (especially if the argument is very large, spanning multiple 102 lines).</para> 103 104 <para>Better: 105 106<programlisting> 107someFunction 108 { x = 1280; y = 1024; } 109 otherArg 110 yetAnotherArg 111</programlisting> 112 113 or 114 115<programlisting> 116let res = { x = 1280; y = 1024; }; 117in someFunction res otherArg yetAnotherArg 118</programlisting> 119 120 </para></listitem> 121 122 <listitem><para>The bodies of functions, asserts, and withs are not 123 indented to prevent a lot of superfluous indentation levels, i.e. 124 125<programlisting> 126{ arg1, arg2 }: 127assert system == "i686-linux"; 128stdenv.mkDerivation { ... 129</programlisting> 130 131 not 132 133<programlisting> 134{ arg1, arg2 }: 135 assert system == "i686-linux"; 136 stdenv.mkDerivation { ... 137</programlisting> 138 139 </para></listitem> 140 141 <listitem><para>Function formal arguments are written as: 142 143<programlisting> 144{ arg1, arg2, arg3 }: 145</programlisting> 146 147 but if they don't fit on one line they're written as: 148 149<programlisting> 150{ arg1, arg2, arg3 151, arg4, ... 152, # Some comment... 153 argN 154}: 155</programlisting> 156 157 </para></listitem> 158 159 <listitem><para>Functions should list their expected arguments as 160 precisely as possible. That is, write 161 162<programlisting> 163{ stdenv, fetchurl, perl }: <replaceable>...</replaceable> 164</programlisting> 165 166 instead of 167 168<programlisting> 169args: with args; <replaceable>...</replaceable> 170</programlisting> 171 172 or 173 174<programlisting> 175{ stdenv, fetchurl, perl, ... }: <replaceable>...</replaceable> 176</programlisting> 177 178 </para> 179 180 <para>For functions that are truly generic in the number of 181 arguments (such as wrappers around <varname>mkDerivation</varname>) 182 that have some required arguments, you should write them using an 183 <literal>@</literal>-pattern: 184 185<programlisting> 186{ stdenv, doCoverageAnalysis ? false, ... } @ args: 187 188stdenv.mkDerivation (args // { 189 <replaceable>...</replaceable> if doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable> 190}) 191</programlisting> 192 193 instead of 194 195<programlisting> 196args: 197 198args.stdenv.mkDerivation (args // { 199 <replaceable>...</replaceable> if args ? doCoverageAnalysis &amp;&amp; args.doCoverageAnalysis then "bla" else "" <replaceable>...</replaceable> 200}) 201</programlisting> 202 203 </para></listitem> 204 205</itemizedlist> 206 207</section> 208 209 210<section xml:id="sec-package-naming"><title>Package naming</title> 211 212<para>In Nixpkgs, there are generally three different names associated with a package: 213 214<itemizedlist> 215 216 <listitem><para>The <varname>name</varname> attribute of the 217 derivation (excluding the version part). This is what most users 218 see, in particular when using 219 <command>nix-env</command>.</para></listitem> 220 221 <listitem><para>The variable name used for the instantiated package 222 in <filename>all-packages.nix</filename>, and when passing it as a 223 dependency to other functions. Typically this is called the 224 <emphasis>package attribute name</emphasis>. This is what Nix 225 expression authors see. It can also be used when installing using 226 <command>nix-env -iA</command>.</para></listitem> 227 228 <listitem><para>The filename for (the directory containing) the Nix 229 expression.</para></listitem> 230 231</itemizedlist> 232 233Most of the time, these are the same. For instance, the package 234<literal>e2fsprogs</literal> has a <varname>name</varname> attribute 235<literal>"e2fsprogs-<replaceable>version</replaceable>"</literal>, is 236bound to the variable name <varname>e2fsprogs</varname> in 237<filename>all-packages.nix</filename>, and the Nix expression is in 238<filename>pkgs/os-specific/linux/e2fsprogs/default.nix</filename>. 239</para> 240 241<para>There are a few naming guidelines: 242 243<itemizedlist> 244 245 <listitem><para>Generally, try to stick to the upstream package 246 name.</para></listitem> 247 248 <listitem><para>Don’t use uppercase letters in the 249 <literal>name</literal> attribute — e.g., 250 <literal>"mplayer-1.0rc2"</literal> instead of 251 <literal>"MPlayer-1.0rc2"</literal>.</para></listitem> 252 253 <listitem><para>The version part of the <literal>name</literal> 254 attribute <emphasis>must</emphasis> start with a digit (following a 255 dash) — e.g., <literal>"hello-0.3.1rc2"</literal>.</para></listitem> 256 257 <listitem><para>If a package is not a release but a commit from a repository, then 258 the version part of the name <emphasis>must</emphasis> be the date of that 259 (fetched) commit. The date must be in <literal>"YYYY-MM-DD"</literal> format. 260 Also append <literal>"unstable"</literal> to the name - e.g., 261 <literal>"pkgname-unstable-2014-09-23"</literal>.</para></listitem> 262 263 <listitem><para>Dashes in the package name should be preserved in 264 new variable names, rather than converted to underscores or camel 265 cased — e.g., <varname>http-parser</varname> instead of 266 <varname>http_parser</varname> or <varname>httpParser</varname>. The 267 hyphenated style is preferred in all three package 268 names.</para></listitem> 269 270 <listitem><para>If there are multiple versions of a package, this 271 should be reflected in the variable names in 272 <filename>all-packages.nix</filename>, 273 e.g. <varname>json-c-0-9</varname> and <varname>json-c-0-11</varname>. 274 If there is an obvious “default” version, make an attribute like 275 <literal>json-c = json-c-0-9;</literal>. 276 See also <xref linkend="sec-versioning" /></para></listitem> 277 278</itemizedlist> 279 280</para> 281 282</section> 283 284 285<section xml:id="sec-organisation"><title>File naming and organisation</title> 286 287<para>Names of files and directories should be in lowercase, with 288dashes between words — not in camel case. For instance, it should be 289<filename>all-packages.nix</filename>, not 290<filename>allPackages.nix</filename> or 291<filename>AllPackages.nix</filename>.</para> 292 293<section xml:id="sec-hierarchy"><title>Hierarchy</title> 294 295<para>Each package should be stored in its own directory somewhere in 296the <filename>pkgs/</filename> tree, i.e. in 297<filename>pkgs/<replaceable>category</replaceable>/<replaceable>subcategory</replaceable>/<replaceable>...</replaceable>/<replaceable>pkgname</replaceable></filename>. 298Below are some rules for picking the right category for a package. 299Many packages fall under several categories; what matters is the 300<emphasis>primary</emphasis> purpose of a package. For example, the 301<literal>libxml2</literal> package builds both a library and some 302tools; but it’s a library foremost, so it goes under 303<filename>pkgs/development/libraries</filename>.</para> 304 305<para>When in doubt, consider refactoring the 306<filename>pkgs/</filename> tree, e.g. creating new categories or 307splitting up an existing category.</para> 308 309<variablelist> 310 <varlistentry> 311 <term>If it’s used to support <emphasis>software development</emphasis>:</term> 312 <listitem> 313 <variablelist> 314 <varlistentry> 315 <term>If it’s a <emphasis>library</emphasis> used by other packages:</term> 316 <listitem> 317 <para><filename>development/libraries</filename> (e.g. <filename>libxml2</filename>)</para> 318 </listitem> 319 </varlistentry> 320 <varlistentry> 321 <term>If it’s a <emphasis>compiler</emphasis>:</term> 322 <listitem> 323 <para><filename>development/compilers</filename> (e.g. <filename>gcc</filename>)</para> 324 </listitem> 325 </varlistentry> 326 <varlistentry> 327 <term>If it’s an <emphasis>interpreter</emphasis>:</term> 328 <listitem> 329 <para><filename>development/interpreters</filename> (e.g. <filename>guile</filename>)</para> 330 </listitem> 331 </varlistentry> 332 <varlistentry> 333 <term>If it’s a (set of) development <emphasis>tool(s)</emphasis>:</term> 334 <listitem> 335 <variablelist> 336 <varlistentry> 337 <term>If it’s a <emphasis>parser generator</emphasis> (including lexers):</term> 338 <listitem> 339 <para><filename>development/tools/parsing</filename> (e.g. <filename>bison</filename>, <filename>flex</filename>)</para> 340 </listitem> 341 </varlistentry> 342 <varlistentry> 343 <term>If it’s a <emphasis>build manager</emphasis>:</term> 344 <listitem> 345 <para><filename>development/tools/build-managers</filename> (e.g. <filename>gnumake</filename>)</para> 346 </listitem> 347 </varlistentry> 348 <varlistentry> 349 <term>Else:</term> 350 <listitem> 351 <para><filename>development/tools/misc</filename> (e.g. <filename>binutils</filename>)</para> 352 </listitem> 353 </varlistentry> 354 </variablelist> 355 </listitem> 356 </varlistentry> 357 <varlistentry> 358 <term>Else:</term> 359 <listitem> 360 <para><filename>development/misc</filename></para> 361 </listitem> 362 </varlistentry> 363 </variablelist> 364 </listitem> 365 </varlistentry> 366 <varlistentry> 367 <term>If it’s a (set of) <emphasis>tool(s)</emphasis>:</term> 368 <listitem> 369 <para>(A tool is a relatively small program, especially one intended 370 to be used non-interactively.)</para> 371 <variablelist> 372 <varlistentry> 373 <term>If it’s for <emphasis>networking</emphasis>:</term> 374 <listitem> 375 <para><filename>tools/networking</filename> (e.g. <filename>wget</filename>)</para> 376 </listitem> 377 </varlistentry> 378 <varlistentry> 379 <term>If it’s for <emphasis>text processing</emphasis>:</term> 380 <listitem> 381 <para><filename>tools/text</filename> (e.g. <filename>diffutils</filename>)</para> 382 </listitem> 383 </varlistentry> 384 <varlistentry> 385 <term>If it’s a <emphasis>system utility</emphasis>, i.e., 386 something related or essential to the operation of a 387 system:</term> 388 <listitem> 389 <para><filename>tools/system</filename> (e.g. <filename>cron</filename>)</para> 390 </listitem> 391 </varlistentry> 392 <varlistentry> 393 <term>If it’s an <emphasis>archiver</emphasis> (which may 394 include a compression function):</term> 395 <listitem> 396 <para><filename>tools/archivers</filename> (e.g. <filename>zip</filename>, <filename>tar</filename>)</para> 397 </listitem> 398 </varlistentry> 399 <varlistentry> 400 <term>If it’s a <emphasis>compression</emphasis> program:</term> 401 <listitem> 402 <para><filename>tools/compression</filename> (e.g. <filename>gzip</filename>, <filename>bzip2</filename>)</para> 403 </listitem> 404 </varlistentry> 405 <varlistentry> 406 <term>If it’s a <emphasis>security</emphasis>-related program:</term> 407 <listitem> 408 <para><filename>tools/security</filename> (e.g. <filename>nmap</filename>, <filename>gnupg</filename>)</para> 409 </listitem> 410 </varlistentry> 411 <varlistentry> 412 <term>Else:</term> 413 <listitem> 414 <para><filename>tools/misc</filename></para> 415 </listitem> 416 </varlistentry> 417 </variablelist> 418 </listitem> 419 </varlistentry> 420 <varlistentry> 421 <term>If it’s a <emphasis>shell</emphasis>:</term> 422 <listitem> 423 <para><filename>shells</filename> (e.g. <filename>bash</filename>)</para> 424 </listitem> 425 </varlistentry> 426 <varlistentry> 427 <term>If it’s a <emphasis>server</emphasis>:</term> 428 <listitem> 429 <variablelist> 430 <varlistentry> 431 <term>If it’s a web server:</term> 432 <listitem> 433 <para><filename>servers/http</filename> (e.g. <filename>apache-httpd</filename>)</para> 434 </listitem> 435 </varlistentry> 436 <varlistentry> 437 <term>If it’s an implementation of the X Windowing System:</term> 438 <listitem> 439 <para><filename>servers/x11</filename> (e.g. <filename>xorg</filename> — this includes the client libraries and programs)</para> 440 </listitem> 441 </varlistentry> 442 <varlistentry> 443 <term>Else:</term> 444 <listitem> 445 <para><filename>servers/misc</filename></para> 446 </listitem> 447 </varlistentry> 448 </variablelist> 449 </listitem> 450 </varlistentry> 451 <varlistentry> 452 <term>If it’s a <emphasis>desktop environment</emphasis>:</term> 453 <listitem> 454 <para><filename>desktops</filename> (e.g. <filename>kde</filename>, <filename>gnome</filename>, <filename>enlightenment</filename>)</para> 455 </listitem> 456 </varlistentry> 457 <varlistentry> 458 <term>If it’s a <emphasis>window manager</emphasis>:</term> 459 <listitem> 460 <para><filename>applications/window-managers</filename> (e.g. <filename>awesome</filename>, <filename>stumpwm</filename>)</para> 461 </listitem> 462 </varlistentry> 463 <varlistentry> 464 <term>If it’s an <emphasis>application</emphasis>:</term> 465 <listitem> 466 <para>A (typically large) program with a distinct user 467 interface, primarily used interactively.</para> 468 <variablelist> 469 <varlistentry> 470 <term>If it’s a <emphasis>version management system</emphasis>:</term> 471 <listitem> 472 <para><filename>applications/version-management</filename> (e.g. <filename>subversion</filename>)</para> 473 </listitem> 474 </varlistentry> 475 <varlistentry> 476 <term>If it’s for <emphasis>video playback / editing</emphasis>:</term> 477 <listitem> 478 <para><filename>applications/video</filename> (e.g. <filename>vlc</filename>)</para> 479 </listitem> 480 </varlistentry> 481 <varlistentry> 482 <term>If it’s for <emphasis>graphics viewing / editing</emphasis>:</term> 483 <listitem> 484 <para><filename>applications/graphics</filename> (e.g. <filename>gimp</filename>)</para> 485 </listitem> 486 </varlistentry> 487 <varlistentry> 488 <term>If it’s for <emphasis>networking</emphasis>:</term> 489 <listitem> 490 <variablelist> 491 <varlistentry> 492 <term>If it’s a <emphasis>mailreader</emphasis>:</term> 493 <listitem> 494 <para><filename>applications/networking/mailreaders</filename> (e.g. <filename>thunderbird</filename>)</para> 495 </listitem> 496 </varlistentry> 497 <varlistentry> 498 <term>If it’s a <emphasis>newsreader</emphasis>:</term> 499 <listitem> 500 <para><filename>applications/networking/newsreaders</filename> (e.g. <filename>pan</filename>)</para> 501 </listitem> 502 </varlistentry> 503 <varlistentry> 504 <term>If it’s a <emphasis>web browser</emphasis>:</term> 505 <listitem> 506 <para><filename>applications/networking/browsers</filename> (e.g. <filename>firefox</filename>)</para> 507 </listitem> 508 </varlistentry> 509 <varlistentry> 510 <term>Else:</term> 511 <listitem> 512 <para><filename>applications/networking/misc</filename></para> 513 </listitem> 514 </varlistentry> 515 </variablelist> 516 </listitem> 517 </varlistentry> 518 <varlistentry> 519 <term>Else:</term> 520 <listitem> 521 <para><filename>applications/misc</filename></para> 522 </listitem> 523 </varlistentry> 524 </variablelist> 525 </listitem> 526 </varlistentry> 527 <varlistentry> 528 <term>If it’s <emphasis>data</emphasis> (i.e., does not have a 529 straight-forward executable semantics):</term> 530 <listitem> 531 <variablelist> 532 <varlistentry> 533 <term>If it’s a <emphasis>font</emphasis>:</term> 534 <listitem> 535 <para><filename>data/fonts</filename></para> 536 </listitem> 537 </varlistentry> 538 <varlistentry> 539 <term>If it’s related to <emphasis>SGML/XML processing</emphasis>:</term> 540 <listitem> 541 <variablelist> 542 <varlistentry> 543 <term>If it’s an <emphasis>XML DTD</emphasis>:</term> 544 <listitem> 545 <para><filename>data/sgml+xml/schemas/xml-dtd</filename> (e.g. <filename>docbook</filename>)</para> 546 </listitem> 547 </varlistentry> 548 <varlistentry> 549 <term>If it’s an <emphasis>XSLT stylesheet</emphasis>:</term> 550 <listitem> 551 <para>(Okay, these are executable...)</para> 552 <para><filename>data/sgml+xml/stylesheets/xslt</filename> (e.g. <filename>docbook-xsl</filename>)</para> 553 </listitem> 554 </varlistentry> 555 </variablelist> 556 </listitem> 557 </varlistentry> 558 </variablelist> 559 </listitem> 560 </varlistentry> 561 <varlistentry> 562 <term>If it’s a <emphasis>game</emphasis>:</term> 563 <listitem> 564 <para><filename>games</filename></para> 565 </listitem> 566 </varlistentry> 567 <varlistentry> 568 <term>Else:</term> 569 <listitem> 570 <para><filename>misc</filename></para> 571 </listitem> 572 </varlistentry> 573</variablelist> 574 575</section> 576 577<section xml:id="sec-versioning"><title>Versioning</title> 578 579<para>Because every version of a package in Nixpkgs creates a 580potential maintenance burden, old versions of a package should not be 581kept unless there is a good reason to do so. For instance, Nixpkgs 582contains several versions of GCC because other packages don’t build 583with the latest version of GCC. Other examples are having both the 584latest stable and latest pre-release version of a package, or to keep 585several major releases of an application that differ significantly in 586functionality.</para> 587 588<para>If there is only one version of a package, its Nix expression 589should be named <filename>e2fsprogs/default.nix</filename>. If there 590are multiple versions, this should be reflected in the filename, 591e.g. <filename>e2fsprogs/1.41.8.nix</filename> and 592<filename>e2fsprogs/1.41.9.nix</filename>. The version in the 593filename should leave out unnecessary detail. For instance, if we 594keep the latest Firefox 2.0.x and 3.5.x versions in Nixpkgs, they 595should be named <filename>firefox/2.0.nix</filename> and 596<filename>firefox/3.5.nix</filename>, respectively (which, at a given 597point, might contain versions <literal>2.0.0.20</literal> and 598<literal>3.5.4</literal>). If a version requires many auxiliary 599files, you can use a subdirectory for each version, 600e.g. <filename>firefox/2.0/default.nix</filename> and 601<filename>firefox/3.5/default.nix</filename>.</para> 602 603<para>All versions of a package <emphasis>must</emphasis> be included 604in <filename>all-packages.nix</filename> to make sure that they 605evaluate correctly.</para> 606 607</section> 608 609</section> 610<section xml:id="sec-sources"><title>Fetching Sources</title> 611 <para>There are multiple ways to fetch a package source in nixpkgs. The 612 general guideline is that you should package sources with a high degree of 613 availability. Right now there is only one fetcher which has mirroring 614 support and that is <literal>fetchurl</literal>. Note that you should also 615 prefer protocols which have a corresponding proxy environment variable. 616 </para> 617 <para>You can find many source fetch helpers in <literal>pkgs/build-support/fetch*</literal>. 618 </para> 619 <para>In the file <literal>pkgs/top-level/all-packages.nix</literal> you can 620 find fetch helpers, these have names on the form 621 <literal>fetchFrom*</literal>. The intention of these are to provide 622 snapshot fetches but using the same api as some of the version controlled 623 fetchers from <literal>pkgs/build-support/</literal>. As an example going 624 from bad to good: 625 <itemizedlist> 626 <listitem> 627 <para>Bad: Uses <literal>git://</literal> which won't be proxied. 628<programlisting> 629src = fetchgit { 630 url = "git://github.com/NixOS/nix.git"; 631 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; 632 sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg"; 633} 634</programlisting> 635 </para> 636 </listitem> 637 <listitem> 638 <para>Better: This is ok, but an archive fetch will still be faster. 639<programlisting> 640src = fetchgit { 641 url = "https://github.com/NixOS/nix.git"; 642 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; 643 sha256 = "1cw5fszffl5pkpa6s6wjnkiv6lm5k618s32sp60kvmvpy7a2v9kg"; 644} 645</programlisting> 646 </para> 647 </listitem> 648 <listitem> 649 <para>Best: Fetches a snapshot archive and you get the rev you want. 650<programlisting> 651src = fetchFromGitHub { 652 owner = "NixOS"; 653 repo = "nix"; 654 rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae"; 655 sha256 = "04yri911rj9j19qqqn6m82266fl05pz98inasni0vxr1cf1gdgv9"; 656} 657</programlisting> 658 </para> 659 </listitem> 660 </itemizedlist> 661 </para> 662</section> 663 664<section xml:id="sec-patches"><title>Patches</title> 665 <para>Patches available online should be retrieved using 666 <literal>fetchpatch</literal>.</para> 667 <para> 668<programlisting> 669patches = [ 670 (fetchpatch { 671 name = "fix-check-for-using-shared-freetype-lib.patch"; 672 url = "http://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=8f5d285"; 673 sha256 = "1f0k043rng7f0rfl9hhb89qzvvksqmkrikmm38p61yfx51l325xr"; 674 }) 675]; 676</programlisting> 677 </para> 678 <para>Otherwise, you can add a <literal>.patch</literal> file to the 679 <literal>nixpkgs</literal> repository. In the interest of keeping our 680 maintenance burden to a minimum, only patches that are unique 681 to <literal>nixpkgs</literal> should be added in this way.</para> 682<para><programlisting> 683patches = [ ./0001-changes.patch ]; 684</programlisting></para> 685 <para>If you do need to do create this sort of patch file, 686 one way to do so is with git: 687 <orderedlist> 688 <listitem><para>Move to the root directory of the source code 689 you're patching.<screen> 690$ cd the/program/source</screen></para></listitem> 691 <listitem><para>If a git repository is not already present, 692 create one and stage all of the source files.<screen> 693$ git init 694$ git add .</screen></para></listitem> 695 <listitem><para>Edit some files to make whatever changes need 696 to be included in the patch.</para></listitem> 697 <listitem><para>Use git to create a diff, and pipe the output 698 to a patch file:<screen> 699$ git diff > nixpkgs/pkgs/the/package/0001-changes.patch</screen> 700 </para></listitem> 701 </orderedlist></para> 702</section> 703 704</chapter>