Repository navigation
Conversation
Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
ReFS can share file extents through FSCTL_DUPLICATE_EXTENTS_TO_FILE, but callers should not need platform-specific logic. Provide a compatibility primitive that reports unsupported elsewhere, allowing callers to use block cloning as an opportunistic optimization with an ordinary write as fallback. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Linked worktrees can contain many identical large files even though they already share the object database. On filesystems that advertise block refcounting, pass the current worktree to the checkout and clone only regular, unconverted files whose contents hash to the requested blob. Any unsupported operation or clone failure falls back silently to the normal checkout path. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Document the alignment and chunk-size requirements, and restore the exact destination length after cloning the rounded final range. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Explain why the destination is sized both before and after cloning the aligned extent range. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Keep converted and non-regular entries eligible for parallel checkout because they cannot use the block-clone path. Document the helper fallback contract and source-path lifetime. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
compat: add copy-on-write file support Linked worktrees can share the storage backing identical files on file systems that provide copy-on-write copies. Callers should be able to request that optimization without knowing the platform-specific mechanism or treating lack of support as an error. Provide file_copy_on_write() on Windows and a minimal ENOSYS fallback elsewhere. ReFS requires aligned ranges smaller than 4 GiB, so use 4 GiB minus 64 KiB for full ranges and issue one rounded request for the tail, trying the two valid ReFS cluster sizes. These are alternative tail alignments, not 64 KiB-sized chunks. Truncating afterward removes only the alignment padding. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Co-authored-by: dscho <127790+dscho@users.noreply.github.com> Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
compat: add copy-on-write file support Linked worktrees can share the storage backing identical files on file systems that provide copy-on-write copies. Callers should be able to request that optimization without knowing the platform-specific mechanism or treating lack of support as an error. Provide file_copy_on_write() on Windows and a minimal ENOSYS fallback elsewhere. ReFS requires aligned ranges smaller than 4 GiB, so use 4 GiB minus 64 KiB for full ranges and issue one rounded request for the tail, trying the two valid ReFS cluster sizes. These are alternative tail alignments, not 64 KiB-sized chunks. Truncating afterward removes only the alignment padding. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com> Signed-off-by: GitHub <noreply@github.com>
worktree: copy unchanged files on write Creating a linked worktree normally materializes another physical copy of every checked-out file. File systems with copy-on-write support can avoid that cost, but only when an existing working-tree file is known to represent exactly the target index entry. For a non-bare source, refresh and write its index after recording the current wall-clock time. The reset child loads that index and considers non-sparse entries whose object IDs and conversion attributes match. It requires the opened file stat data to match the refreshed index and predate the recorded time, both before and after copying, which retains Git\047s racy-index protection without hashing converted or Git LFS content. Keep the decision in reset and honor worktree.copyOnWrite=false so users can disable the optimization if a platform implementation proves problematic. Unsupported operations and all validation failures retain the normal checkout path. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Expose the primitive through test-tool so tests can establish a runtime prerequisite by performing a real copy-on-write operation. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Exercise the optimization only after a real copy-on-write probe succeeds. Verify Trace2 records successful copies for clean raw and CRLF-converted files, excludes dirty raw and converted files, and honors the configuration opt-out. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Document the copy-on-write optimization and its opt-out. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Avoid refreshing and writing the source index on platforms where the copy-on-write primitive is unavailable. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Document the lifetime of the caller-owned copy source passed through unpack_trees_options. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Keep the configuration opt-out separate from capability and metadata validation so the successful lookup semantics are explicit. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
State explicitly that both the copy source and its index remain caller-owned for the duration of unpacking. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Resolve the source index entry and its conversion attributes once before deciding whether checkout can run in parallel, then carry that entry into the synchronous copy-on-write path. Signed-off-by: GitHub <noreply@github.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: dscho <127790+dscho@users.noreply.github.com>
Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…source of cloning properly Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…t expected to be cloned even it those files are clean, that is more conservative approach. Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…with zeros Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…ailed clone attempt on NTFS Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…ot needed because proper file size was set on file creation. Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
… often use case Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…kipped if worktree is created in empty folder Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
…segment is not cloned because cloning not aligned segment is slow, it is rather copied from source. Fixed and optimized check for source-clone for git repositories with autocrlf=false where cloning was not executed at all (facebook/react, microsoft/vscode, kubernetes/kubernetes). Signed-off-by: Tomas Kubes <kubes.tomas@gmail.com>
|
Thank you for working on this. In the current form, this PR is massive and not in a mergeable state, unfortunately. The commit history is in no way as clear and as succinct as we try to make it in the Git project. Git for Windows tries to follow the same rules as the Git project so that everything is upstreamable. In the Git project, it is expected that a patch series tells a story, a very clear story, that the commit messages contain the context, the intent, the justification, and include explanations of the implementation as long as they are not also already clear from the diff. Further, the code is supposed to be DRY. 28 commits and 18 changed files do not speak that language to me. They tell me that a lot was added, and probably a lot of that is actually not even necessary to implement what we want to implement here. Also, I fear that a lot of the aspects here are left unclear, starting with the PR title. In Git nomenclature, "cloning" has a very specific meaning. That means that every reader who is familiar with Git must be confused as to what you mean by block cloning. The term "block cloning" only makes sense for those who are familiar with ReFS, which is not the case for Git contributors who are, in large parts, Microsoft haters and would not touch it with a long pole. Coming along with terminology they are prone to dislike immediately isn't going to fly. Since the changes are so massive, it is hard to come up with an exhaustive list of issues to fix. To name just two, after having a glimpse at the overall diff (because, as I said, the patch-for-patch story is totally unreviewable): You said you built on #6424, and that's good, I just wanted it to be taken in a very different direction, focusing on surgical, precise fixes, re-structuring not only the commits into a clear and compelling story, but first and foremost the logic. Copilot did a really bad job at designing the structure of those code changes, so I wasn't even sure that I would start with the code as-is, but probably rather start from scratch, with a sound abstraction that stands a chance of surviving contact with the Git mailing list, and only pilfering the Win32-specific logic from the existing PR. This is not a light undertaking, if we want to have a prayer at ending up with a PR that can be upstreamed with at most cosmetical fixes, we have to be very careful to be mindful of Git's conventions and expectations from the start. |
Hi there,
I spent some time with testing, fixing and optimizing ReFS support for git work tree implementation originally created with copilot and now I came to the point in which it works quite good.
Correctness was tested on artificial and real git repositories.
Overall the cloning is slower for small files, so I chosen threshold of files > 160KiB for which cloning happen on ReFS.
The last unaligned segment is not cloned, but rather copied due to performance.
I was comparing runs on two VHDX disk one with ReFS and second with NTFS on my laptop Acer Nitro V16. It is faster in almost all testing cases compare to original implementation with either NTFS or ReFS and in the same time it brings space savings around 30%, space saving was counted from occupied blocks on disk.
In common repositories threshold of 160Kb clone very small amount of files (in count), but good portion of size of repository. Lower threshold would mean slightly slower creating of work tree, but much bigger space saving.
Git-ReFS-Correctness-Report.pdf