diff options
Diffstat (limited to 'src/bin/ngit/sub_commands/list.rs')
| -rw-r--r-- | src/bin/ngit/sub_commands/list.rs | 158 |
1 files changed, 44 insertions, 114 deletions
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs index 133ac83..3d5e876 100644 --- a/src/bin/ngit/sub_commands/list.rs +++ b/src/bin/ngit/sub_commands/list.rs | |||
| @@ -35,7 +35,7 @@ use crate::{ | |||
| 35 | git::{Repo, RepoActions, str_to_sha1}, | 35 | git::{Repo, RepoActions, str_to_sha1}, |
| 36 | git_events::{ | 36 | git_events::{ |
| 37 | commit_msg_from_patch_oneliner, event_is_revision_root, event_to_cover_letter, | 37 | commit_msg_from_patch_oneliner, event_is_revision_root, event_to_cover_letter, |
| 38 | get_parent_commit_from_patch, patch_supports_commit_ids, | 38 | get_parent_commit_from_patch, |
| 39 | }, | 39 | }, |
| 40 | repo_ref::get_repo_coordinates_when_remote_unknown, | 40 | repo_ref::get_repo_coordinates_when_remote_unknown, |
| 41 | }; | 41 | }; |
| @@ -623,72 +623,6 @@ async fn launch_interactive() -> Result<()> { | |||
| 623 | } | 623 | } |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | let binding_patch_text_ref = format!( | ||
| 627 | "{} commits", | ||
| 628 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len() | ||
| 629 | ); | ||
| 630 | let patch_text_ref = if most_recent_proposal_patch_chain_or_pr_or_pr_update | ||
| 631 | .len() | ||
| 632 | .gt(&1) | ||
| 633 | { | ||
| 634 | binding_patch_text_ref.as_str() | ||
| 635 | } else { | ||
| 636 | "1 commit" | ||
| 637 | }; | ||
| 638 | |||
| 639 | let no_support_for_patches_as_branch = most_recent_proposal_patch_chain_or_pr_or_pr_update | ||
| 640 | .iter() | ||
| 641 | .any(|event| !patch_supports_commit_ids(event)); | ||
| 642 | |||
| 643 | if no_support_for_patches_as_branch { | ||
| 644 | println!("{patch_text_ref}"); | ||
| 645 | return match Interactor::default().choice( | ||
| 646 | PromptChoiceParms::default() | ||
| 647 | .with_default(0) | ||
| 648 | .with_choices(vec![ | ||
| 649 | "learn why this proposals can't be checked out".to_string(), | ||
| 650 | format!("apply to current branch with `git am`"), | ||
| 651 | format!("download to ./patches"), | ||
| 652 | "back".to_string(), | ||
| 653 | ]), | ||
| 654 | )? { | ||
| 655 | 0 => { | ||
| 656 | println!( | ||
| 657 | "Some proposals are posted as patch without listing a parent commit\n" | ||
| 658 | ); | ||
| 659 | println!( | ||
| 660 | "they are not anchored against a particular state of the code base like a standard patch or a pull request can be\n" | ||
| 661 | ); | ||
| 662 | println!( | ||
| 663 | "they are designed to reviewed by studying the diff (in a tool like gitworkshop.dev) and if acceptable by a maintainer, applied to the latest version of master with any conflicts resolved as the do so\n" | ||
| 664 | ); | ||
| 665 | println!( | ||
| 666 | "this has proven to be a smoother workflow for large scale projects with a high frequency of changes, even when patches are exchanged via email\n" | ||
| 667 | ); | ||
| 668 | println!( | ||
| 669 | "by default ngit posts proposals with a parent commit so either workflow can be used" | ||
| 670 | ); | ||
| 671 | Interactor::default().choice( | ||
| 672 | PromptChoiceParms::default() | ||
| 673 | .with_default(0) | ||
| 674 | .with_choices(vec!["back".to_string()]), | ||
| 675 | )?; | ||
| 676 | continue; | ||
| 677 | } | ||
| 678 | 1 => { | ||
| 679 | launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update) | ||
| 680 | } | ||
| 681 | 2 => save_patches_to_dir( | ||
| 682 | most_recent_proposal_patch_chain_or_pr_or_pr_update, | ||
| 683 | &git_repo, | ||
| 684 | ), | ||
| 685 | 3 => continue, | ||
| 686 | _ => { | ||
| 687 | bail!("unexpected choice") | ||
| 688 | } | ||
| 689 | }; | ||
| 690 | } | ||
| 691 | |||
| 692 | let branch_exists = git_repo | 626 | let branch_exists = git_repo |
| 693 | .get_local_branch_names() | 627 | .get_local_branch_names() |
| 694 | .context("gitlib2 will not show a list of local branch names")? | 628 | .context("gitlib2 will not show a list of local branch names")? |
| @@ -705,35 +639,36 @@ async fn launch_interactive() -> Result<()> { | |||
| 705 | 639 | ||
| 706 | let last_patch = most_recent_proposal_patch_chain_or_pr_or_pr_update | 640 | let last_patch = most_recent_proposal_patch_chain_or_pr_or_pr_update |
| 707 | .last() | 641 | .last() |
| 708 | .context( | 642 | .context("there should be at least one patch as we have already checked for this")?; |
| 709 | "there should be at least one patch as we have already checked for this", | ||
| 710 | )?; | ||
| 711 | 643 | ||
| 712 | let proposal_base_commit = str_to_sha1(&get_parent_commit_from_patch(last_patch, Some(&git_repo))?) | 644 | let proposal_base_commit = get_parent_commit_from_patch(last_patch, Some(&git_repo)) |
| 713 | .context("failed to get valid parent commit id from patch")?; | 645 | .ok() |
| 646 | .and_then(|s| str_to_sha1(&s).ok()); | ||
| 714 | 647 | ||
| 715 | let (main_branch_name, master_tip) = git_repo.get_main_or_master_branch()?; | 648 | let (main_branch_name, master_tip) = git_repo.get_main_or_master_branch()?; |
| 716 | 649 | ||
| 717 | if !git_repo.does_commit_exist(&proposal_base_commit.to_string())? { | 650 | if let Some(ref base_commit) = proposal_base_commit { |
| 718 | println!("your '{main_branch_name}' branch may not be up-to-date."); | 651 | if !git_repo.does_commit_exist(&base_commit.to_string())? { |
| 719 | println!("the proposal parent commit doesnt exist in your local repository."); | 652 | println!("your '{main_branch_name}' branch may not be up-to-date."); |
| 720 | return match Interactor::default().choice(PromptChoiceParms::default().with_default(0).with_choices( | 653 | println!("the proposal parent commit doesnt exist in your local repository."); |
| 721 | vec![ | 654 | return match Interactor::default().choice(PromptChoiceParms::default().with_default(0).with_choices( |
| 722 | format!( | 655 | vec![ |
| 723 | "manually run `git pull` on '{main_branch_name}' and select proposal again" | 656 | format!( |
| 724 | ), | 657 | "manually run `git pull` on '{main_branch_name}' and select proposal again" |
| 725 | format!("apply to current branch with `git am`"), | 658 | ), |
| 726 | format!("download to ./patches"), | 659 | format!("apply to current branch with `git am`"), |
| 727 | "back".to_string(), | 660 | format!("download to ./patches"), |
| 728 | ], | 661 | "back".to_string(), |
| 729 | ))? { | 662 | ], |
| 730 | 0 | 3 => continue, | 663 | ))? { |
| 731 | 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update), | 664 | 0 | 3 => continue, |
| 732 | 2 => save_patches_to_dir(most_recent_proposal_patch_chain_or_pr_or_pr_update, &git_repo), | 665 | 1 => launch_git_am_with_patches(most_recent_proposal_patch_chain_or_pr_or_pr_update), |
| 733 | _ => { | 666 | 2 => save_patches_to_dir(most_recent_proposal_patch_chain_or_pr_or_pr_update, &git_repo), |
| 734 | bail!("unexpected choice") | 667 | _ => { |
| 735 | } | 668 | bail!("unexpected choice") |
| 736 | }; | 669 | } |
| 670 | }; | ||
| 671 | } | ||
| 737 | } | 672 | } |
| 738 | 673 | ||
| 739 | let proposal_tip = str_to_sha1( | 674 | let proposal_tip = str_to_sha1( |
| @@ -748,8 +683,14 @@ async fn launch_interactive() -> Result<()> { | |||
| 748 | ) | 683 | ) |
| 749 | .context("failed to get valid commit_id from patch")?; | 684 | .context("failed to get valid commit_id from patch")?; |
| 750 | 685 | ||
| 751 | let (_, proposal_behind_main) = | 686 | let proposal_behind_main_len = if let Some(ref base_commit) = proposal_base_commit { |
| 752 | git_repo.get_commits_ahead_behind(&master_tip, &proposal_base_commit)?; | 687 | git_repo |
| 688 | .get_commits_ahead_behind(&master_tip, base_commit) | ||
| 689 | .map(|(_, behind)| behind.len()) | ||
| 690 | .unwrap_or(0) | ||
| 691 | } else { | ||
| 692 | 0 | ||
| 693 | }; | ||
| 753 | 694 | ||
| 754 | // branch doesnt exist | 695 | // branch doesnt exist |
| 755 | if !branch_exists { | 696 | if !branch_exists { |
| @@ -758,7 +699,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 758 | format!( | 699 | format!( |
| 759 | "create and checkout proposal branch ({} ahead {} behind '{main_branch_name}')", | 700 | "create and checkout proposal branch ({} ahead {} behind '{main_branch_name}')", |
| 760 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), | 701 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), |
| 761 | proposal_behind_main.len(), | 702 | proposal_behind_main_len, |
| 762 | ), | 703 | ), |
| 763 | format!("apply to current branch with `git am`"), | 704 | format!("apply to current branch with `git am`"), |
| 764 | format!("download to ./patches"), | 705 | format!("download to ./patches"), |
| @@ -815,7 +756,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 815 | format!( | 756 | format!( |
| 816 | "checkout proposal branch ({} ahead {} behind '{main_branch_name}')", | 757 | "checkout proposal branch ({} ahead {} behind '{main_branch_name}')", |
| 817 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), | 758 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), |
| 818 | proposal_behind_main.len(), | 759 | proposal_behind_main_len, |
| 819 | ), | 760 | ), |
| 820 | format!("apply to current branch with `git am`"), | 761 | format!("apply to current branch with `git am`"), |
| 821 | format!("download to ./patches"), | 762 | format!("download to ./patches"), |
| @@ -913,7 +854,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 913 | println!( | 854 | println!( |
| 914 | "updated proposal available ({} ahead {} behind '{main_branch_name}'). existing version is {} ahead {} behind '{main_branch_name}'", | 855 | "updated proposal available ({} ahead {} behind '{main_branch_name}'). existing version is {} ahead {} behind '{main_branch_name}'", |
| 915 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), | 856 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), |
| 916 | proposal_behind_main.len(), | 857 | proposal_behind_main_len, |
| 917 | local_ahead_of_main.len(), | 858 | local_ahead_of_main.len(), |
| 918 | local_beind_main.len(), | 859 | local_beind_main.len(), |
| 919 | ); | 860 | ); |
| @@ -930,13 +871,6 @@ async fn launch_interactive() -> Result<()> { | |||
| 930 | )? { | 871 | )? { |
| 931 | 0 => { | 872 | 0 => { |
| 932 | check_clean(&git_repo)?; | 873 | check_clean(&git_repo)?; |
| 933 | git_repo.create_branch_at_commit( | ||
| 934 | &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, | ||
| 935 | &proposal_base_commit.to_string(), | ||
| 936 | )?; | ||
| 937 | git_repo.checkout( | ||
| 938 | &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, | ||
| 939 | )?; | ||
| 940 | let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len(); | 874 | let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len(); |
| 941 | let _ = git_repo | 875 | let _ = git_repo |
| 942 | .apply_patch_chain( | 876 | .apply_patch_chain( |
| @@ -947,7 +881,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 947 | println!( | 881 | println!( |
| 948 | "checked out new version of proposal ({} ahead {} behind '{main_branch_name}'), replacing old version ({} ahead {} behind '{main_branch_name}')", | 882 | "checked out new version of proposal ({} ahead {} behind '{main_branch_name}'), replacing old version ({} ahead {} behind '{main_branch_name}')", |
| 949 | chain_length, | 883 | chain_length, |
| 950 | proposal_behind_main.len(), | 884 | proposal_behind_main_len, |
| 951 | local_ahead_of_main.len(), | 885 | local_ahead_of_main.len(), |
| 952 | local_beind_main.len(), | 886 | local_beind_main.len(), |
| 953 | ); | 887 | ); |
| @@ -991,7 +925,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 991 | "local proposal branch exists with {} unpublished commits on top of the most up-to-date version of the proposal ({} ahead {} behind '{main_branch_name}')", | 925 | "local proposal branch exists with {} unpublished commits on top of the most up-to-date version of the proposal ({} ahead {} behind '{main_branch_name}')", |
| 992 | local_ahead_of_proposal.len(), | 926 | local_ahead_of_proposal.len(), |
| 993 | local_ahead_of_main.len(), | 927 | local_ahead_of_main.len(), |
| 994 | proposal_behind_main.len(), | 928 | proposal_behind_main_len, |
| 995 | ); | 929 | ); |
| 996 | return match Interactor::default().choice( | 930 | return match Interactor::default().choice( |
| 997 | PromptChoiceParms::default() | 931 | PromptChoiceParms::default() |
| @@ -1012,7 +946,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 1012 | "checked out proposal branch with {} unpublished commits ({} ahead {} behind '{main_branch_name}')", | 946 | "checked out proposal branch with {} unpublished commits ({} ahead {} behind '{main_branch_name}')", |
| 1013 | local_ahead_of_proposal.len(), | 947 | local_ahead_of_proposal.len(), |
| 1014 | local_ahead_of_main.len(), | 948 | local_ahead_of_main.len(), |
| 1015 | proposal_behind_main.len(), | 949 | proposal_behind_main_len, |
| 1016 | ); | 950 | ); |
| 1017 | Ok(()) | 951 | Ok(()) |
| 1018 | } | 952 | } |
| @@ -1032,7 +966,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 1032 | println!( | 966 | println!( |
| 1033 | "you have previously applied the latest version of the proposal ({} ahead {} behind '{main_branch_name}') but your local proposal branch has amended or rebased it ({} ahead {} behind '{main_branch_name}')", | 967 | "you have previously applied the latest version of the proposal ({} ahead {} behind '{main_branch_name}') but your local proposal branch has amended or rebased it ({} ahead {} behind '{main_branch_name}')", |
| 1034 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), | 968 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), |
| 1035 | proposal_behind_main.len(), | 969 | proposal_behind_main_len, |
| 1036 | local_ahead_of_main.len(), | 970 | local_ahead_of_main.len(), |
| 1037 | local_beind_main.len(), | 971 | local_beind_main.len(), |
| 1038 | ); | 972 | ); |
| @@ -1045,7 +979,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 1045 | local_ahead_of_main.len(), | 979 | local_ahead_of_main.len(), |
| 1046 | local_beind_main.len(), | 980 | local_beind_main.len(), |
| 1047 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), | 981 | most_recent_proposal_patch_chain_or_pr_or_pr_update.len(), |
| 1048 | proposal_behind_main.len(), | 982 | proposal_behind_main_len, |
| 1049 | ); | 983 | ); |
| 1050 | 984 | ||
| 1051 | println!( | 985 | println!( |
| @@ -1085,10 +1019,6 @@ async fn launch_interactive() -> Result<()> { | |||
| 1085 | } | 1019 | } |
| 1086 | 1 => { | 1020 | 1 => { |
| 1087 | check_clean(&git_repo)?; | 1021 | check_clean(&git_repo)?; |
| 1088 | git_repo.create_branch_at_commit( | ||
| 1089 | &cover_letter.get_branch_name_with_pr_prefix_and_shorthand_id()?, | ||
| 1090 | &proposal_base_commit.to_string(), | ||
| 1091 | )?; | ||
| 1092 | let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len(); | 1022 | let chain_length = most_recent_proposal_patch_chain_or_pr_or_pr_update.len(); |
| 1093 | let _ = git_repo | 1023 | let _ = git_repo |
| 1094 | .apply_patch_chain( | 1024 | .apply_patch_chain( |
| @@ -1102,7 +1032,7 @@ async fn launch_interactive() -> Result<()> { | |||
| 1102 | println!( | 1032 | println!( |
| 1103 | "checked out latest version of proposal ({} ahead {} behind '{main_branch_name}'), replacing unpublished version ({} ahead {} behind '{main_branch_name}')", | 1033 | "checked out latest version of proposal ({} ahead {} behind '{main_branch_name}'), replacing unpublished version ({} ahead {} behind '{main_branch_name}')", |
| 1104 | chain_length, | 1034 | chain_length, |
| 1105 | proposal_behind_main.len(), | 1035 | proposal_behind_main_len, |
| 1106 | local_ahead_of_main.len(), | 1036 | local_ahead_of_main.len(), |
| 1107 | local_beind_main.len(), | 1037 | local_beind_main.len(), |
| 1108 | ); | 1038 | ); |