```nix
{
src = fetchgit {
url = "git://github.com/NixOS/nix.git";
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
};
}
```
- Better: This is ok, but an archive fetch will still be faster.
```nix
{
src = fetchgit {
url = "https://github.com/NixOS/nix.git";
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
};
}
```
- Best: Fetches a snapshot archive for the given revision.
```nix
{
src = fetchFromGitHub {
owner = "NixOS";
repo = "nix";
rev = "1f795f9f44607cc5bec70d1300150bfefcef2aae";
hash = "sha256-7D4m+saJjbSFP5hOwpQq2FGR2rr+psQMTcyb1ZvtXsQ=";
};
}
```
> [!Note]
> When fetching from GitHub, always reference revisions by their full commit hash.
> GitHub shares commit hashes among all forks and returns `404 Not Found` when a short commit hash is ambiguous.
> It already happened in Nixpkgs for short, 6-character commit hashes.
>
> Pushing large amounts of auto generated commits into forks is a practical vector for a denial-of-service attack, and was already [demonstrated against GitHub Actions Beta](https://blog.teddykatz.com/2019/11/12/github-actions-dos.html).
## Patches
Sometimes, changes are needed to the source to allow building a derivation in nixpkgs, or to get earlier access to an upstream fix or improvement.
When using the `patches` parameter to `mkDerivation`, make sure the patch name clearly describes the reason for the patch, or add a comment.
> [!Note]
> The version of the package does not need to be changed just because a patch is applied. Declarative package installations don't depend on the version, while imperative `nix-env` installations can use [`upgrade --eq/leq/--always`](https://nix.dev/manual/nix/2.25/command-ref/nix-env/upgrade#flags).
>
> See [Versioning](#versioning) for details on package versioning.
### Fetching patches
In the interest of keeping our maintenance burden and the size of Nixpkgs to a minimum, patches already merged upstream or published elsewhere _should_ be retrieved using `fetchpatch2`:
```nix
{
patches = [
(fetchpatch2 {
name = "fix-check-for-using-shared-freetype-lib.patch";
url = "https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/patch/?id=8f5d28536e4518716fdfe974e580194c8f57871d";
hash = "sha256-uRcxaCjd+WAuGrXOmGfFeu79cUILwkRdBu48mwcBE7g=";
})
];
}
```
If a patch is available online but does not cleanly apply, it can be modified in some fixed ways by using additional optional arguments for `fetchpatch2`. Check [the `fetchpatch` reference](https://nixos.org/manual/nixpkgs/unstable/#fetchpatch) for details.
When adding patches in this manner you should be reasonably sure that the used URL is stable. Patches referencing open pull requests will change when the PR is updated and code forges (such as GitHub) usually garbage collect commits that are no longer reachable due to rebases/amends.
### Vendoring patches
In the following cases, a `.patch` file _should_ be added to Nixpkgs repository, instead of retrieved:
- solves problems unique to packaging in Nixpkgs
- cannot be fetched easily
- has a high chance to disappear in the future due to unstable or unreliable URLs
The latter avoids link rot when the upstream abandons, squashes or rebases their change, in which case the commit may get garbage-collected.
```nix
{
patches = [ ./0001-add-missing-include.patch ];
}
```
If you do need to do create this sort of patch file, one way to do so is with git:
1. Move to the root directory of the source code you're patching.
```ShellSession
$ cd the/program/source
```
2. If a git repository is not already present, create one and stage all of the source files.
```ShellSession
$ git init
$ git add .
```
3. Edit some files to make whatever changes need to be included in the patch.