The original builtins.fetchGit
docs; see also comment in Nix issue #5128.
builtins.fetchGit referenceToGitRepo -> storeResult
Fetch a Git repo.
referenceToGitRepo = URL | path | gitArgs
URL :: string = httpURL | httpsURL | ftpURL | fileURL
Supported code hosting services: GitHub, GitLab, SourceHut.
httpURL = string
Needs to conform to the http://
URI scheme (see RFC 9110, section 4.2).
httpsURL = string
Needs to conform to the https://
URI scheme (see RFC 9110, section 4.2).
ftpURL = string
Needs to conform to the ftp://
URI scheme (see RFC 1738, section 3.2).
webLikeURL :: string = httpURL | httpsURL | ftpURL
fileURL :: string = "file://"
+ fileURLPathPart
fileURLPathPart = string
fileURLPathPart is a shorthand for fileURL (i.e., it will be prefixed with "file://"
during evaluation) therefore both need to conform to the file://
URI scheme (see the path syntax of RFC 8089).
path = Nix path | fileURLPathPart
gitArgs :: attribute set =
{ url
:: (URL | path);
[ name
:: string ? "source"
];
[ ref
:: gitReference ? "HEAD"
];
[ rev
:: gitFullCommitHash ? <ref
dereferenced> ];
[ submodules
:: boolean ? false
];
[ shallow
:: boolean ? false
];
[ allRefs
:: boolean ? false
];
}
webLikeGitArgs :: attribute set =
(Erlang-y) gitArgs#{ url
:: webLikeURL; }
(Haskell-y) gitArgs { url
:: webLikeURL; }
pathLikeGitArgs :: attribute set =
(Erlang-y) gitArgs#{ url
:: (path | fileURL); }
(Haskell-y) gitArgs#{ url
:: (path | fileURL); }
webLike = webLikeURL | webLikeGitArgs
Argument that is a URL or has a URL member conforming to the http://
, https://
, and ftp://
URI schemes.
pathLike = path | fileURL | pathLikeGitArgs Argument that resolves or has a member that resolves to a file system path.
gitReference = string
Needs to be valid Git reference.
gitFullCommitHash = string
Has to be full SHA-1 (for now object name (40-byte hexadecimal string) that refers to an existing commit in the repo.
storeResult :: attribute set =
{ lastModified
:: ?;
lastModifiedDate
:: ?;
narHash
:: ?;
outPath
:: nixStorePath;
rev
:: gitFullCommitHash;
revCount
:: ?;
shortRev
:: ?;
submodules
:: boolean;
}
builtins.fetchGit
behaves differently when called with pathLike or webLike arguments.
These sections describe the behaviour of builtins.fetchGit
when called with webLike arguments:
-
1.1.1 webLikeURL type argument: string that conforms to the
http://
,https://
, andftp://
URI schemes. -
1.1.2 webLikeGitArgs type argument: same as gitArgs attribute set, except that the mandatory
url
attribute value is a webLikeURL
NOTE
The
file://
URI scheme is omitted on purpose, and is discussed in section 1.2 "Path-like" semantics.
builtins.fetchGit string
String format | Outcome | ||
---|---|---|---|
webLikeURL | httpURL | "http://..." |
The latest commit (or HEAD) of the repo's default branch (typically called main ormaster ) will be fetched. |
httpsURL | "https://..." |
||
ftpURL | "ftp://..." |
HTTPS examples with the supported code hosting sites:
builtins.fetchGit "https://github.com/NixOS/nix"
builtins.fetchGit "https://git.sr.ht/~rycee/configurations"
builtins.fetchGit "https://gitlab.com/rycee/home-manager"
NOTE
gitArgs
attributesrev
andref
will only be discussed in subsequent sections, but they also needed to be addressed here because of the significant role they play regarding the call results.
builtins.fetchGit attribute set
gitArgs attributes |
Outcome | Example argument | Example resolved to full webLikeGitArgs attribute set | ||
---|---|---|---|---|---|
url attribute (mandatory) |
rev attribute (optional) |
ref attribute (optional) |
|||
webLikeURL | omitted1.1.2-1 | omitted (or default value of HEAD used) |
Same asbuiltins.fetchGit webLikeURL(see Table 1.1.1-1 above) |
{ url = "https://github.com/nixos/nix"; } |
{ url = "https://github.com/NixOS/nix"; name = "source"; ref = "HEAD"; rev = "<SHA-1 commit hash of HEAD>" submodules = false; shallow = false; allRefs = false; } |
present | ignored1.1.2-2 | Fetch repo at rev commit |
{ url = "https://github.com/nixos/nix"; rev = "be4654c344f0745d4c2eefb33a878bd1f23f6b40"; } |
{ url = "https://github.com/nixos/nix"; name = "source"; ref = "" rev = "be4654c344f0745d4c2eefb33a878bd1f23f6b40"; submodules = false; shallow = false; allRefs = false; } |
|
omitted1.1.2-1 | present | Fetch repo at ref branch / tag |
{ url = "https://github.com/nixos/nix"; ref = "refs/tags/2.10.3"; } |
{ url = "https://github.com/nixos/nix"; name = "source"; ref = "refs/tags/2.10.3"; rev = "309c2e27542818b74219d6825e322b8965c7ad69"; submodules = false; shallow = false; allRefs = false; } |
[1.1.2-1]: See section 3.3 rev
[1.1.2-2]: See section 3.4 ref
Calls with pathLike arguments attempt to fetch a repo in a directory on a local or remote file system. The target repo may be a project under active development so their status and state may need to be determined before trying to copy the repo to the Nix store.
That is, characteristics that builtins.fetchGit
cares about.
The status of a Git repo is
-
dirty, if there are modified tracked files and/or staged changes. (Untracked content does not count.)
-
clean, if the output of
git diff-index HEAD
is empty. (If there are only untracked files ingit status
, the repo is clean.)
The state of a Git repo is the specific commit where the HEAD reference points to (directly or indirectly) at the moment when the repo is fetched.
Directly, if the repo is in a "detached HEAD" state, and indirectly when the commit is also the target of other references as shown on the figure below.
1.2.1.2-1. State of a Git repoLEGEND: orange label = branch, blue label = tag
1.2.2. Argument of type Nix path
, fileURL
, or fileURLPathPart
STATUS | De-reference process | |||
---|---|---|---|---|
dirty | clean | |||
STATE | on BRANCH |
Copy directory contents verbatim | Fetch repo at HEAD of BRANCH |
HEAD -> refs/heads/BRANCH -> <SHA-1 commit hash> |
at TAG |
Copy directory contents verbatim | Fetch repo at TAG |
HEAD -> refs/tags/TAG -> <SHA-1 commit hash> |
|
detached HEAD | Copy directory contents verbatim | Fetch repo at HEAD | HEAD -> <SHA-1 commit hash> |
In fact, the 3 "STATE" rows could easily be collapsed into one as Git branches and tags are only labels to a Git object and what matters to fetchGit
is the specific commit at the end of the de-reference process.
Example calls:
-
via Nix path:
builtins.fetchGit ~/clones/nix
-
via fileURL:
builtins.fetchGit "file:///home/nix_user/clones/nix"
-
via fileURLPathPart:
builtins.fetchGit "/home/nix_user/clones/nix"
This means one of the following:
-
via {
url
:: Nix path }builtins.fetchGit { url = ~/clones/nix; ... }
-
via {
url
:: fileURLPathPart }builtins.fetchGit { url = "/home/nix_user/clones/nix"; ... }
-
via {
url
:: fileURL }builtins.fetchGit { url = "file:///home/nix_user/clones/nix"; ... }
The following table takes advantage of the fact that state is simply determined by the current value of the HEAD reference:
NOTE
gitArgs
attributesrev
andref
will only be discussed in subsequent sections, but they also needed to be addressed here because of the significant role they play regarding the call results.
STATUS | gitArgs attributes |
Outcome | Example argument | ||
---|---|---|---|---|---|
url attribute (mandatory) |
rev attribute (optional) |
ref attribute (optional) |
|||
dirty | Nix path | fileURLPathPart | fileURL (See examples at the top of this section.) |
omitted1.2.3-1 | omitted (or default value of HEAD used) |
Copy directory contents verbatim |
{ url = "https://github.com/nixos/nix"; } |
clean | omitted1.2.3-1 | omitted (or default value of HEAD used) |
Fetch repo at HEAD | ||
ignored1.2.3-2 | present | ignored1.2.3-3 | Ignore changes (if any) and fetch repo at rev commit |
{ url = "https://github.com/nixos/nix"; rev = "be4654c344f0745d4c2eefb33a878bd1f23f6b40"; } |
|
ignored1.2.3-2 | omitted1.2.3-1 | present | Ignore changes (if any) and fetch repo at ref tag / branch |
{ url = "https://github.com/nixos/nix"; ref = "refs/tags/2.10.3"; } |
[1.2.3-1]: See section 3.3 rev
[1.2.3-2]: When ref
or rev
is present, the intention is probably to fetch a known past state from the repo's history, thus the most recent changes are not relevant (neither the status of the repo).
[1.2.3-3]: See section 3.4 ref
As a corollary, here are some tips:
-
If you need to fetch a local repo, calling
builtins.fetchGit
withref
(branch or tag) orrev
(commit hash) will make sure that a repo is fetched with a predictable content, ignoring any changes that may have been made since you last touched it. -
If you are packaging a project under active development and want to test changes without commiting, you'll probably want to call
builtins.fetchGit
with{ url = ...; }
or the specified in 1.2.2. Argument of typeNix path
,fileURL
, orfileURLPathPart
.
Reminder:
gitArgs :: attribute set =
{ url
:: (URL | path);
[ name
:: string ? "source"
];
[ ref
:: gitReference ? "HEAD"
];
[ rev
:: gitFullCommitHash ? <ref
dereferenced> ];
[ submodules
:: boolean ? false
];
[ shallow
:: boolean ? false
];
[ allRefs
:: boolean ? false
];
}
Description | This attribute is covered extensively in section 1. Behaviour (specifically, in sections 1.1.2 webLikeGitArgs type argument and 1.2.3 pathLikeGitArgs type argument). |
---|---|
Type | string |
Default value | none |
Description | The name part of the Nix store path where the Git repo's content will be copied to. |
---|---|
Type | string |
Default value | "source" |
Examples:
nix-repl> builtins.fetchGit { url = ./.; }
{ ...; outPath = "/nix/store/zwp1brk7ndhls3br4hk4h9xhpii17zs5-source"; ...; }
nix-repl> builtins.fetchGit { url = ./.; name = "miez"; }
{ ...; outPath = "/nix/store/zwp1brk7ndhls3br4hk4h9xhpii17zs5-miez"; ...; }
Description | The rev attribute is used to refer to a specific commit by the full SHA-1 Git object name (40-byte hexadecimal string) - or as it is more colloquially called, the commit hash. |
---|---|
Type | string |
Additional constraints |
40-byte hexadecimal SHA-1 string |
Default value | The dereferenced value of the Git reference held by the ref attribute. (See next section.) |
Sections 1.1.2 webLikeGitArgs type argument and 1.2.3 pathLikeGitArgs type argument) in 1. Behaviour describe the prevailing behaviour builtins.fetchgit
when the rev
attribute is used.
NOTE
Specifying the
rev
attribute will render theref
attribute irrelevant no matter if it is included in the input attribute set or not. See next section for more.
Description | The ref attribute accepts a Git reference that is present in the target repo.
|
---|---|
Type | string |
Additional constraints |
See Git reference syntax |
Default value | "HEAD" |
WARNING
By default, the
ref
value is prefixed withrefs/heads/
. After Nix 2.3.0, it will not be prefixed withrefs/heads/
ifref
starts withrefs/
.
3.3.1 ref
attribute ignored when the rev
attribute is provided
The rev
attribute (i.e., the commit hash) has higher specificity; a ref
reference will need to be resolved and its value may change with time, but a commit hash will always point to the same exact commit object and thus to the same state of the the repo during the lifetime of a Git repo. (TODO: right?)
TODO: Re-work original examples
TODO/NOTE: Stopping here for now to wait for the resolution of comment on Nix issue #5128
Quick notes (expect this to be edited):
The in-docs links (e.g., links to types such as "string", "attribute set", etc.) are just empty ones for now.
The inspiration for the "pseudo types" section come from the Erlang docs that is also a dynamically typed language, but has a "sub-language" for type specification for functions and each function doc starts with these, thus making the descriptions unambiguous.