-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
RFC: separate object lookup error for promisor packs #5776
Conversation
Checks for the presence of a '<pack>.promisor' sidecar file.
"Missing" means that an object isn't present in the ODB but should be available from a promisor remote or similar. Promisor packfiles may reference objects that aren't present in the packfile but are available remotely. Compare with to GIT_ENOTFOUND which indicates there is no information to suggest the object will ever be available - the repository may be corrupt or a oid lookup is not present.
If an object is referenced from a promisor packfile and the object is not found elsewhere in the ODB, then return EMISSING instead of ENOTFOUND. Promisor packfiles can refer to objects that are not available in the pack but should be available remotely. Contrast with ENOTFOUND to indicate there is no information this object will ever exist.
libgit2/libgit2#5776 Catch and deal with GIT_EMISSING and convert it to ObjectMissingError. This is a subclass of KeyError which is mapped from GIT_ENOTFOUND.
Hi github maintainers, I'm willing to do some work to help improve libgit2's partial clone support. What can I do to help this along? |
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.
Sorry about the delay, @rcoup; I haven't had a lot of bandwidth in 2020. I think that the direction that this is going is largely correct.
The code doesn't actually do (2) properly when there are multiple ODB backends in place, but hopefully it conveys the basic idea.
Is the problem here that we're short circuiting the lookup on the first promisor pack, and a subsequent odb backend may have the object? (In other words, we erroneously report EMISSING
even though we have the object?) Or is there a deeper underlying problem that I'm not seeing yet?
Conceptually, EMISSING could also be used for things like shallow clones where parent commits aren't available locally, etc.
I wonder if that's what we would want to do. I agree that they're similar (object exists on the remote and doesn't exist locally) but I wonder if they should be distinct error codes so that a caller can distinguish them more easily. 🤔
if (!git_disable_pack_keep_file_checks) { | ||
memcpy(p->pack_name + root_len, ".keep", sizeof(".keep")); | ||
if (git_path_exists(p->pack_name) == true) | ||
p->pack_keep = 1; | ||
} | ||
|
||
memcpy(p->pack_name + root_len, ".pack", sizeof(".pack")); | ||
} else { | ||
root_len = path_len - strlen(".pack"); |
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.
In line 1181 we ensure that path_len
is at least strlen(".idx")
. If it were strlen(".idx")
, here we would set root_len
to (size_t)-1
.
I think that it's unlikely that there's a call path that would call us with just .idx
as the path but some sort of guard seems like it should be in order.
Yes. Presumably there might be some other complexities wrt multiple ODB backends.
Yes, maybe |
FYI I picked up this PR and started to address the review comments - however I ran into a major obstacle -
This PR doesn't currently do those things and lacks the context to do so without changing the libgit2 API. I think this PR promotes ENOTFOUND to EPROMISED basically every time if there is a promisor packfile involved, which is too eager (unless we define the error code as meaning "this object might be promised", as opposed to "is promised"). I think this PR is probably best simply closed - there are two other PRs that I will try to write instead:
Limitations - I can only add these codes to the path API eg |
Closed in favour of #5993 and follow-ups |
There's currently no support in libgit2 for partial clones (#5564). This attempts to start support them by distinguishing object-lookup faults between
ENOTFOUND
(the requested oid is bad or the repo is corrupt) from a newEMISSING
error (indicating the oid is referenced from a promisor pack, and therefore should be available remotely)..packfile
sidecar and track it in an attribute ofgit_pack_file
To be clear, there's no support for fetching missing objects from a promisor remote.
The code doesn't actually do (2) properly when there are multiple ODB backends in place, but hopefully it conveys the basic idea.
Conceptually, EMISSING could also be used for things like shallow clones where parent commits aren't available locally, etc.