@@ -427,7 +427,7 @@ pub enum CreateCommitFastError {
427427
428428/// Options for `Repo::amend_fast`
429429#[ derive( Debug ) ]
430- pub enum AmendFastOptions {
430+ pub enum AmendFastOptions < ' repo > {
431431 /// Amend a set of paths from the current state of the working copy.
432432 FromWorkingCopy {
433433 /// The status entries for the files to amend.
@@ -438,14 +438,20 @@ pub enum AmendFastOptions {
438438 /// The paths to amend.
439439 paths : Vec < PathBuf > ,
440440 } ,
441+ /// Amend a set of paths from a different commit.
442+ FromCommit {
443+ /// The commit whose contents will be ammended.
444+ commit : Commit < ' repo > ,
445+ } ,
441446}
442447
443- impl AmendFastOptions {
448+ impl < ' repo > AmendFastOptions < ' repo > {
444449 /// Returns whether there are any paths to be amended.
445450 pub fn is_empty ( & self ) -> bool {
446451 match & self {
447452 AmendFastOptions :: FromIndex { paths } => paths. is_empty ( ) ,
448453 AmendFastOptions :: FromWorkingCopy { status_entries } => status_entries. is_empty ( ) ,
454+ AmendFastOptions :: FromCommit { commit } => commit. is_empty ( ) ,
449455 }
450456 }
451457}
@@ -1422,10 +1428,14 @@ impl Repo {
14221428 /// See `Repo::cherry_pick_fast` for motivation for performing the operation
14231429 /// in-memory.
14241430 #[ instrument]
1425- pub fn amend_fast ( & self , parent_commit : & Commit , opts : & AmendFastOptions ) -> Result < Tree > {
1431+ pub fn amend_fast (
1432+ & self ,
1433+ parent_commit : & Commit ,
1434+ opts : & AmendFastOptions ,
1435+ ) -> std:: result:: Result < Tree , CreateCommitFastError > {
14261436 let parent_commit_pathbufs = self
14271437 . get_paths_touched_by_commit ( parent_commit) ?
1428- . ok_or_else ( || Error :: GetPatch {
1438+ . ok_or_else ( || CreateCommitFastError :: GetPatch {
14291439 commit : parent_commit. get_oid ( ) ,
14301440 } ) ?
14311441 . into_iter ( )
@@ -1439,6 +1449,11 @@ impl Repo {
14391449 result. extend ( entry. paths ( ) . iter ( ) . cloned ( ) ) ;
14401450 }
14411451 }
1452+ AmendFastOptions :: FromCommit { commit } => {
1453+ if let Some ( paths) = self . get_paths_touched_by_commit ( commit) ? {
1454+ result. extend ( paths. iter ( ) . cloned ( ) ) ;
1455+ }
1456+ }
14421457 } ;
14431458 result. into_iter ( ) . collect_vec ( )
14441459 } ;
@@ -1492,6 +1507,25 @@ impl Repo {
14921507 } )
14931508 . collect :: < HashMap < _ , _ > > ( )
14941509 }
1510+ AmendFastOptions :: FromCommit { commit } => {
1511+ let amended_tree = self . cherry_pick_fast (
1512+ commit,
1513+ parent_commit,
1514+ & CherryPickFastOptions {
1515+ reuse_parent_tree_if_possible : false ,
1516+ } ,
1517+ ) ?;
1518+ self . get_paths_touched_by_commit ( commit) ?
1519+ . unwrap_or_default ( )
1520+ . iter ( )
1521+ . filter_map ( |path| match amended_tree. get_path ( path) {
1522+ Ok ( Some ( entry) ) => {
1523+ Some ( ( path. clone ( ) , Some ( ( entry. get_oid ( ) , entry. get_filemode ( ) ) ) ) )
1524+ }
1525+ Ok ( None ) | Err ( _) => None ,
1526+ } )
1527+ . collect :: < HashMap < _ , _ > > ( )
1528+ }
14951529 } ;
14961530
14971531 // Merge the new path entries into the existing set of parent tree.
0 commit comments