Skip to main content

lit/commands/
pull.rs

1use crate::commands::{fetch, merge};
2use crate::core::find_repo_root;
3use crate::response::PullResponse;
4
5pub fn execute(remote: String, branch: String) -> Result<PullResponse, crate::errors::LitError> {
6    let repo_root = find_repo_root()?;
7
8    // Step 1: Fetch
9    let fetch_result = fetch::execute(remote.clone(), Some(branch.clone()))?;
10
11    // Step 2: Merge the remote-tracking branch into current
12    let tracking_ref = format!("remotes/{}/{}", remote, branch);
13    let remote_hash = crate::core::refs::read_ref(&repo_root, &tracking_ref)
14        .map_err(|_| format!("No tracking ref for '{}/{}'", remote, branch))?;
15
16    // Check if current branch tip matches — already up to date
17    let _current_branch =
18        crate::core::refs::get_current_branch(&repo_root).unwrap_or_else(|_| "HEAD".to_string());
19    let local_hash = crate::core::refs::read_head(&repo_root).ok();
20
21    if local_hash.as_deref() == Some(&remote_hash) {
22        return Ok(PullResponse {
23            remote: remote.clone(),
24            branch: branch.clone(),
25            objects_fetched: fetch_result.objects_transferred,
26            fast_forward: false,
27            has_conflicts: false,
28            merge_message: "Already up to date".to_string(),
29            message: format!(
30                "From {}\n  Already up to date ({} objects fetched)",
31                remote, fetch_result.objects_transferred
32            ),
33        });
34    }
35
36    // Step 3: Merge
37    // Use the tracking ref name as the merge source
38    let merge_branch = format!("{}/{}", remote, branch);
39    let merge_result = merge::execute(merge_branch, None)?;
40
41    Ok(PullResponse {
42        remote: remote.clone(),
43        branch: branch.clone(),
44        objects_fetched: fetch_result.objects_transferred,
45        fast_forward: merge_result.fast_forward,
46        has_conflicts: merge_result.has_conflicts,
47        merge_message: merge_result.message.clone(),
48        message: format!(
49            "From {}\n  {} objects fetched\n  {}",
50            remote, fetch_result.objects_transferred, merge_result.message
51        ),
52    })
53}