diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-18 10:25:26 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-18 10:41:12 +0100 |
| commit | 4961e2d4c14e50bfc6685c69681d3f2cc9294360 (patch) | |
| tree | 878c9a0ebf6ec3ca0e3c418f1a91ab5edb7bba18 /src/bin | |
| parent | 28a37393ee62e3b53dad69d58810f72151bd58c2 (diff) | |
feat(sync): add `ref-name` param to limit sync
limit syncing to a single reference with this new parameter.
change instructions for out of sync remotes to use sync with this new
option.
Diffstat (limited to 'src/bin')
| -rw-r--r-- | src/bin/git_remote_nostr/push.rs | 8 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/sync.rs | 43 |
2 files changed, 46 insertions, 5 deletions
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs index 1738790..80aed22 100644 --- a/src/bin/git_remote_nostr/push.rs +++ b/src/bin/git_remote_nostr/push.rs | |||
| @@ -601,7 +601,7 @@ fn create_rejected_refspecs_and_remotes_refspecs( | |||
| 601 | .or_insert(vec![url.to_string()]); | 601 | .or_insert(vec![url.to_string()]); |
| 602 | term.write_line( | 602 | term.write_line( |
| 603 | format!( | 603 | format!( |
| 604 | "ERROR: {short_name} {to} conflicts with nostr ({} ahead {} behind) and local ({} ahead {} behind). either:\r\n 1. pull from that git server and resolve\r\n 2. force push your branch to the git server before pushing to nostr remote", | 604 | "ERROR: {short_name} {to} conflicts with nostr ({} ahead {} behind) and local ({} ahead {} behind). someone else may have pushed new updates. options:\r\n 1. review and integrate remote's tip available via `git checkout {remote_value}` \r\n 2. align remote state with nostr via `ngit sync --ref-name {to} --force` and try to push again", |
| 605 | ahead_of_nostr.len(), | 605 | ahead_of_nostr.len(), |
| 606 | behind_nostr.len(), | 606 | behind_nostr.len(), |
| 607 | ahead_of_local.len(), | 607 | ahead_of_local.len(), |
| @@ -622,7 +622,7 @@ fn create_rejected_refspecs_and_remotes_refspecs( | |||
| 622 | .and_modify(|a| a.push(url.to_string())) | 622 | .and_modify(|a| a.push(url.to_string())) |
| 623 | .or_insert(vec![url.to_string()]); | 623 | .or_insert(vec![url.to_string()]); |
| 624 | term.write_line( | 624 | term.write_line( |
| 625 | format!("ERROR: {short_name} {to} conflicts with nostr and is not an ancestor of local branch. either:\r\n 1. pull from that git server and resolve\r\n 2. force push your branch to the git server before pushing to nostr remote").as_str(), | 625 | format!("ERROR: {short_name} {to} conflicts with nostr and is not an ancestor of local branch. someone else may have pushed new updates. options:\r\n 1. review and integrate remote's tip available via `git checkout {remote_value}` \r\n 2. align remote state with nostr via `ngit sync --ref-name {to} --force` and try to push again").as_str(), |
| 626 | )?; | 626 | )?; |
| 627 | } | 627 | } |
| 628 | } else { | 628 | } else { |
| @@ -655,7 +655,7 @@ fn create_rejected_refspecs_and_remotes_refspecs( | |||
| 655 | .or_insert(vec![url.to_string()]); | 655 | .or_insert(vec![url.to_string()]); |
| 656 | term.write_line( | 656 | term.write_line( |
| 657 | format!( | 657 | format!( |
| 658 | "ERROR: {short_name} already contains {to} {} ahead and {} behind local branch. either:\r\n 1. pull from that git server and resolve\r\n 2. force push your branch to the git server before pushing to nostr remote", | 658 | "ERROR: {short_name} already contains {to} {} ahead and {} behind local branch. someone else may have pushed new updates. options:\r\n 1. review and integrate remote's tip available via `git checkout {remote_value}` \r\n 2. align remote state with nostr via `ngit sync --ref-name {to} --force` and try to push again", |
| 659 | ahead.len(), | 659 | ahead.len(), |
| 660 | behind.len(), | 660 | behind.len(), |
| 661 | ).as_str(), | 661 | ).as_str(), |
| @@ -672,7 +672,7 @@ fn create_rejected_refspecs_and_remotes_refspecs( | |||
| 672 | .and_modify(|a| a.push(url.to_string())) | 672 | .and_modify(|a| a.push(url.to_string())) |
| 673 | .or_insert(vec![url.to_string()]); | 673 | .or_insert(vec![url.to_string()]); |
| 674 | term.write_line( | 674 | term.write_line( |
| 675 | format!("ERROR: {short_name} already contains {to} at {remote_value} which is not an ancestor of local branch. either:\r\n 1. pull from that git server and resolve\r\n 2. force push your branch to the git server before pushing to nostr remote").as_str(), | 675 | format!("ERROR: {short_name} already contains {to} at {remote_value} which is not an ancestor of local branch. someone else may have pushed new updates. options:\r\n 1. review and integrate remote's tip available via `git checkout {remote_value}` \r\n 2. align remote state with nostr via `ngit sync --ref-name {to} --force` and try to push again").as_str(), |
| 676 | )?; | 676 | )?; |
| 677 | } | 677 | } |
| 678 | } else { | 678 | } else { |
diff --git a/src/bin/ngit/sub_commands/sync.rs b/src/bin/ngit/sub_commands/sync.rs index 00dfe75..61c13a8 100644 --- a/src/bin/ngit/sub_commands/sync.rs +++ b/src/bin/ngit/sub_commands/sync.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use anyhow::{Context, Result}; | 1 | use anyhow::{Context, Result, bail}; |
| 2 | use ngit::{ | 2 | use ngit::{ |
| 3 | client::{ | 3 | client::{ |
| 4 | Client, Connect, Params, fetching_with_report, get_repo_ref_from_cache, | 4 | Client, Connect, Params, fetching_with_report, get_repo_ref_from_cache, |
| @@ -13,6 +13,9 @@ use ngit::{ | |||
| 13 | 13 | ||
| 14 | #[derive(Debug, clap::Args)] | 14 | #[derive(Debug, clap::Args)] |
| 15 | pub struct SubCommandArgs { | 15 | pub struct SubCommandArgs { |
| 16 | /// optionally just sync a specific reference. eg main or v1.5.2 | ||
| 17 | #[clap(short, long)] | ||
| 18 | pub(crate) ref_name: Option<String>, | ||
| 16 | /// force push updates and delete refs from non-grasp git servers | 19 | /// force push updates and delete refs from non-grasp git servers |
| 17 | #[arg(long, action)] | 20 | #[arg(long, action)] |
| 18 | force: bool, | 21 | force: bool, |
| @@ -23,6 +26,32 @@ pub async fn launch(args: &SubCommandArgs) -> Result<()> { | |||
| 23 | let git_repo = Repo::discover().context("failed to find a git repository")?; | 26 | let git_repo = Repo::discover().context("failed to find a git repository")?; |
| 24 | let git_repo_path = git_repo.get_path()?; | 27 | let git_repo_path = git_repo.get_path()?; |
| 25 | 28 | ||
| 29 | let full_ref_name = if let Some(ref_name) = &args.ref_name { | ||
| 30 | if ref_name.starts_with("refs/") { | ||
| 31 | if git_repo.git_repo.find_reference(ref_name).is_ok() { | ||
| 32 | Some(ref_name.clone()) | ||
| 33 | } else { | ||
| 34 | bail!("could not find reference {ref_name}"); | ||
| 35 | } | ||
| 36 | } else if git_repo | ||
| 37 | .git_repo | ||
| 38 | .find_reference(&format!("refs/tags/{ref_name}")) | ||
| 39 | .is_ok() | ||
| 40 | { | ||
| 41 | Some(format!("refs/tags/{ref_name}")) | ||
| 42 | } else if git_repo | ||
| 43 | .git_repo | ||
| 44 | .find_reference(&format!("refs/heads/{ref_name}")) | ||
| 45 | .is_ok() | ||
| 46 | { | ||
| 47 | Some(format!("refs/heads/{ref_name}")) | ||
| 48 | } else { | ||
| 49 | bail!("could not find reference {ref_name}"); | ||
| 50 | } | ||
| 51 | } else { | ||
| 52 | None | ||
| 53 | }; | ||
| 54 | |||
| 26 | let client = Client::new(Params::with_git_config_relay_defaults(&Some(&git_repo))); | 55 | let client = Client::new(Params::with_git_config_relay_defaults(&Some(&git_repo))); |
| 27 | 56 | ||
| 28 | let (nostr_remote_name, decoded_nostr_url) = git_repo | 57 | let (nostr_remote_name, decoded_nostr_url) = git_repo |
| @@ -56,6 +85,12 @@ pub async fn launch(args: &SubCommandArgs) -> Result<()> { | |||
| 56 | // delete ref from remote | 85 | // delete ref from remote |
| 57 | let mut not_deleted = vec![]; | 86 | let mut not_deleted = vec![]; |
| 58 | for remote_ref_name in remote_state.keys() { | 87 | for remote_ref_name in remote_state.keys() { |
| 88 | // skip unspecified refs | ||
| 89 | if let Some(full_ref_name) = &full_ref_name { | ||
| 90 | if remote_ref_name != full_ref_name { | ||
| 91 | continue; | ||
| 92 | } | ||
| 93 | } | ||
| 59 | if (!remote_ref_name.starts_with("refs/heads/pr/") | 94 | if (!remote_ref_name.starts_with("refs/heads/pr/") |
| 60 | && (remote_ref_name.starts_with("refs/heads/") | 95 | && (remote_ref_name.starts_with("refs/heads/") |
| 61 | || remote_ref_name.starts_with("refs/tags/"))) | 96 | || remote_ref_name.starts_with("refs/tags/"))) |
| @@ -75,6 +110,12 @@ pub async fn launch(args: &SubCommandArgs) -> Result<()> { | |||
| 75 | // add or update ref on remote | 110 | // add or update ref on remote |
| 76 | let mut not_updated = vec![]; | 111 | let mut not_updated = vec![]; |
| 77 | for nostr_ref_name in nostr_state.state.keys() { | 112 | for nostr_ref_name in nostr_state.state.keys() { |
| 113 | // skip unspecified refs | ||
| 114 | if let Some(full_ref_name) = &full_ref_name { | ||
| 115 | if nostr_ref_name != full_ref_name { | ||
| 116 | continue; | ||
| 117 | } | ||
| 118 | } | ||
| 78 | if nostr_ref_name.starts_with("refs/heads/") | 119 | if nostr_ref_name.starts_with("refs/heads/") |
| 79 | || nostr_ref_name.starts_with("refs/tags/") | 120 | || nostr_ref_name.starts_with("refs/tags/") |
| 80 | || !nostr_ref_name.starts_with("refs/heads/pr/") | 121 | || !nostr_ref_name.starts_with("refs/heads/pr/") |