OXYGENHUB

A commit's own snapshot records no operation (refs #41) cd4eb55e3b3d

snapshot_as(for_commit) neither stores the working-copy change it builds
nor records an operation for it: the commit's operation, recorded right
after, replaces the working copy, so the snapshot's cost a durable write
for nothing. A commit that fails leaves the files on disk for the next
snapshot. Old and new builds alternating on the Linux tree, six direct
commits each: median 0.61 s before, 0.58 s after.
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-10-01 22:56 UTC
Signature
✔ signed by Andy McCall
Hash
cd4eb55e3b3d5201e29f6e6a59a5839b4d184864adcfbd988cb5401e1d25a03f
Depends on
17f94b13ae54 1d360c91a289 8f10a07a1dbe 982864068a59 992467d31d26 b30a880fa409 cc7a00565161 f9466021286a
Depended on by
5b4c51307b14 33472ccc08cc
In bookmarks
agents-in-readme bare-hashes carried-not-removed carry-identical doctor-trust identical-sides keyless-tags main merge-remote-bookmark only-help-103 paths-for-resolutions-and-amend push-notes show-stat subrepo-pin-state switch-says
In tags
v0.10.0 v0.11.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.4.3 v0.4.4 v0.4.5 v0.4.6 v0.5.0 v0.5.1 v0.6.0 v0.7.0 v0.8.0 v0.9.0
Edits
8 atoms, 0 tree operations, 2 files

Browse the tree at this change

modified crates/oxy-core/src/repo/snapshot.rs +14 −8
…
379 unchanged lines
380 380
        self.snapshot_as(command, true, false)
381 381
    }
382 382
383 -
    /// `snapshot_as`; `force_manifest` writes the manifest even where a
384 -
    /// status would not bother (an edited file is read next time whatever
385 -
    /// it says), for a commit, after which that file is unchanged.
383 +
    /// `snapshot_as`; `for_commit` writes the manifest even where a status
384 +
    /// would not bother (an edited file is read next time whatever it
385 +
    /// says), since after the commit that file is unchanged, and records no
386 +
    /// operation: the commit's own, recorded straight after, replaces the
387 +
    /// working copy, so the snapshot's would cost a durable write for
388 +
    /// nothing. Should the commit fail, the files are still on disk and the
389 +
    /// next snapshot finds them.
386 390
    fn snapshot_as(
387 391
        &self,
388 392
        command: &str,
389 393
        partial: bool,
390 -
        force_manifest: bool,
394 +
        for_commit: bool,
391 395
    ) -> Result<SnapshotResult> {
392 396
        let _lock = self.lock_snapshot()?;
393 397
        let batch = self.store.begin_batch()?;
394 -
        let result = self.snapshot_locked(command, partial, force_manifest);
398 +
        let result = self.snapshot_locked(command, partial, for_commit);
395 399
        batch.finish()?;
396 400
        result
397 401
    }
…
2 unchanged lines
400 404
        &self,
401 405
        command: &str,
402 406
        partial: bool,
403 -
        force_manifest: bool,
407 +
        for_commit: bool,
404 408
    ) -> Result<SnapshotResult> {
405 409
        let _all = crate::timing::phase("snapshot");
406 410
        let (op_ref, op) = self.head_op()?;
…
168 unchanged lines
575 579
        let encoded = wc.encode_streaming(|batch| self.store.put_texts(&batch))?;
576 580
        let new_hash = crate::hash::hash_object(crate::hash::ObjectType::Change, &encoded);
577 581
        let changed = new_hash != old_hash;
578 -
        if changed {
582 +
        // For a commit the change is neither stored nor recorded: the commit
583 +
        // stores its own, built from this one's operations.
584 +
        if changed && !for_commit {
579 585
            self.store.put(crate::hash::ObjectType::Change, &encoded)?;
580 586
            let mut view = op.view.clone();
581 587
            view.workspaces.insert(self.workspace, new_hash);
…
9 unchanged lines
591 597
        // (it need not be read again), a new blob, a path added or gone.
592 598
        // An edited file is read next time whatever it says.
593 599
        let worth = match self.read_manifest()? {
594 -
            _ if force_manifest => true,
600 +
            _ if for_commit => true,
595 601
            None => true,
596 602
            Some((c, u, m)) => {
597 603
                c != conflicted
…
2273 unchanged lines
modified docs/benchmarks.md +6 −0
…
826 unchanged lines
827 827
commits after a status each: median 0.39 s before, 0.34 s after (Git
828 828
0.14 to 0.16 s).
829 829
830 +
A commit's own snapshot (straight after an edit) no longer stores its
831 +
working-copy change or records an operation for it: the commit's
832 +
operation, recorded straight after, replaces the working copy. Old and
833 +
new builds alternating, six direct commits each (load average 4.4): median
834 +
0.61 s before, 0.58 s after (Git 0.16 to 0.27 s at that load).
835 +