Skip to content

Commit

Permalink
feat: respect pushRemote/upstream when pulling
Browse files Browse the repository at this point in the history
  • Loading branch information
altsem committed Oct 5, 2024
1 parent 3437acd commit 9226eb7
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 25 deletions.
79 changes: 66 additions & 13 deletions src/ops/pull.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use super::{create_prompt, Action, OpTrait};
use crate::{
git::remote::{get_push_remote, get_upstream_shortname},
git::{
self,
remote::{self, get_push_remote, get_upstream_components, get_upstream_shortname},
},
items::TargetData,
menu::arg::Arg,
state::State,
Expand All @@ -15,8 +18,20 @@ pub(crate) fn init_args() -> Vec<Arg> {

pub(crate) struct PullFromPushRemote;
impl OpTrait for PullFromPushRemote {
fn get_action(&self, target: Option<&TargetData>) -> Option<Action> {
todo!("Implement PullFromPushRemote");
fn get_action(&self, _target: Option<&TargetData>) -> Option<Action> {
Some(Rc::new(
|state: &mut State, term: &mut Term| match get_push_remote(&state.repo)? {
None => {
let mut prompt =
create_prompt("Set pushRemote then pull", set_push_remote_and_pull, true);
Rc::get_mut(&mut prompt).unwrap()(state, term)
}
Some(push_remote) => {
let refspec = git::get_head(&state.repo)?;
pull(state, term, &push_remote, Some(&refspec))
}
},
))
}

fn display(&self, state: &State) -> String {
Expand All @@ -28,19 +43,35 @@ impl OpTrait for PullFromPushRemote {
}
}

fn set_push_remote_and_pull(state: &mut State, term: &mut Term, push_remote_name: &str) -> Res<()> {
let repo = state.repo.clone();
let push_remote = repo
.find_remote(push_remote_name)
.map_err(|_| "Invalid pushRemote")?;

remote::set_push_remote(&repo, Some(&push_remote))
.map_err(|_| "Could not set pushRemote config")?;

let refspec = git::get_head(&repo)?;
pull(state, term, push_remote_name, Some(&refspec))
}

pub(crate) struct PullFromUpstream;
impl OpTrait for PullFromUpstream {
fn get_action(&self, _target: Option<&TargetData>) -> Option<Action> {
Some(Rc::new(|state: &mut State, term: &mut Term| {
todo!("Implement PullFromUpstream");
// let mut cmd = Command::new("git");
// cmd.arg("pull");
// cmd.args(state.pending_menu.as_ref().unwrap().args());

// state.close_menu();
// state.run_cmd_async(term, &[], cmd)?;
// Ok(())
}))
Some(Rc::new(
|state: &mut State, term: &mut Term| match get_upstream_components(&state.repo)? {
None => {
let mut prompt =
create_prompt("Set upstream then pull", set_upstream_and_pull, true);
Rc::get_mut(&mut prompt).unwrap()(state, term)
}
Some((remote, branch)) => {
let refspec = format!("refs/heads/{}", branch);
pull(state, term, &remote, Some(&refspec))
}
},
))
}

fn display(&self, state: &State) -> String {
Expand All @@ -52,6 +83,20 @@ impl OpTrait for PullFromUpstream {
}
}

fn set_upstream_and_pull(state: &mut State, term: &mut Term, upstream_name: &str) -> Res<()> {
state
.pending_menu
.as_mut()
.unwrap()
.args
.get_mut("--set-upstream")
.ok_or("Internal error")?
.set("")?;

let refspec = git::get_head(&state.repo)?;
pull(state, term, upstream_name, Some(&refspec))
}

pub(crate) struct PullFromElsewhere;
impl OpTrait for PullFromElsewhere {
fn get_action(&self, _target: Option<&TargetData>) -> Option<Action> {
Expand All @@ -64,11 +109,19 @@ impl OpTrait for PullFromElsewhere {
}

fn pull_elsewhere(state: &mut State, term: &mut Term, remote: &str) -> Res<()> {
pull(state, term, remote, None)
}

fn pull(state: &mut State, term: &mut Term, remote: &str, refspec: Option<&str>) -> Res<()> {
let mut cmd = Command::new("git");
cmd.args(["pull"]);
cmd.args(state.pending_menu.as_ref().unwrap().args());
cmd.arg(remote);

if let Some(refspec) = refspec {
cmd.arg(refspec);
}

state.close_menu();
state.run_cmd_async(term, &[], cmd)?;
Ok(())
Expand Down
9 changes: 1 addition & 8 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ mod pull;
mod push;
mod quit;
mod rebase;
mod remote;
mod reset;
mod stage;
mod stash;
mod unstage;
mod remote;

use helpers::{clone_and_commit, commit, keys, run, TestContext};

Expand Down Expand Up @@ -211,13 +211,6 @@ fn fetch_all() {
snapshot!(ctx, "fa");
}

#[test]
fn pull() {
let ctx = TestContext::setup_clone();
clone_and_commit(&ctx.remote_dir, "remote-file", "hello");
snapshot!(ctx, "Fp");
}

mod show_refs {
use super::*;

Expand Down
37 changes: 37 additions & 0 deletions src/tests/pull.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
use super::*;

#[test]
fn pull_upstream() {
let ctx = TestContext::setup_clone();
clone_and_commit(&ctx.remote_dir, "remote-file", "hello");
snapshot!(ctx, "Fu");
}

#[test]
fn pull_upstream_prompt() {
let ctx = TestContext::setup_init();
snapshot!(ctx, "Fu");
}

#[test]
fn pull_from_elsewhere_prompt() {
snapshot!(TestContext::setup_clone(), "Fe");
Expand All @@ -9,3 +22,27 @@ fn pull_from_elsewhere_prompt() {
fn pull_from_elsewhere() {
snapshot!(TestContext::setup_clone(), "Feorigin<enter>");
}

#[test]
fn pull_push_remote_prompt() {
let ctx = TestContext::setup_clone();
snapshot!(ctx, "Fp");
}

#[test]
fn pull_push_remote() {
let ctx = TestContext::setup_clone();
snapshot!(ctx, "Fporigin<enter>");
}

#[test]
fn pull_set_push_remote_pull_again() {
let ctx = TestContext::setup_clone();
let mut ctx = ctx;
let mut state = ctx.init_state();
state
.update(&mut ctx.term, &keys("Fporigin<enter>"))
.unwrap();
state.update(&mut ctx.term, &keys("Fp")).unwrap();
insta::assert_snapshot!(ctx.redact_buffer());
}
25 changes: 25 additions & 0 deletions src/tests/snapshots/gitu__tests__pull__pull_push_remote.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: src/tests/pull.rs
expression: ctx.redact_buffer()
---
On branch main |
Your branch is up to date with 'origin/main'. |
|
Recent commits |
b66a0bf main origin/main add initial-file |
|
|
|
|
|
|
|
|
|
|
────────────────────────────────────────────────────────────────────────────────|
$ git pull origin refs/heads/main |
From |
* branch main -> FETCH_HEAD |
Already up to date. |
styles_hash: a7f12e4c3c38781e
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: src/tests/pull.rs
expression: ctx.redact_buffer()
---
On branch main |
Your branch is up to date with 'origin/main'. |
|
Recent commits |
b66a0bf main origin/main add initial-file |
|
|
|
|
|
|
|
|
|
|
|
|
|
────────────────────────────────────────────────────────────────────────────────|
? Set pushRemote then pull:|
styles_hash: e0d524e635f78ab7
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
source: src/tests/pull.rs
expression: ctx.redact_buffer()
---
On branch main |
Your branch is up to date with 'origin/main'. |
|
Recent commits |
b66a0bf main origin/main add initial-file |
|
|
|
|
|
|
|
|
|
|
────────────────────────────────────────────────────────────────────────────────|
$ git pull origin refs/heads/main |
From |
* branch main -> FETCH_HEAD |
Already up to date. |
styles_hash: a7f12e4c3c38781e
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: src/tests/mod.rs
source: src/tests/pull.rs
expression: ctx.redact_buffer()
---
On branch main |
Expand All @@ -12,14 +12,14 @@ expression: ctx.redact_buffer()
|
|
|
|
────────────────────────────────────────────────────────────────────────────────|
$ git pull |
$ git pull origin refs/heads/main |
From |
* branch main -> FETCH_HEAD |
b66a0bf..d07f2d3 main -> origin/main |
Updating b66a0bf..d07f2d3 |
Fast-forward |
remote-file | 1 + |
1 file changed, 1 insertion(+) |
create mode 100644 remote-file |
styles_hash: fe1a0f5d15268e04
styles_hash: 5cab1b81bd346c16

0 comments on commit 9226eb7

Please sign in to comment.