upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/git_remote_nostr/fetch.rs22
-rw-r--r--src/bin/ngit/sub_commands/checkout.rs61
-rw-r--r--src/bin/ngit/sub_commands/init.rs12
-rw-r--r--src/bin/ngit/sub_commands/list.rs158
-rw-r--r--src/lib/git_events.rs9
5 files changed, 77 insertions, 185 deletions
diff --git a/src/bin/git_remote_nostr/fetch.rs b/src/bin/git_remote_nostr/fetch.rs
index 7ee264b..dd80f0f 100644
--- a/src/bin/git_remote_nostr/fetch.rs
+++ b/src/bin/git_remote_nostr/fetch.rs
@@ -10,7 +10,7 @@ use ngit::{
10 git::{Repo, RepoActions}, 10 git::{Repo, RepoActions},
11 git_events::{ 11 git_events::{
12 KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, 12 KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE,
13 identify_clone_urls_for_oids_from_pr_pr_update_events, tag_value, 13 identify_clone_urls_for_oids_from_pr_pr_update_events,
14 }, 14 },
15 login::get_curent_user, 15 login::get_curent_user,
16 repo_ref::{RepoRef, is_grasp_server_in_list}, 16 repo_ref::{RepoRef, is_grasp_server_in_list},
@@ -126,19 +126,13 @@ pub fn make_commits_for_proposal(
126 patches_ancestor_last: &[Event], 126 patches_ancestor_last: &[Event],
127) -> Result<String> { 127) -> Result<String> {
128 let patches_ancestor_first: Vec<&Event> = patches_ancestor_last.iter().rev().collect(); 128 let patches_ancestor_first: Vec<&Event> = patches_ancestor_last.iter().rev().collect();
129 let mut tip_commit_id = if let Ok(parent_commit) = tag_value( 129 let first_patch = patches_ancestor_first
130 patches_ancestor_first 130 .first()
131 .first() 131 .context("proposal should have at least one patch")?;
132 .context("proposal should have at least one patch")?, 132
133 "parent-commit", 133 let mut tip_commit_id =
134 ) { 134 ngit::git_events::get_parent_commit_from_patch(first_patch, Some(git_repo))
135 parent_commit 135 .context("failed to determine parent commit for proposal")?;
136 } else {
137 // TODO choose most recent commit on master before patch timestamp so it doesnt
138 // constantly get rebased
139 let (_, hash) = git_repo.get_main_or_master_branch()?;
140 hash.to_string()
141 };
142 136
143 for patch in &patches_ancestor_first { 137 for patch in &patches_ancestor_first {
144 let commit_id = git_repo 138 let commit_id = git_repo
diff --git a/src/bin/ngit/sub_commands/checkout.rs b/src/bin/ngit/sub_commands/checkout.rs
index 87f1ff2..67447ae 100644
--- a/src/bin/ngit/sub_commands/checkout.rs
+++ b/src/bin/ngit/sub_commands/checkout.rs
@@ -24,7 +24,7 @@ use nostr_sdk::{EventId, FromBech32};
24use crate::{ 24use crate::{
25 client::{Client, Connect, fetching_with_report, get_repo_ref_from_cache}, 25 client::{Client, Connect, fetching_with_report, get_repo_ref_from_cache},
26 git::{Repo, RepoActions, str_to_sha1}, 26 git::{Repo, RepoActions, str_to_sha1},
27 git_events::{event_to_cover_letter, get_parent_commit_from_patch, patch_supports_commit_ids}, 27 git_events::event_to_cover_letter,
28 repo_ref::get_repo_coordinates_when_remote_unknown, 28 repo_ref::get_repo_coordinates_when_remote_unknown,
29}; 29};
30 30
@@ -261,32 +261,7 @@ fn checkout_patch(
261 most_recent_proposal_patch_chain_or_pr_or_pr_update: &[nostr::Event], 261 most_recent_proposal_patch_chain_or_pr_or_pr_update: &[nostr::Event],
262 nostr_remote_name: Option<&str>, 262 nostr_remote_name: Option<&str>,
263) -> Result<()> { 263) -> Result<()> {
264 let no_support_for_patches_as_branch = most_recent_proposal_patch_chain_or_pr_or_pr_update 264 let (_, _master_tip) = git_repo.get_main_or_master_branch()?;
265 .iter()
266 .any(|event| !patch_supports_commit_ids(event));
267
268 if no_support_for_patches_as_branch {
269 bail!(
270 "this proposal cannot be checked out as a branch because some patches do not have a parent commit.\n\
271 Try `ngit apply --stdout` to apply patches to the current branch, or use `ngit list` for interactive options."
272 );
273 }
274
275 let last_patch = most_recent_proposal_patch_chain_or_pr_or_pr_update
276 .last()
277 .context("there should be at least one patch")?;
278
279 let proposal_base_commit = str_to_sha1(&get_parent_commit_from_patch(last_patch, Some(git_repo))?)
280 .context("failed to get valid parent commit id from patch")?;
281
282 let (main_branch_name, _master_tip) = git_repo.get_main_or_master_branch()?;
283
284 if !git_repo.does_commit_exist(&proposal_base_commit.to_string())? {
285 bail!(
286 "the proposal parent commit doesn't exist in your local repository.\n\
287 Try running `git pull` on '{main_branch_name}' first, or use `ngit apply --stdout` to apply patches to the current branch."
288 );
289 }
290 265
291 if git_repo.has_outstanding_changes()? { 266 if git_repo.has_outstanding_changes()? {
292 bail!("working directory is not clean. Discard or stash (un)staged changes and try again."); 267 bail!("working directory is not clean. Discard or stash (un)staged changes and try again.");
@@ -322,23 +297,25 @@ fn checkout_patch(
322 297
323 let local_branch_tip = git_repo.get_tip_of_branch(&branch_name)?; 298 let local_branch_tip = git_repo.get_tip_of_branch(&branch_name)?;
324 299
325 let proposal_tip = str_to_sha1( 300 // If we can reliably determine the proposal tip commit, use it to skip
326 &get_commit_id_from_patch( 301 // re-applying when already up-to-date. If the commit tag is absent or
327 most_recent_proposal_patch_chain_or_pr_or_pr_update 302 // unreliable, skip this check and let apply_patch_chain handle idempotency.
328 .first() 303 if let Ok(proposal_tip_str) = get_commit_id_from_patch(
329 .context("there should be at least one patch")?, 304 most_recent_proposal_patch_chain_or_pr_or_pr_update
330 ) 305 .first()
331 .context("failed to get valid commit_id from patch")?, 306 .context("there should be at least one patch")?,
332 ) 307 ) {
333 .context("failed to get valid commit_id from patch")?; 308 if let Ok(proposal_tip) = str_to_sha1(&proposal_tip_str) {
334 309 if proposal_tip.eq(&local_branch_tip) {
335 if proposal_tip.eq(&local_branch_tip) { 310 git_repo.checkout(&branch_name)?;
336 git_repo.checkout(&branch_name)?; 311 println!("branch '{branch_name}' checked out and up-to-date");
337 println!("branch '{branch_name}' checked out and up-to-date"); 312 return Ok(());
338 return Ok(()); 313 }
314 }
339 } 315 }
340 316
341 git_repo.create_branch_at_commit(&branch_name, &proposal_base_commit.to_string())?; 317 // Branch exists but may need updating — re-apply the chain.
318 // apply_patch_chain handles already-applied commits idempotently.
342 git_repo.checkout(&branch_name)?; 319 git_repo.checkout(&branch_name)?;
343 let _ = git_repo 320 let _ = git_repo
344 .apply_patch_chain( 321 .apply_patch_chain(
diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs
index 75306d1..5dd6157 100644
--- a/src/bin/ngit/sub_commands/init.rs
+++ b/src/bin/ngit/sub_commands/init.rs
@@ -1724,10 +1724,7 @@ struct PollContext {
1724 reveal_state: Arc<ServerRevealState>, 1724 reveal_state: Arc<ServerRevealState>,
1725} 1725}
1726 1726
1727fn create_server_bars( 1727fn create_server_bars(clone_urls: &[String], detail_multi: &MultiProgress) -> Vec<ProgressBar> {
1728 clone_urls: &[String],
1729 detail_multi: &MultiProgress,
1730) -> Vec<ProgressBar> {
1731 let waiting_style = ProgressStyle::with_template(" {spinner} {msg}") 1728 let waiting_style = ProgressStyle::with_template(" {spinner} {msg}")
1732 .unwrap() 1729 .unwrap()
1733 .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈"); 1730 .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈");
@@ -1779,12 +1776,7 @@ fn spawn_expand_timer(
1779 }) 1776 })
1780} 1777}
1781 1778
1782fn finalize_spinner( 1779fn finalize_spinner(all_ready: bool, spinner_pb: &ProgressBar, final_ready: u64, total: u64) {
1783 all_ready: bool,
1784 spinner_pb: &ProgressBar,
1785 final_ready: u64,
1786 total: u64,
1787) {
1788 if all_ready { 1780 if all_ready {
1789 spinner_pb.finish_and_clear(); 1781 spinner_pb.finish_and_clear();
1790 } else { 1782 } else {
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 );
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index b39e797..32c23ac 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -40,17 +40,16 @@ pub fn get_commit_id_from_patch(event: &Event) -> Result<String> {
40 } 40 }
41} 41}
42 42
43pub fn get_parent_commit_from_patch( 43pub fn get_parent_commit_from_patch(event: &Event, git_repo: Option<&Repo>) -> Result<String> {
44 event: &Event,
45 git_repo: Option<&Repo>,
46) -> Result<String> {
47 if let Ok(parent) = tag_value(event, "parent-commit") { 44 if let Ok(parent) = tag_value(event, "parent-commit") {
48 return Ok(parent); 45 return Ok(parent);
49 } 46 }
50 47
51 let metadata = crate::mbox_parser::parse_mbox_patch(&event.content) 48 let metadata = crate::mbox_parser::parse_mbox_patch(&event.content)
52 .context("failed to parse patch for timestamp")?; 49 .context("failed to parse patch for timestamp")?;
53 let timestamp = metadata.committer_timestamp.unwrap_or(metadata.author_timestamp); 50 let timestamp = metadata
51 .committer_timestamp
52 .unwrap_or(metadata.author_timestamp);
54 53
55 if let Some(repo) = git_repo { 54 if let Some(repo) = git_repo {
56 if let Some(best_guess) = repo 55 if let Some(best_guess) = repo