-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce libgit2 #9240
Introduce libgit2 #9240
Conversation
🎉 All dependencies have been resolved ! |
…or() This is for graceful migration to lazy-trees fetchers (which are all accessor-based). Eventually fetch() will be removed.
This replaces most calls to the "git" binary with libgit2.
Instead of making a complete copy of the repo, fetching the submodules, and writing the result to the store (which is all superexpensive), we now fetch the submodules recursively using the Git fetcher, and return a union accessor that "mounts" the accessors for the submodules on top of the root accessor.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Triaged in Nix team meeting:
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-11-03-nix-team-meeting-minutes-100/35245/1 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-11-06-nix-team-meeting-minutes-101/35247/1 |
std::vector<Submodule> submodules; | ||
}; | ||
|
||
virtual WorkdirInfo getWorkdirInfo() = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about bare repos?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK bare repos just work. There is a test in functional/flakes/flakes.sh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No significant issues. LGTM if you could implement/address the suggestions (this review + previous one + John's).
.expired = !locked && (settings.tarballTtl.get() == 0 || timestamp + settings.tarballTtl < time(0)), | ||
.infoAttrs = jsonToAttrs(nlohmann::json::parse(infoJSON)), | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cache behavior is hard to follow, but I suggest we fix that forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar for the many interactions with the Inputs
object. I can't claim to fully understand how the attributes "evolve", let alone prove to myself that requirements about caching and reproducibility are upheld, but I figure I will have a better understanding after completing something based on
Not a blocker for merging this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may consider using an existing wrapper, such as https://github.com/AndreyG/libgit2cpp, but this can be done later.
Co-authored-by: Robert Hensing <[email protected]>
Co-authored-by: Robert Hensing <[email protected]>
Tested on nix flake prefetch 'git+https://github.com/blender/blender.git?rev=4ed8a360e956daf2591add4d3c9ec0719e2628fe&submodules=1'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question about shallow+caching. Otherwise LGTM
if (isShallow && !getShallowAttr(input)) | ||
throw Error("'%s' is a shallow Git repository, but shallow repositories are only allowed when `shallow = true;` is specified", repoInfo.url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this check needed?
What if the repo was fetched shallowly and then later we need it without shallow?
If it's part of the cache key that would be a solution. I'd consider that a performance bug still, but could be fixed after merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is much likely a bug in this (already before this PR). If:
- a shallow remote is fetched with
shallow = true
- later the remote unshallows
- another revision is fetched from the same remote with
shallow = false
...then this error would trigger and the only way to fix it is deleting the nix cache directory.
This bug could only ever trigger on remote repos, as local repos don't get cached via ~/.cache
.
One could argue that this bug is very unlikely to trigger because remote repos are usually never shallow.
It seems to me that the only reason this check has to exist is because on shallow clones the revCount
breaks. If revCount
was ignored in general and removed from the API, we wouldn't need to care much about repos being shallow or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To cover potential bugs like this, I would like to improve the testing infra. I opened an issue where this can be discussed: #9388
}; | ||
|
||
git_fetch_options opts = GIT_FETCH_OPTIONS_INIT; | ||
opts.depth = shallow ? 1 : GIT_FETCH_DEPTH_FULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fetching with depth 1 will fail as soon as the requested rev
is not the latest rev
of the fetched ref
, as any other rev cannot be reached with --depth 1
. Basically as soon as another commit is made on the remote repo this will certainly fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To solve this, instead of fetching $ref:$ref
, simply fetching $rev
with depth=1
is sufficient. But still, the current shallow
behavior of builtins.fetchGit would be broken for which I just clarified the documentation here.
@Ericson2314 @edolstra You might have overlooked it, therefore pinging you. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-11-20-nix-team-meeting-minutes-105/35902/1 |
libgit2 is not capable of using git-credentials helpers yet. This prevents private repositories from being used. Based on code that was replaced in NixOS#9240 (Introduce libgit2); hence: Co-authored-by: Eelco Dolstra <[email protected]>
Motivation
This makes most of
GitInputScheme
uselibgit2
instead of the "git" binary. Extracted from the lazy-trees branch, whereGitInputAccessor
is used to provide direct access to git repos without copying them to the Nix store first.Depends on #9239.
Context
Priorities
Add 👍 to pull requests you find important.