@@ -1546,11 +1546,6 @@ fn apply_to_commit2(
15461546 . transpose ( ) ;
15471547 }
15481548 Op :: Workspace ( ws_path) => {
1549- let normal_parents = commit
1550- . parent_ids ( )
1551- . map ( |parent| transaction. get ( filter, parent) )
1552- . collect :: < Option < Vec < git2:: Oid > > > ( ) ;
1553-
15541549 if let Some ( ( redirect, _) ) = resolve_workspace_redirect ( repo, & commit. tree ( ) ?, ws_path)
15551550 {
15561551 if let Some ( r) = apply_to_commit2 ( & to_op ( redirect) , commit, transaction) ? {
@@ -1561,11 +1556,11 @@ fn apply_to_commit2(
15611556 }
15621557 }
15631558
1564- let normal_parents = some_or ! ( normal_parents , { return Ok ( None ) } ) ;
1559+ let commit_filter = filter ;
15651560
15661561 let cw = get_workspace ( repo, & commit. tree ( ) ?, ws_path) ;
15671562
1568- let extra_parents = commit
1563+ let parent_filters = commit
15691564 . parents ( )
15701565 . map ( |parent| {
15711566 rs_tracing:: trace_scoped!( "parent" , "id" : parent. id( ) . to_string( ) ) ;
@@ -1583,31 +1578,18 @@ fn apply_to_commit2(
15831578 & parent. tree ( ) . unwrap_or_else ( |_| tree:: empty ( repo) ) ,
15841579 & p,
15851580 ) ;
1586- let f = opt:: optimize ( to_filter ( Op :: Subtract ( cw, pcw) ) ) ;
1587-
1588- apply_to_commit2 ( & to_op ( f) , & parent, transaction)
1581+ Ok ( ( parent, pcw) )
15891582 } )
1590- . collect :: < JoshResult < Option < Vec < _ > > > > ( ) ?;
1583+ . collect :: < JoshResult < Vec < _ > > > ( ) ?;
15911584
1592- let extra_parents = some_or ! ( extra_parents, { return Ok ( None ) } ) ;
1593-
1594- let filtered_parent_ids: Vec < _ > =
1595- normal_parents. into_iter ( ) . chain ( extra_parents) . collect ( ) ;
1596-
1597- let filtered_tree = apply (
1585+ return per_rev_filter (
15981586 transaction,
1599- filter,
1600- Apply :: from_commit ( commit) ?. with_parents ( filtered_parent_ids. clone ( ) ) ,
1601- ) ?;
1602-
1603- return Some ( history:: create_filtered_commit (
16041587 commit,
1605- filtered_parent_ids,
1606- filtered_tree,
1607- transaction,
16081588 filter,
1609- ) )
1610- . transpose ( ) ;
1589+ commit_filter,
1590+ cw,
1591+ parent_filters,
1592+ ) ;
16111593 }
16121594 Op :: Fold => {
16131595 let filtered_parent_ids = commit
@@ -1633,50 +1615,24 @@ fn apply_to_commit2(
16331615 }
16341616 Op :: Hook ( hook) => {
16351617 let commit_filter = transaction. lookup_filter_hook ( & hook, commit. id ( ) ) ?;
1636- let normal_parents = commit
1637- . parent_ids ( )
1638- . map ( |x| transaction. get ( filter, x) )
1639- . collect :: < Option < Vec < _ > > > ( ) ;
1640- let normal_parents = some_or ! ( normal_parents, { return Ok ( None ) } ) ;
1618+ let cw = commit_filter;
16411619
1642- // Compute the difference between the current commit's filter and each parent's filter.
1643- // This determines what new content should be contributed by that parent in the filtered history.
1644- let extra_parents = commit
1620+ let parent_filters = commit
16451621 . parents ( )
16461622 . map ( |parent| {
1647- rs_tracing:: trace_scoped!( "hook parent" , "id" : parent. id( ) . to_string( ) ) ;
1648-
16491623 let pcw = transaction. lookup_filter_hook ( & hook, parent. id ( ) ) ?;
1650- let f = opt:: optimize ( to_filter ( Op :: Subtract ( commit_filter, pcw) ) ) ;
1651-
1652- let r = apply_to_commit2 ( & to_op ( f) , & parent, transaction) ;
1653- r
1624+ Ok ( ( parent, pcw) )
16541625 } )
1655- . collect :: < JoshResult < Option < Vec < _ > > > > ( ) ?;
1626+ . collect :: < JoshResult < Vec < _ > > > ( ) ?;
16561627
1657- let extra_parents = some_or ! ( extra_parents, { return Ok ( None ) } ) ;
1658-
1659- let extra_parents: Vec < _ > = extra_parents
1660- . into_iter ( )
1661- . filter ( |& oid| oid != git2:: Oid :: zero ( ) )
1662- . collect ( ) ;
1663-
1664- let filtered_parent_ids: Vec < _ > =
1665- normal_parents. into_iter ( ) . chain ( extra_parents) . collect ( ) ;
1666-
1667- let tree_data = apply (
1628+ return per_rev_filter (
16681629 transaction,
1669- commit_filter,
1670- Apply :: from_commit ( commit) ?. with_parents ( filtered_parent_ids. clone ( ) ) ,
1671- ) ?;
1672- return Some ( history:: create_filtered_commit (
16731630 commit,
1674- filtered_parent_ids,
1675- tree_data,
1676- transaction,
16771631 filter,
1678- ) )
1679- . transpose ( ) ;
1632+ commit_filter,
1633+ cw,
1634+ parent_filters,
1635+ ) ;
16801636 }
16811637 _ => {
16821638 let filtered_parent_ids = commit
@@ -2099,6 +2055,53 @@ pub fn is_linear(filter: Filter) -> bool {
20992055 }
21002056}
21012057
2058+ fn per_rev_filter (
2059+ transaction : & cache:: Transaction ,
2060+ commit : & git2:: Commit ,
2061+ filter : Filter ,
2062+ commit_filter : Filter ,
2063+ cw : Filter ,
2064+ parent_filters : Vec < ( git2:: Commit , Filter ) > ,
2065+ ) -> JoshResult < Option < git2:: Oid > > {
2066+ // Compute the difference between the current commit's filter and each parent's filter.
2067+ // This determines what new content should be contributed by that parent in the filtered history.
2068+ let extra_parents = parent_filters
2069+ . into_iter ( )
2070+ . map ( |( parent, pcw) | {
2071+ let f = opt:: optimize ( to_filter ( Op :: Subtract ( cw, pcw) ) ) ;
2072+ apply_to_commit2 ( & to_op ( f) , & parent, transaction)
2073+ } )
2074+ . collect :: < JoshResult < Option < Vec < _ > > > > ( ) ?;
2075+
2076+ let extra_parents = some_or ! ( extra_parents, { return Ok ( None ) } ) ;
2077+
2078+ let extra_parents: Vec < _ > = extra_parents
2079+ . into_iter ( )
2080+ . filter ( |& oid| oid != git2:: Oid :: zero ( ) )
2081+ . collect ( ) ;
2082+
2083+ let normal_parents = commit
2084+ . parent_ids ( )
2085+ . map ( |parent| transaction. get ( filter, parent) )
2086+ . collect :: < Option < Vec < git2:: Oid > > > ( ) ;
2087+ let normal_parents = some_or ! ( normal_parents, { return Ok ( None ) } ) ;
2088+ let filtered_parent_ids: Vec < _ > = normal_parents. into_iter ( ) . chain ( extra_parents) . collect ( ) ;
2089+
2090+ let tree_data = apply (
2091+ transaction,
2092+ commit_filter,
2093+ Apply :: from_commit ( commit) ?. with_parents ( filtered_parent_ids. clone ( ) ) ,
2094+ ) ?;
2095+ return Some ( history:: create_filtered_commit (
2096+ commit,
2097+ filtered_parent_ids,
2098+ tree_data,
2099+ transaction,
2100+ filter,
2101+ ) )
2102+ . transpose ( ) ;
2103+ }
2104+
21022105#[ cfg( test) ]
21032106mod tests {
21042107 use super :: * ;
0 commit comments