1use crate::safety;
2use crate::{Outpost, OutpostError, OutpostResult, RefName, Reporter, StepKind, UpstreamRef};
3
4pub struct PullOptions;
5
6pub struct PullReport {
7 pub source_updated: bool,
8 pub outpost_updated: bool,
9}
10
11pub fn run(
12 outpost: &Outpost,
13 _opts: PullOptions,
14 reporter: &mut dyn Reporter,
15) -> OutpostResult<PullReport> {
16 let branch = outpost.current_branch().map_err(|err| match err {
17 OutpostError::BranchNotFound { .. } => OutpostError::NoUpstreamTracking {
18 branch: "HEAD".to_owned(),
19 },
20 other => other,
21 })?;
22 let source = outpost.source_repo()?;
23 if !source.branch_exists(&branch)? {
24 return Err(OutpostError::BranchNotFound {
25 branch: branch.as_str().to_owned(),
26 repo: source.work_tree().to_path_buf(),
27 });
28 }
29
30 reporter.step(
31 StepKind::SourceFetch,
32 &format!(
33 "fast-forwarding source {} branch {} from origin/{}",
34 source.work_tree().display(),
35 branch.as_str(),
36 branch.as_str()
37 ),
38 );
39 let source_branch_ref = format!("refs/heads/{}", branch.as_str());
40 let source_before = source
41 .git()
42 .run_capture(["rev-parse", &source_branch_ref])?;
43 source.fast_forward_branch_from_origin(&branch)?;
44 let source_after = source
45 .git()
46 .run_capture(["rev-parse", &source_branch_ref])?;
47
48 let upstream = UpstreamRef {
49 remote: outpost.metadata().remote_name.clone(),
50 merge_ref: RefName::parse(format!("refs/heads/{}", branch.as_str()))?,
51 };
52 safety::check_no_divergence(outpost, &branch, &upstream)?;
53
54 reporter.step(
55 StepKind::OutpostFetch,
56 &format!(
57 "fast-forwarding outpost {} branch {} from {}/{}",
58 outpost.work_tree().display(),
59 branch.as_str(),
60 upstream.remote.as_str(),
61 branch.as_str()
62 ),
63 );
64 let before = outpost.git().run_capture(["rev-parse", "HEAD"])?;
65 outpost.git().run_check([
66 "pull",
67 "--ff-only",
68 upstream.remote.as_str(),
69 branch.as_str(),
70 ])?;
71 let after = outpost.git().run_capture(["rev-parse", "HEAD"])?;
72
73 Ok(PullReport {
74 source_updated: source_before != source_after,
75 outpost_updated: before != after,
76 })
77}