Skip to content

Implement automatic reflog pruning (90-day expiry) #19

@UtsavBalar1231

Description

@UtsavBalar1231

Problem

Reflog grows indefinitely with no automatic pruning mechanism. Over time, reflog files become large and contain ancient history that's no longer useful.

Location

  • src/reflog.rs - Reflog implementation
  • No expiry logic exists

Impact

  • Reflog files grow unbounded
  • Wasted disk space
  • Slower reflog operations as file grows
  • Ancient entries rarely useful for recovery

Approach

1. Add Expiry Configuration:

pub struct Config {
    /// How long to keep reflog entries (days)
    pub reflog_expire_days: u32,  // Default: 90
    
    /// Automatically prune on operations
    pub reflog_auto_prune: bool,  // Default: true
}

2. Implement Pruning Logic:

pub fn prune_reflog(path: &Path, days: u32) -> Result<usize> {
    let cutoff = SystemTime::now() - Duration::from_secs(days as u64 * 86400);
    
    let entries = load_reflog(path)?;
    let keep: Vec<_> = entries.into_iter()
        .filter(|e| e.timestamp > cutoff)
        .collect();
    
    let pruned = entries.len() - keep.len();
    save_reflog(path, &keep)?;
    Ok(pruned)
}

3. Trigger Points:

  • Automatic: After each operation (if auto_prune enabled)
  • Manual: dot reflog expire command
  • Scheduled: Via cron or systemd timer (user's choice)

4. Pruning Strategy:

  • Keep recent entries (last 90 days by default)
  • Keep entries referenced by branches/tags (never prune)
  • Option to keep more entries for specific refs

5. Safety:

  • Never prune entries still reachable from refs
  • Warn before pruning manually
  • Option for dry-run: dot reflog expire --dry-run

Git's Approach

Git has complex expiry rules:

  • gc.reflogExpire: default 90 days
  • gc.reflogExpireUnreachable: default 30 days
  • Different expiry for reachable vs. unreachable commits

We can start simpler and add complexity if needed.

Commands to Add

# Prune expired entries
dot reflog expire

# Prune with custom expiry
dot reflog expire --expire-days=30

# Preview what would be pruned
dot reflog expire --dry-run

# Delete all reflog entries (dangerous)
dot reflog delete --all

Test Cases

  • Entries older than threshold are pruned
  • Recent entries are kept
  • Entries referenced by branches are kept
  • Manual expiry works
  • Dry-run shows correct preview

Related

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or requestpriority: lowLow priority - nice to have

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions