-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Comparing changes
Open a pull request
base repository: git/git
base: 221c3daef41bdd7eebd5f45d711e847d0a85aa86
head repository: git/git
compare: d699d15c328b03fd822d3950f7ed76debef02c26
- 9 commits
- 34 files changed
- 2 contributors
Commits on Feb 19, 2024
-
Merge branch 'ps/reftable-backend' into ps/reflog-list
* ps/reftable-backend: refs/reftable: fix leak when copying reflog fails ci: add jobs to test with the reftable backend refs: introduce reftable backend
Configuration menu - View commit details
-
Copy full SHA for f7cdeaf - Browse repository at this point
Copy the full SHA f7cdeafView commit details
Commits on Feb 21, 2024
-
dir-iterator: pass name to
prepare_next_entry_data()
directlyWhen adding the next directory entry for `struct dir_iterator` we pass the complete `struct dirent *` to `prepare_next_entry_data()` even though we only need the entry's name. Refactor the code to pass in the name, only. This prepares for a subsequent commit where we introduce the ability to iterate through dir entries in an ordered manner. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 0218de2 - Browse repository at this point
Copy the full SHA 0218de2View commit details -
dir-iterator: support iteration in sorted order
The `struct dir_iterator` is a helper that allows us to iterate through directory entries. This iterator returns entries in the exact same order as readdir(3P) does -- or in other words, it guarantees no specific order at all. This is about to become problematic as we are introducing a new reflog subcommand to list reflogs. As the "files" backend uses the directory iterator to enumerate reflogs, returning reflog names and exposing them to the user would inherit the indeterministic ordering. Naturally, it would make for a terrible user interface to show a list with no discernible order. While this could be handled at a higher level by the new subcommand itself by collecting and ordering the reflogs, this would be inefficient because we would first have to collect all reflogs before we can sort them, which would introduce additional latency when there are many reflogs. Instead, introduce a new option into the directory iterator that asks for its entries to be yielded in lexicographical order. If set, the iterator will read all directory entries greedily and sort them before we start to iterate over them. While this will of course also incur overhead as we cannot yield the directory entries immediately, it should at least be more efficient than having to sort the complete list of reflogs as we only need to sort one directory at a time. This functionality will be used in a follow-up commit. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for de34f26 - Browse repository at this point
Copy the full SHA de34f26View commit details -
refs/files: sort reflogs returned by the reflog iterator
We use a directory iterator to return reflogs via the reflog iterator. This iterator returns entries in the same order as readdir(3P) would and will thus yield reflogs with no discernible order. Set the new `DIR_ITERATOR_SORTED` flag that was introduced in the preceding commit so that the order is deterministic. While the effect of this can only been observed in a test tool, a subsequent commit will start to expose this functionality to users via a new `git reflog list` subcommand. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for e69e8ff - Browse repository at this point
Copy the full SHA e69e8ffView commit details -
refs/files: sort merged worktree and common reflogs
When iterating through reflogs in a worktree we create a merged iterator that merges reflogs from both refdbs. The resulting refs are ordered so that instead we first return all worktree reflogs before we return all common refs. This is the only remaining case where a ref iterator returns entries in a non-lexicographic order. The result would look something like the following (listed with a command we introduce in a subsequent commit): ``` $ git reflog list HEAD refs/worktree/per-worktree refs/heads/main refs/heads/wt ``` So we first print the per-worktree reflogs in lexicographic order, then the common reflogs in lexicographic order. This is confusing and not consistent with how we print per-worktree refs, which are exclusively sorted lexicographically. Sort reflogs lexicographically in the same way as we sort normal refs. As this is already implemented properly by the "reftable" backend via a separate selection function, we simply pull out that logic and reuse it for the "files" backend. As logs are properly sorted now, mark the merged reflog iterator as sorted. Tests will be added in a subsequent commit. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 6f22780 - Browse repository at this point
Copy the full SHA 6f22780View commit details -
refs: always treat iterators as ordered
In the preceding commit we have converted the reflog iterator of the "files" backend to be ordered, which was the only remaining ref iterator that wasn't ordered. Refactor the ref iterator infrastructure so that we always assume iterators to be ordered, thus simplifying the code. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 5e01d83 - Browse repository at this point
Copy the full SHA 5e01d83View commit details -
refs: drop unused params from the reflog iterator callback
The ref and reflog iterators share much of the same underlying code to iterate over the corresponding entries. This results in some weird code because the reflog iterator also exposes an object ID as well as a flag to the callback function. Neither of these fields do refer to the reflog though -- they refer to the corresponding ref with the same name. This is quite misleading. In practice at least the object ID cannot really be implemented in any other way as a reflog does not have a specific object ID in the first place. This is further stressed by the fact that none of the callbacks except for our test helper make use of these fields. Split up the infrastucture so that ref and reflog iterators use separate callback signatures. This allows us to drop the nonsensical fields from the reflog iterator. Note that internally, the backends still use the same shared infra to iterate over both types. As the backends should never end up being called directly anyway, this is not much of a problem and thus kept as-is for simplicity's sake. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 31f8983 - Browse repository at this point
Copy the full SHA 31f8983View commit details -
refs: stop resolving ref corresponding to reflogs
The reflog iterator tries to resolve the corresponding ref for every reflog that it is about to yield. Historically, this was done due to multiple reasons: - It ensures that the refname is safe because we end up calling `check_refname_format()`. Also, non-conformant refnames are skipped altogether. - The iterator used to yield the resolved object ID as well as its flags to the callback. This info was never used though, and the corresponding parameters were dropped in the preceding commit. - When a ref is corrupt then the reflog is not emitted at all. We're about to introduce a new `git reflog list` subcommand that will print all reflogs that the refdb knows about. Skipping over reflogs whose refs are corrupted would be quite counterproductive in this case as the user would have no way to learn about reflogs which may still exist in their repository to help and rescue such a corrupted ref. Thus, the only remaining reason for why we'd want to resolve the ref is to verify its refname. Refactor the code to call `check_refname_format()` directly instead of trying to resolve the ref. This is significantly more efficient given that we don't have to hit the object database anymore to list reflogs. And second, it ensures that we end up showing reflogs of broken refs, which will help to make the reflog more useful. Note that this really only impacts the case where the corresponding ref is corrupt. Reflogs for nonexistent refs would have been returned to the caller beforehand already as we did not pass `RESOLVE_REF_READING` to the function, and thus `refs_resolve_ref_unsafe()` would have returned successfully in that case. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 59c50a9 - Browse repository at this point
Copy the full SHA 59c50a9View commit details -
builtin/reflog: introduce subcommand to list reflogs
While the git-reflog(1) command has subcommands to show reflog entries or check for reflog existence, it does not have any subcommands that would allow the user to enumerate all existing reflogs. This makes it quite hard to discover which reflogs a repository has. While this can be worked around with the "files" backend by enumerating files in the ".git/logs" directory, users of the "reftable" backend don't enjoy such a luxury. Introduce a new subcommand `git reflog list` that lists all reflogs the repository knows of to fill this gap. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for d699d15 - Browse repository at this point
Copy the full SHA d699d15View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 221c3daef41bdd7eebd5f45d711e847d0a85aa86...d699d15c328b03fd822d3950f7ed76debef02c26