@@ -6,98 +6,92 @@ pub fn log(mut repo: gix::Repository, out: &mut dyn std::io::Write, pathspec: BS
66 repo. object_cache_size_if_unset ( repo. compute_object_cache_size_for_tree_diffs ( & * * repo. index_or_empty ( ) ?) ) ;
77
88 let head = repo. head ( ) ?. peel_to_commit_in_place ( ) ?;
9- let infos : Vec < _ > =
9+ let mut topo =
1010 gix:: traverse:: commit:: topo:: Builder :: from_iters ( & repo. objects , [ head. id ] , None :: < Vec < gix:: ObjectId > > )
11- . build ( ) ?
12- . collect ( ) ;
11+ . build ( ) ?;
1312
14- let infos: Vec < _ > = infos
15- . into_iter ( )
16- . filter ( |info| {
17- let commit = repo. find_commit ( info. as_ref ( ) . unwrap ( ) . id ) . unwrap ( ) ;
13+ while let Some ( info) = topo. next ( ) {
14+ let info = info?;
15+ let commit = repo. find_commit ( info. id ) . unwrap ( ) ;
1816
19- let mut buffer = Vec :: new ( ) ;
20- let tree = repo. objects . find_tree ( & commit. tree_id ( ) . unwrap ( ) , & mut buffer) . unwrap ( ) ;
17+ let mut buffer = Vec :: new ( ) ;
18+ let tree = repo. objects . find_tree ( & commit. tree_id ( ) . unwrap ( ) , & mut buffer) . unwrap ( ) ;
2119
22- let Some ( entry) = tree. bisect_entry ( pathspec. as_ref ( ) , false ) else {
23- return false ;
24- } ;
20+ let Some ( entry) = tree. bisect_entry ( pathspec. as_ref ( ) , false ) else {
21+ continue ;
22+ } ;
2523
26- let parent_ids: Vec < _ > = commit. parent_ids ( ) . collect ( ) ;
24+ let parent_ids: Vec < _ > = commit. parent_ids ( ) . collect ( ) ;
2725
28- if parent_ids. is_empty ( ) {
29- // We confirmed above that the file is in `commit`'s tree. If `parent_ids` is
30- // empty, the file was added in `commit`.
26+ if parent_ids. is_empty ( ) {
27+ // We confirmed above that the file is in `commit`'s tree. If `parent_ids` is
28+ // empty, the file was added in `commit`.
3129
32- return true ;
33- }
30+ write_info ( & repo, out, & info) ?;
3431
35- let parent_ids_with_changes: Vec < _ > = parent_ids
36- . clone ( )
37- . into_iter ( )
38- . filter ( |parent_id| {
39- let mut buffer = Vec :: new ( ) ;
40- let parent_commit = repo. find_commit ( * parent_id) . unwrap ( ) ;
41- let parent_tree = repo
42- . objects
43- . find_tree ( & parent_commit. tree_id ( ) . unwrap ( ) , & mut buffer)
44- . unwrap ( ) ;
45-
46- if let Some ( parent_entry) = parent_tree. bisect_entry ( pathspec. as_ref ( ) , false ) {
47- if entry. oid == parent_entry. oid {
48- // The blobs storing the file in `entry` and `parent_entry` are
49- // identical which means the file was not changed in `commit`.
50-
51- return false ;
52- }
53- }
32+ break ;
33+ }
5434
55- true
56- } )
57- . collect ( ) ;
35+ let parent_ids_with_changes: Vec < _ > = parent_ids
36+ . clone ( )
37+ . into_iter ( )
38+ . filter ( |parent_id| {
39+ let mut buffer = Vec :: new ( ) ;
40+ let parent_commit = repo. find_commit ( * parent_id) . unwrap ( ) ;
41+ let parent_tree = repo
42+ . objects
43+ . find_tree ( & parent_commit. tree_id ( ) . unwrap ( ) , & mut buffer)
44+ . unwrap ( ) ;
5845
59- if parent_ids. len ( ) != parent_ids_with_changes. len ( ) {
60- // At least one parent had an identical version of the file which means it was not
61- // changed in `commit`.
46+ if let Some ( parent_entry) = parent_tree. bisect_entry ( pathspec. as_ref ( ) , false ) {
47+ if entry. oid == parent_entry. oid {
48+ // The blobs storing the file in `entry` and `parent_entry` are
49+ // identical which means the file was not changed in `commit`.
6250
63- return false ;
64- }
51+ return false ;
52+ }
53+ }
54+
55+ true
56+ } )
57+ . collect ( ) ;
6558
66- for parent_id in parent_ids_with_changes {
67- let modifications =
68- get_modifications_for_file_path ( & repo . objects , pathspec . as_ref ( ) , commit. id , parent_id . into ( ) ) ;
59+ if parent_ids . len ( ) != parent_ids_with_changes. len ( ) {
60+ // At least one parent had an identical version of the file which means it was not
61+ // changed in ` commit`.
6962
70- return !modifications . is_empty ( ) ;
71- }
63+ continue ;
64+ }
7265
73- return false ;
74- } )
75- . collect ( ) ;
66+ for parent_id in parent_ids_with_changes {
67+ let modifications =
68+ get_modifications_for_file_path ( & repo . objects , pathspec . as_ref ( ) , commit . id , parent_id . into ( ) ) ;
7669
77- write_infos ( & repo, out, infos) ?;
70+ if !modifications. is_empty ( ) {
71+ write_info ( & repo, & mut * out, & info) ?;
72+ }
73+ }
74+ }
7875
7976 Ok ( ( ) )
8077}
8178
82- fn write_infos (
79+ fn write_info (
8380 repo : & gix:: Repository ,
8481 mut out : impl std:: io:: Write ,
85- infos : Vec < Result < gix:: traverse:: commit:: Info , gix :: traverse :: commit :: topo :: Error > > ,
82+ info : & gix:: traverse:: commit:: Info ,
8683) -> Result < ( ) , std:: io:: Error > {
87- for info in infos {
88- let info = info. unwrap ( ) ;
89- let commit = repo. find_commit ( info. id ) . unwrap ( ) ;
84+ let commit = repo. find_commit ( info. id ) . unwrap ( ) ;
9085
91- let message = commit. message_raw_sloppy ( ) ;
92- let title = message. lines ( ) . next ( ) ;
86+ let message = commit. message_raw_sloppy ( ) ;
87+ let title = message. lines ( ) . next ( ) ;
9388
94- writeln ! (
95- out,
96- "{} {}" ,
97- info. id. to_hex_with_len( 8 ) ,
98- title. map( BString :: from) . unwrap_or_else( || "<no message>" . into( ) )
99- ) ?;
100- }
89+ writeln ! (
90+ out,
91+ "{} {}" ,
92+ info. id. to_hex_with_len( 8 ) ,
93+ title. map( BString :: from) . unwrap_or_else( || "<no message>" . into( ) )
94+ ) ?;
10195
10296 Ok ( ( ) )
10397}
0 commit comments