Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d4b07d2
feat(maintenance): add maintenance command with run/register/unregist…
Jun 3, 2026
a99d087
test(maintenance): add 26 integration tests and 12 unit tests
Jun 3, 2026
6d944c8
docs(maintenance): add command docs, changelog, and readme update
Jun 3, 2026
7a7c8af
fix(compat): register maintenance in help_examples_banner visible com…
Jun 3, 2026
0acd5e0
fix(maintenance): ensure pack files are discoverable and readable aft…
Jun 17, 2026
6a24989
feat(maintenance): fix six implementation bugs from debug111
Jun 18, 2026
8c9e157
feat(maintenance): harden pack-refs, gc reachability and incremental-…
Jun 18, 2026
ec830b3
fix(maintenance): address GC, pack-refs, and index robustness issues
Jun 18, 2026
d253e3d
fix(maintenance): abort GC on index/read errors, guard ref deletion, …
Jun 18, 2026
458465c
fix(maintenance): preserve file-backed stash roots, skip ref locks, s…
Jun 18, 2026
efa5a80
fix(maintenance): keep old packs readable during repack, stream loose…
Jun 18, 2026
3b3659f
fix(maintenance): preserve packed-refs and file-backed refs as GC roots
Jun 18, 2026
dd109fd
fix(maintenance): harden GC ref collection, pack temp dirs, and packe…
Jun 18, 2026
0c3d8ef
fix(maintenance): harden packed-refs install, stash reflog, and GC ro…
Jun 18, 2026
87eb5b3
fix(maintenance): preserve loose refs after pack-refs, remove dead gc…
Jun 18, 2026
4664cf4
fix(maintenance): drop object_index rows for pruned loose objects dur…
Jun 18, 2026
c9341c8
fix(maintenance): root all index stages in GC, report prefetch unsupp…
Jun 18, 2026
5eb77a4
fix(maintenance): use v2 index for packs, keep prefetch non-fatal, pa…
Jun 18, 2026
9ea9494
Merge branch 'main' into original-fixes
huimouG Jun 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,6 @@ The following Git top-level commands are currently **not implemented** in Libra

- `gc` – garbage-collect unreachable objects and pack files
- `prune` – remove loose objects that are no longer reachable
- ~~`maintenance`~~ – ✅ `libra maintenance` (run, register, unregister, status)
- `pack-objects` / `unpack-objects` – pack and unpack object collections
- `remote-show` – show detailed remote info
- `fetch-pack` / `push-pack` – low-level fetch/push operations
Expand Down
6 changes: 6 additions & 0 deletions src/command/maintenance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ const MAINTENANCE_LAST_RUN_KEY: &str = "maintenance.last-run";
const DEFAULT_LOOSE_OBJECT_THRESHOLD: usize = 100;
const DEFAULT_PACK_COUNT_THRESHOLD: usize = 5;
const LOOSE_OBJECT_AGE_SECONDS: u64 = 14 * 24 * 60 * 60; // 2 weeks
/// Grace period before an unreachable loose object may be deleted by `gc`.
///
/// This protects concurrent commands (add/commit/fetch/hash-object) that have
/// just written objects but not yet updated refs/reflogs/index. Objects newer
/// than this grace period are left in place even when unreachable.
const GC_PRUNE_GRACE_SECONDS: u64 = 60 * 60; // 1 hour

/// `--help` examples shown in `libra maintenance --help` output.
pub const MAINTENANCE_EXAMPLES: &str = "\
Expand Down
6 changes: 5 additions & 1 deletion src/command/stash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,11 @@ async fn run_push(options: StashPushOptions) -> Result<StashOutput, StashError>

let index_tree =
tree::create_tree_from_index(&index).map_err(|e| StashError::WriteObject(e.to_string()))?;
let index_tree_hash = index_tree.id;
let index_tree_data = index_tree
.to_data()
.map_err(|e| StashError::WriteObject(e.to_string()))?;
let index_tree_hash = object::write_git_object(&git_dir, "tree", &index_tree_data)
.map_err(|e| StashError::WriteObject(e.to_string()))?;

let (author, committer) = util::create_signatures().await;
let (current_branch_name, head_commit_summary) = match Head::current().await {
Expand Down