@@ -36,17 +36,24 @@ pub fn amend(
36
36
fn signature_allow_undefined_name (
37
37
repo : & Repository ,
38
38
) -> std:: result:: Result < Signature < ' _ > , git2:: Error > {
39
- match repo. signature ( ) {
40
- Err ( e) if e. code ( ) == ErrorCode :: NotFound => {
39
+ let signature = repo. signature ( ) ;
40
+
41
+ if let Err ( ref e) = signature {
42
+ if e. code ( ) == ErrorCode :: NotFound {
41
43
let config = repo. config ( ) ?;
42
- Signature :: now (
43
- config. get_str ( "user.name" ) . unwrap_or ( "unknown" ) ,
44
- config. get_str ( "user.email" ) ?,
45
- )
46
- }
47
44
48
- v => v,
45
+ if let ( Err ( _) , Ok ( email_entry) ) = (
46
+ config. get_entry ( "user.name" ) ,
47
+ config. get_entry ( "user.email" ) ,
48
+ ) {
49
+ if let Some ( email) = email_entry. value ( ) {
50
+ return Signature :: now ( "unknown" , email) ;
51
+ }
52
+ } ;
53
+ }
49
54
}
55
+
56
+ signature
50
57
}
51
58
52
59
/// this does not run any git hooks
@@ -245,4 +252,86 @@ mod tests {
245
252
246
253
Ok ( ( ) )
247
254
}
255
+
256
+ /// Beware: this test has to be run with a `$HOME/.gitconfig` that has
257
+ /// `user.email` not set. Otherwise, git falls back to the value of
258
+ /// `user.email` in `$HOME/.gitconfig` and this test fails.
259
+ ///
260
+ /// As of February 2021, `repo_init_empty` sets all git config locations
261
+ /// to an empty temporary directory, so this constraint is met.
262
+ #[ test]
263
+ fn test_empty_email ( ) -> Result < ( ) > {
264
+ let file_path = Path :: new ( "foo" ) ;
265
+ let ( _td, repo) = repo_init_empty ( ) . unwrap ( ) ;
266
+ let root = repo. path ( ) . parent ( ) . unwrap ( ) ;
267
+ let repo_path = root. as_os_str ( ) . to_str ( ) . unwrap ( ) ;
268
+
269
+ File :: create ( & root. join ( file_path) ) ?
270
+ . write_all ( b"test\n foo" ) ?;
271
+
272
+ stage_add_file ( repo_path, file_path) ?;
273
+
274
+ repo. config ( ) ?. remove ( "user.email" ) ?;
275
+
276
+ let error = commit ( repo_path, "commit msg" ) ;
277
+
278
+ assert ! ( matches!( error, Err ( _) ) ) ;
279
+
280
+ repo. config ( ) ?. set_str ( "user.email" , "email" ) ?;
281
+
282
+ let success = commit ( repo_path, "commit msg" ) ;
283
+
284
+ assert ! ( matches!( success, Ok ( _) ) ) ;
285
+ assert_eq ! ( count_commits( & repo, 10 ) , 1 ) ;
286
+
287
+ let details =
288
+ get_commit_details ( repo_path, success. unwrap ( ) ) . unwrap ( ) ;
289
+
290
+ assert_eq ! ( details. author. name, "name" ) ;
291
+ assert_eq ! ( details. author. email, "email" ) ;
292
+
293
+ Ok ( ( ) )
294
+ }
295
+
296
+ /// See comment to `test_empty_email`.
297
+ #[ test]
298
+ fn test_empty_name ( ) -> Result < ( ) > {
299
+ let file_path = Path :: new ( "foo" ) ;
300
+ let ( _td, repo) = repo_init_empty ( ) . unwrap ( ) ;
301
+ let root = repo. path ( ) . parent ( ) . unwrap ( ) ;
302
+ let repo_path = root. as_os_str ( ) . to_str ( ) . unwrap ( ) ;
303
+
304
+ File :: create ( & root. join ( file_path) ) ?
305
+ . write_all ( b"test\n foo" ) ?;
306
+
307
+ stage_add_file ( repo_path, file_path) ?;
308
+
309
+ repo. config ( ) ?. remove ( "user.name" ) ?;
310
+
311
+ let mut success = commit ( repo_path, "commit msg" ) ;
312
+
313
+ assert ! ( matches!( success, Ok ( _) ) ) ;
314
+ assert_eq ! ( count_commits( & repo, 10 ) , 1 ) ;
315
+
316
+ let mut details =
317
+ get_commit_details ( repo_path, success. unwrap ( ) ) . unwrap ( ) ;
318
+
319
+ assert_eq ! ( details. author. name, "unknown" ) ;
320
+ assert_eq ! ( details. author. email, "email" ) ;
321
+
322
+ repo. config ( ) ?. set_str ( "user.name" , "name" ) ?;
323
+
324
+ success = commit ( repo_path, "commit msg" ) ;
325
+
326
+ assert ! ( matches!( success, Ok ( _) ) ) ;
327
+ assert_eq ! ( count_commits( & repo, 10 ) , 2 ) ;
328
+
329
+ details =
330
+ get_commit_details ( repo_path, success. unwrap ( ) ) . unwrap ( ) ;
331
+
332
+ assert_eq ! ( details. author. name, "name" ) ;
333
+ assert_eq ! ( details. author. email, "email" ) ;
334
+
335
+ Ok ( ( ) )
336
+ }
248
337
}
0 commit comments