@@ -6,11 +6,136 @@ use std::path::PathBuf;
6
6
7
7
use branchless:: core:: effects:: Effects ;
8
8
use branchless:: core:: formatting:: Glyphs ;
9
- use branchless:: git:: { hydrate_tree, process_diff_for_record, FileMode , MaybeZeroOid , Repo } ;
9
+ use branchless:: git:: {
10
+ hydrate_tree, process_diff_for_record, Commit , FileMode , MaybeZeroOid , NonZeroOid , Repo , Tree ,
11
+ } ;
10
12
use bstr:: ByteSlice ;
11
13
use eyre:: Context ;
12
14
use scm_record:: { File , Section , SelectedContents } ;
13
15
16
+ fn entries_from_files (
17
+ repo : & Repo ,
18
+ old_tree : & Tree ,
19
+ new_tree : & Tree ,
20
+ files : & [ File ] ,
21
+ ) -> eyre:: Result < HashMap < PathBuf , Option < ( NonZeroOid , FileMode ) > > > {
22
+ let entries = files
23
+ . into_iter ( )
24
+ . map ( |file| {
25
+ let file_path = file. path . clone ( ) . into_owned ( ) ;
26
+ let value = {
27
+ let ( selected, _unselected) = file. get_selected_contents ( ) ;
28
+ let blob_oid = match selected {
29
+ SelectedContents :: Absent => return Ok ( ( file_path, None ) ) ,
30
+ SelectedContents :: Unchanged => {
31
+ old_tree. get_oid_for_path ( & file. path ) ?. unwrap_or_default ( )
32
+ }
33
+ SelectedContents :: Binary {
34
+ old_description : _,
35
+ new_description : _,
36
+ } => new_tree. get_oid_for_path ( & file. path ) ?. unwrap ( ) ,
37
+ SelectedContents :: Present { contents } => {
38
+ MaybeZeroOid :: NonZero ( repo. create_blob_from_contents ( contents. as_bytes ( ) ) ?)
39
+ }
40
+ } ;
41
+ match blob_oid {
42
+ MaybeZeroOid :: Zero => None ,
43
+ MaybeZeroOid :: NonZero ( blob_oid) => {
44
+ let new_file_mode = file
45
+ . get_file_mode ( )
46
+ . expect ( "File mode should have been set" ) ;
47
+ let file_mode = i32:: try_from ( new_file_mode) . unwrap ( ) ;
48
+ let file_mode = FileMode :: from ( file_mode) ;
49
+ Some ( ( blob_oid, file_mode) )
50
+ }
51
+ }
52
+ } ;
53
+ Ok ( ( file_path, value) )
54
+ } )
55
+ . collect :: < eyre:: Result < _ > > ( ) ?;
56
+ Ok ( entries)
57
+ }
58
+
59
+ fn select_all ( mut entries : Vec < File > ) -> Vec < File > {
60
+ for File {
61
+ path : _,
62
+ file_mode : _,
63
+ sections,
64
+ } in & mut entries
65
+ {
66
+ for section in sections {
67
+ match section {
68
+ Section :: Unchanged { lines : _ } => { }
69
+ Section :: Changed { lines } => {
70
+ for line in lines {
71
+ line. is_toggled = true ;
72
+ }
73
+ }
74
+ Section :: FileMode {
75
+ is_toggled,
76
+ before : _,
77
+ after : _,
78
+ }
79
+ | Section :: Binary {
80
+ is_toggled,
81
+ old_description : _,
82
+ new_description : _,
83
+ } => {
84
+ * is_toggled = true ;
85
+ }
86
+ }
87
+ }
88
+ }
89
+ entries
90
+ }
91
+
92
+ fn assert_trees_equal (
93
+ test : & str ,
94
+ repo : & Repo ,
95
+ parent_commit : & Commit ,
96
+ current_commit : & Commit ,
97
+ expected_tree : & Tree ,
98
+ entries : & [ File ] ,
99
+ ) -> eyre:: Result < ( ) > {
100
+ let old_tree = parent_commit. get_tree ( ) ?;
101
+ let new_tree = current_commit. get_tree ( ) ?;
102
+ let entries = entries_from_files ( repo, & old_tree, & new_tree, entries) ?;
103
+ let actual_tree_oid = hydrate_tree ( & repo, Some ( & old_tree) , entries) ?;
104
+ let actual_tree = repo. find_tree_or_fail ( actual_tree_oid) ?;
105
+ let actual_commit = {
106
+ let author = current_commit. get_author ( ) ;
107
+ let committer = current_commit. get_committer ( ) ;
108
+ let message = current_commit. get_message_raw ( ) ;
109
+ let message = message. to_str_lossy ( ) ;
110
+ let parents = current_commit. get_parents ( ) ;
111
+ let actual_oid = repo. create_commit (
112
+ None ,
113
+ & author,
114
+ & committer,
115
+ & message,
116
+ & actual_tree,
117
+ parents. iter ( ) . collect ( ) ,
118
+ ) ?;
119
+ repo. find_commit_or_fail ( actual_oid) ?
120
+ } ;
121
+ if actual_tree. get_oid ( ) != expected_tree. get_oid ( ) {
122
+ eyre:: bail!(
123
+ "\
124
+ Trees are NOT equal for test {test:?}
125
+ Actual: {actual} vs expected: {expected}
126
+ Try running:
127
+ git diff-tree -p {expected} {actual}
128
+ Or examine the new (wrong) commit with:
129
+ git show {commit_oid}" ,
130
+ expected = expected_tree. get_oid( ) . to_string( ) ,
131
+ actual = actual_tree. get_oid( ) . to_string( ) ,
132
+ commit_oid = actual_commit. get_oid( ) ,
133
+ ) ;
134
+ }
135
+
136
+ Ok ( ( ) )
137
+ }
138
+
14
139
fn main ( ) -> eyre:: Result < ( ) > {
15
140
let path_to_repo = std:: env:: var ( "PATH_TO_REPO" )
16
141
. wrap_err ( "Could not read PATH_TO_REPO environment variable" ) ?;
@@ -34,105 +159,29 @@ fn main() -> eyre::Result<()> {
34
159
let new_tree = current_commit. get_tree ( ) ?;
35
160
let diff = repo. get_diff_between_trees ( & effects, Some ( & old_tree) , & new_tree, 0 ) ?;
36
161
37
- let entries = {
38
- let mut entries = process_diff_for_record ( & repo, & diff) ?;
39
- for File {
40
- path : _,
41
- file_mode : _,
42
- sections,
43
- } in & mut entries
44
- {
45
- for section in sections {
46
- match section {
47
- Section :: Unchanged { lines : _ } => { }
48
- Section :: Changed { lines } => {
49
- for line in lines {
50
- line. is_toggled = true ;
51
- }
52
- }
53
- Section :: FileMode {
54
- is_toggled,
55
- before : _,
56
- after : _,
57
- }
58
- | Section :: Binary {
59
- is_toggled,
60
- old_description : _,
61
- new_description : _,
62
- } => {
63
- * is_toggled = true ;
64
- }
65
- }
66
- }
67
- }
68
- entries
69
- } ;
70
- let entries: HashMap < _ , _ > = entries
71
- . into_iter ( )
72
- . map ( |file| {
73
- let file_path = file. path . clone ( ) . into_owned ( ) ;
74
- let value = {
75
- let ( selected, _unselected) = file. get_selected_contents ( ) ;
76
- let blob_oid = match selected {
77
- SelectedContents :: Absent => return Ok ( ( file_path, None ) ) ,
78
- SelectedContents :: Unchanged => {
79
- old_tree. get_oid_for_path ( & file. path ) ?. unwrap_or_default ( )
80
- }
81
- SelectedContents :: Binary {
82
- old_description : _,
83
- new_description : _,
84
- } => new_tree. get_oid_for_path ( & file. path ) ?. unwrap ( ) ,
85
- SelectedContents :: Present { contents } => MaybeZeroOid :: NonZero (
86
- repo. create_blob_from_contents ( contents. as_bytes ( ) ) ?,
87
- ) ,
88
- } ;
89
- match blob_oid {
90
- MaybeZeroOid :: Zero => None ,
91
- MaybeZeroOid :: NonZero ( blob_oid) => {
92
- let new_file_mode = file
93
- . get_file_mode ( )
94
- . expect ( "File mode should have been set" ) ;
95
- let file_mode = i32:: try_from ( new_file_mode) . unwrap ( ) ;
96
- let file_mode = FileMode :: from ( file_mode) ;
97
- Some ( ( blob_oid, file_mode) )
98
- }
99
- }
100
- } ;
101
- Ok ( ( file_path, value) )
102
- } )
103
- . collect :: < eyre:: Result < _ > > ( ) ?;
162
+ let entries = process_diff_for_record ( & repo, & diff) ?;
163
+ {
164
+ assert_trees_equal (
165
+ & format ! ( "select-none {parent_commit:?}" ) ,
166
+ & repo,
167
+ & parent_commit,
168
+ & current_commit,
169
+ & parent_commit. get_tree ( ) ?,
170
+ & entries,
171
+ ) ?;
172
+ }
104
173
105
- let actual_tree_oid = hydrate_tree ( & repo, Some ( & old_tree) , entries) ?;
106
- let actual_tree = repo. find_tree_or_fail ( actual_tree_oid) ?;
107
- let actual_commit = {
108
- let author = current_commit. get_author ( ) ;
109
- let committer = current_commit. get_committer ( ) ;
110
- let message = current_commit. get_message_raw ( ) ;
111
- let message = message. to_str_lossy ( ) ;
112
- let parents = current_commit. get_parents ( ) ;
113
- let actual_oid = repo. create_commit (
114
- None ,
115
- & author,
116
- & committer,
117
- & message,
118
- & actual_tree,
119
- parents. iter ( ) . collect ( ) ,
174
+ // Select all changes (the resulting tree should be identical).
175
+ {
176
+ let entries = select_all ( entries) ;
177
+ assert_trees_equal (
178
+ & format ! ( "select-all {current_commit:?}" ) ,
179
+ & repo,
180
+ & parent_commit,
181
+ & current_commit,
182
+ & current_commit. get_tree ( ) ?,
183
+ & entries,
120
184
) ?;
121
- repo. find_commit_or_fail ( actual_oid) ?
122
- } ;
123
- let expected_tree = current_commit. get_tree ( ) ?;
124
- if actual_tree. get_oid ( ) != expected_tree. get_oid ( ) {
125
- println ! (
126
- "Trees are NOT equal, actual {actual} vs expected {expected}\n \
127
- Try running:\n \
128
- git diff-tree -p {expected} {actual}\n \
129
- Or examine the new (wrong) commit with:\n \
130
- git show {commit_oid}",
131
- expected = expected_tree. get_oid( ) . to_string( ) ,
132
- actual = actual_tree. get_oid( ) . to_string( ) ,
133
- commit_oid = actual_commit. get_oid( ) ,
134
- ) ;
135
- std:: process:: exit ( 1 ) ;
136
185
}
137
186
}
138
187
0 commit comments