pocket_cli/vcs/
timeline.rs

1//! Timeline (branch) functionality for Pocket VCS
2//!
3//! Handles the creation and management of timelines (branches).
4
5use std::path::Path;
6use std::fs;
7use serde::{Serialize, Deserialize};
8use anyhow::Result;
9use thiserror::Error;
10
11use crate::vcs::ShoveId;
12
13/// Error types specific to timeline operations
14#[derive(Error, Debug)]
15pub enum TimelineError {
16    #[error("Timeline already exists: {0}")]
17    AlreadyExists(String),
18    
19    #[error("Cannot delete the current timeline")]
20    CannotDeleteCurrent,
21    
22    #[error("Timeline has no head shove")]
23    NoHead,
24}
25
26/// Remote tracking information for a timeline
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct RemoteTracking {
29    pub remote_name: String,
30    pub remote_timeline: String,
31}
32
33/// A timeline (branch) in the repository
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct Timeline {
36    /// Name of the timeline
37    pub name: String,
38    
39    /// Current head shove
40    pub head: Option<ShoveId>,
41    
42    /// Remote tracking information (if any)
43    pub remote: Option<RemoteTracking>,
44}
45
46impl Timeline {
47    /// Create a new timeline
48    pub fn new(name: &str, head: Option<ShoveId>) -> Self {
49        Self {
50            name: name.to_string(),
51            head,
52            remote: None,
53        }
54    }
55    
56    /// Load a timeline from a file
57    pub fn load(path: &Path) -> Result<Self> {
58        let content = fs::read_to_string(path)?;
59        let timeline: Self = toml::from_str(&content)?;
60        Ok(timeline)
61    }
62    
63    /// Save the timeline to a file
64    pub fn save(&self, path: &Path) -> Result<()> {
65        let content = toml::to_string_pretty(self)?;
66        fs::write(path, content)?;
67        Ok(())
68    }
69    
70    /// Update the head of this timeline
71    pub fn update_head(&mut self, shove_id: ShoveId) {
72        self.head = Some(shove_id);
73    }
74    
75    /// Set up remote tracking for this timeline
76    pub fn set_remote_tracking(&mut self, remote_name: &str, remote_timeline: &str) {
77        self.remote = Some(RemoteTracking {
78            remote_name: remote_name.to_string(),
79            remote_timeline: remote_timeline.to_string(),
80        });
81    }
82    
83    // Additional methods would be implemented here:
84    // - merge: Merge another timeline into this one
85    // - is_ancestor: Check if one shove is an ancestor of another
86    // - get_common_ancestor: Find the common ancestor of two shoves
87    // - etc.
88}