diff --git a/src/default_config.toml b/src/default_config.toml index 2122468203..52f9aa0a9a 100644 --- a/src/default_config.toml +++ b/src/default_config.toml @@ -116,6 +116,7 @@ fetch_menu.--prune = ["-p"] fetch_menu.--tags = ["-t"] fetch_menu.fetch_all = ["a"] fetch_menu.quit = ["q", ""] +fetch_menu.fetch_elsewhere = ["e"] root.log_menu = ["l"] log_menu.log_current = ["l"] @@ -125,6 +126,7 @@ log_menu.quit = ["q", ""] root.pull_menu = ["F"] pull_menu.--rebase = ["-r"] pull_menu.pull = ["p"] +pull_menu.pull_elsewhere = ["e"] pull_menu.quit = ["q", ""] root.push_menu = ["P"] @@ -133,6 +135,7 @@ push_menu.--force = ["-F"] push_menu.--no-verify = ["-h"] push_menu.--dry-run = ["-n"] push_menu.push = ["p"] +push_menu.push_elsewhere = ["e"] push_menu.quit = ["q", ""] root.rebase_menu = ["r"] diff --git a/src/ops/fetch.rs b/src/ops/fetch.rs index 5991356e54..c4ffdfd18e 100644 --- a/src/ops/fetch.rs +++ b/src/ops/fetch.rs @@ -1,7 +1,7 @@ -use super::{Action, OpTrait}; -use crate::{items::TargetData, menu::arg::Arg}; +use super::{create_prompt, Action, OpTrait}; +use crate::{items::TargetData, menu::arg::Arg, state::State, term::Term, Res}; use derive_more::Display; -use std::{process::Command, rc::Rc}; +use std::{ffi::OsString, process::Command, rc::Rc}; pub(crate) const ARGS: &[Arg] = &[ Arg::new("--prune", "Prune deleted branches", false), @@ -23,3 +23,22 @@ impl OpTrait for FetchAll { })) } } + +#[derive(Display)] +#[display(fmt = "Fetch from elsewhere")] +pub(crate) struct FetchElsewhere; +impl OpTrait for FetchElsewhere { + fn get_action(&self, _target: Option<&TargetData>) -> Option { + Some(create_prompt("Select remote", push_elsewhere)) + } +} + +fn push_elsewhere(state: &mut State, term: &mut Term, args: &[OsString], remote: &str) -> Res<()> { + let mut cmd = Command::new("git"); + cmd.args(["fetch"]); + cmd.args(args); + cmd.arg(remote); + + state.run_cmd_async(term, &[], cmd)?; + Ok(()) +} diff --git a/src/ops/mod.rs b/src/ops/mod.rs index 52aeb6db51..a8c585c3e2 100644 --- a/src/ops/mod.rs +++ b/src/ops/mod.rs @@ -52,9 +52,12 @@ pub(crate) enum Op { Commit, CommitAmend, FetchAll, + FetchElsewhere, LogCurrent, Pull, + PullElsewhere, Push, + PushElsewhere, RebaseAbort, RebaseContinue, RebaseElsewhere, @@ -126,9 +129,12 @@ impl Op { Op::Commit => Box::new(commit::Commit), Op::CommitAmend => Box::new(commit::CommitAmend), Op::FetchAll => Box::new(fetch::FetchAll), + Op::FetchElsewhere => Box::new(fetch::FetchElsewhere), Op::LogCurrent => Box::new(log::LogCurrent), Op::Pull => Box::new(pull::Pull), + Op::PullElsewhere => Box::new(pull::PullElsewhere), Op::Push => Box::new(push::Push), + Op::PushElsewhere => Box::new(push::PushElsewhere), Op::RebaseAbort => Box::new(rebase::RebaseAbort), Op::RebaseContinue => Box::new(rebase::RebaseContinue), Op::RebaseElsewhere => Box::new(rebase::RebaseElsewhere), diff --git a/src/ops/pull.rs b/src/ops/pull.rs index 2f6e58267c..16af576404 100644 --- a/src/ops/pull.rs +++ b/src/ops/pull.rs @@ -1,7 +1,7 @@ -use super::{Action, OpTrait}; -use crate::{items::TargetData, menu::arg::Arg, state::State, term::Term}; +use super::{create_prompt, Action, OpTrait}; +use crate::{items::TargetData, menu::arg::Arg, state::State, term::Term, Res}; use derive_more::Display; -use std::{process::Command, rc::Rc}; +use std::{ffi::OsString, process::Command, rc::Rc}; pub(crate) const ARGS: &[Arg] = &[Arg::new("--rebase", "Rebase local commits", false)]; @@ -20,3 +20,22 @@ impl OpTrait for Pull { })) } } + +#[derive(Display)] +#[display(fmt = "Pull from elsewhere")] +pub(crate) struct PullElsewhere; +impl OpTrait for PullElsewhere { + fn get_action(&self, _target: Option<&TargetData>) -> Option { + Some(create_prompt("Select remote", pull_elsewhere)) + } +} + +fn pull_elsewhere(state: &mut State, term: &mut Term, args: &[OsString], remote: &str) -> Res<()> { + let mut cmd = Command::new("git"); + cmd.args(["pull"]); + cmd.args(args); + cmd.arg(remote); + + state.run_cmd_async(term, &[], cmd)?; + Ok(()) +} diff --git a/src/ops/push.rs b/src/ops/push.rs index 23c7b383d5..2eb8172890 100644 --- a/src/ops/push.rs +++ b/src/ops/push.rs @@ -1,7 +1,7 @@ -use super::{Action, OpTrait}; -use crate::{items::TargetData, menu::arg::Arg, state::State, term::Term}; +use super::{create_prompt, Action, OpTrait}; +use crate::{items::TargetData, menu::arg::Arg, state::State, term::Term, Res}; use derive_more::Display; -use std::{process::Command, rc::Rc}; +use std::{ffi::OsString, process::Command, rc::Rc}; pub(crate) const ARGS: &[Arg] = &[ Arg::new("--force-with-lease", "Force with lease", false), @@ -25,3 +25,22 @@ impl OpTrait for Push { })) } } + +#[derive(Display)] +#[display(fmt = "Push elsewhere")] +pub(crate) struct PushElsewhere; +impl OpTrait for PushElsewhere { + fn get_action(&self, _target: Option<&TargetData>) -> Option { + Some(create_prompt("Select remote", push_elsewhere)) + } +} + +fn push_elsewhere(state: &mut State, term: &mut Term, args: &[OsString], remote: &str) -> Res<()> { + let mut cmd = Command::new("git"); + cmd.args(["push"]); + cmd.arg(format!("--repo={}", remote)); + cmd.args(args); + + state.run_cmd_async(term, &[], cmd)?; + Ok(()) +} diff --git a/src/tests/fetch.rs b/src/tests/fetch.rs new file mode 100644 index 0000000000..1a1fed6168 --- /dev/null +++ b/src/tests/fetch.rs @@ -0,0 +1,11 @@ +use super::*; + +#[test] +fn fetch_from_elsewhere_prompt() { + snapshot!(TestContext::setup_clone(), "fe"); +} + +#[test] +fn fetch_from_elsewhere() { + snapshot!(TestContext::setup_clone(), "feorigin"); +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 6c9165a03f..59cd91953c 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -4,7 +4,9 @@ use std::fs; mod helpers; mod discard; mod editor; +mod fetch; mod log; +mod pull; mod push; mod quit; mod rebase; diff --git a/src/tests/pull.rs b/src/tests/pull.rs new file mode 100644 index 0000000000..1a16d7853b --- /dev/null +++ b/src/tests/pull.rs @@ -0,0 +1,11 @@ +use super::*; + +#[test] +fn pull_from_elsewhere_prompt() { + snapshot!(TestContext::setup_clone(), "Fe"); +} + +#[test] +fn pull_from_elsewhere() { + snapshot!(TestContext::setup_clone(), "Feorigin"); +} diff --git a/src/tests/push.rs b/src/tests/push.rs index f8349ef1b5..b70f97ce88 100644 --- a/src/tests/push.rs +++ b/src/tests/push.rs @@ -20,3 +20,13 @@ fn open_push_menu_after_dash_input() { commit(ctx.dir.path(), "new-file", ""); snapshot!(ctx, "-P"); } + +#[test] +fn push_elsewhere_prompt() { + snapshot!(TestContext::setup_clone(), "Pe"); +} + +#[test] +fn push_elsewhere() { + snapshot!(TestContext::setup_clone(), "Peorigin"); +} diff --git a/src/tests/snapshots/gitu__tests__fetch__fetch_from_elsewhere.snap b/src/tests/snapshots/gitu__tests__fetch__fetch_from_elsewhere.snap new file mode 100644 index 0000000000..ce6aebadd1 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__fetch__fetch_from_elsewhere.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/fetch.rs +expression: ctx.redact_buffer() +--- +▌On branch main | +▌Your branch is up to date with 'origin/main'. | + | + Recent commits | + _______ main origin/main add initial-file | + | + | + | + | + | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +$ git fetch origin | +styles_hash: b6d8677bf94d7533 diff --git a/src/tests/snapshots/gitu__tests__fetch__fetch_from_elsewhere_prompt.snap b/src/tests/snapshots/gitu__tests__fetch__fetch_from_elsewhere_prompt.snap new file mode 100644 index 0000000000..a4c3edf920 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__fetch__fetch_from_elsewhere_prompt.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/fetch.rs +expression: ctx.redact_buffer() +--- +▌On branch main | +▌Your branch is up to date with 'origin/main'. | + | + Recent commits | + _______ main origin/main add initial-file | + | + | + | + | + | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +? Select remote: › | +styles_hash: a2a72e20bfcc2997 diff --git a/src/tests/snapshots/gitu__tests__pull__pull_from_elsewhere.snap b/src/tests/snapshots/gitu__tests__pull__pull_from_elsewhere.snap new file mode 100644 index 0000000000..3ed16883c0 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__pull__pull_from_elsewhere.snap @@ -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 | + _______ main origin/main add initial-file | + | + | + | + | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +$ git pull origin | +Already up to date. | +styles_hash: baa329f6340fcc8b diff --git a/src/tests/snapshots/gitu__tests__pull__pull_from_elsewhere_prompt.snap b/src/tests/snapshots/gitu__tests__pull__pull_from_elsewhere_prompt.snap new file mode 100644 index 0000000000..e433e27730 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__pull__pull_from_elsewhere_prompt.snap @@ -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 | + _______ main origin/main add initial-file | + | + | + | + | + | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +? Select remote: › | +styles_hash: a2a72e20bfcc2997 diff --git a/src/tests/snapshots/gitu__tests__push__open_push_menu_after_dash_input.snap b/src/tests/snapshots/gitu__tests__push__open_push_menu_after_dash_input.snap index 48973a9108..1cf2eea899 100644 --- a/src/tests/snapshots/gitu__tests__push__open_push_menu_after_dash_input.snap +++ b/src/tests/snapshots/gitu__tests__push__open_push_menu_after_dash_input.snap @@ -1,5 +1,5 @@ --- -source: src/tests/mod.rs +source: src/tests/push.rs expression: ctx.redact_buffer() --- ▌On branch main | @@ -19,7 +19,7 @@ expression: ctx.redact_buffer() ────────────────────────────────────────────────────────────────────────────────| Push Arguments | p Push -n Dry run (--dry-run) | -q/ Quit/Close -F Force (--force) | - -f Force with lease (--force-with-lease) | +e Push elsewhere -F Force (--force) | +q/ Quit/Close -f Force with lease (--force-with-lease) | -h Disable hooks (--no-verify) | -styles_hash: 4ed1a7fbfeb2affb +styles_hash: 5f1105080c8b8328 diff --git a/src/tests/snapshots/gitu__tests__push__push_elsewhere.snap b/src/tests/snapshots/gitu__tests__push__push_elsewhere.snap new file mode 100644 index 0000000000..440449f442 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__push__push_elsewhere.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/push.rs +expression: ctx.redact_buffer() +--- +▌On branch main | +▌Your branch is up to date with 'origin/main'. | + | + Recent commits | + _______ main origin/main add initial-file | + | + | + | + | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +$ git push --repo=origin | +Everything up-to-date | +styles_hash: 8df49eee15f4c4d3 diff --git a/src/tests/snapshots/gitu__tests__push__push_elsewhere_prompt.snap b/src/tests/snapshots/gitu__tests__push__push_elsewhere_prompt.snap new file mode 100644 index 0000000000..78ec9e8ea9 --- /dev/null +++ b/src/tests/snapshots/gitu__tests__push__push_elsewhere_prompt.snap @@ -0,0 +1,25 @@ +--- +source: src/tests/push.rs +expression: ctx.redact_buffer() +--- +▌On branch main | +▌Your branch is up to date with 'origin/main'. | + | + Recent commits | + _______ main origin/main add initial-file | + | + | + | + | + | + | + | + | + | + | + | + | + | +────────────────────────────────────────────────────────────────────────────────| +? Select remote: › | +styles_hash: a2a72e20bfcc2997