@@ -66,6 +66,47 @@ fn get_current_branch(
66
66
Ok ( None )
67
67
}
68
68
69
+ /// Tries to find the default repo to fetch from based on configuration.
70
+ ///
71
+ /// > branch.<name>.remote
72
+ /// >
73
+ /// > When on branch `<name>`, it tells `git fetch` and `git push` which remote to fetch from or
74
+ /// > push to. [...] If no remote is configured, or if you are not on any branch and there is more
75
+ /// > than one remote defined in the repository, it defaults to `origin` for fetching [...].
76
+ ///
77
+ /// [git-config-branch-name-remote]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-branchltnamegtremote
78
+ ///
79
+ /// Falls back to `get_default_remote_in_repo`.
80
+ pub fn get_default_remote_for_fetch (
81
+ repo_path : & RepoPath ,
82
+ ) -> Result < String > {
83
+ let repo = repo ( repo_path) ?;
84
+ get_default_remote_for_fetch_in_repo ( & repo)
85
+ }
86
+
87
+ // TODO: Very similar to `get_default_remote_for_push_in_repo`. Can probably be refactored.
88
+ pub ( crate ) fn get_default_remote_for_fetch_in_repo (
89
+ repo : & Repository ,
90
+ ) -> Result < String > {
91
+ scope_time ! ( "get_default_remote_for_fetch_in_repo" ) ;
92
+
93
+ let config = repo. config ( ) ?;
94
+
95
+ let branch = get_current_branch ( repo) ?;
96
+
97
+ if let Some ( branch) = branch {
98
+ let remote_name = bytes2string ( branch. name_bytes ( ) ?) ?;
99
+
100
+ let entry_name = format ! ( "branch.{}.remote" , & remote_name) ;
101
+
102
+ if let Ok ( entry) = config. get_entry ( & entry_name) {
103
+ return bytes2string ( entry. value_bytes ( ) ) ;
104
+ }
105
+ }
106
+
107
+ get_default_remote_in_repo ( repo)
108
+ }
109
+
69
110
/// Tries to find the default repo to push to based on configuration.
70
111
///
71
112
/// > remote.pushDefault
@@ -93,6 +134,7 @@ pub fn get_default_remote_for_push(
93
134
get_default_remote_for_push_in_repo ( & repo)
94
135
}
95
136
137
+ // TODO: Very similar to `get_default_remote_for_fetch_in_repo`. Can probably be refactored.
96
138
pub ( crate ) fn get_default_remote_for_push_in_repo (
97
139
repo : & Repository ,
98
140
) -> Result < String > {
@@ -383,6 +425,42 @@ mod tests {
383
425
) ) ;
384
426
}
385
427
428
+ #[ test]
429
+ fn test_default_remote_for_fetch ( ) {
430
+ let ( remote_dir, _remote) = repo_init ( ) . unwrap ( ) ;
431
+ let remote_path = remote_dir. path ( ) . to_str ( ) . unwrap ( ) ;
432
+ let ( repo_dir, repo) = repo_clone ( remote_path) . unwrap ( ) ;
433
+ let repo_path: & RepoPath = & repo_dir
434
+ . into_path ( )
435
+ . as_os_str ( )
436
+ . to_str ( )
437
+ . unwrap ( )
438
+ . into ( ) ;
439
+
440
+ debug_cmd_print (
441
+ repo_path,
442
+ "git remote rename origin alternate" ,
443
+ ) ;
444
+
445
+ debug_cmd_print (
446
+ repo_path,
447
+ & format ! ( "git remote add someremote {remote_path}" ) [ ..] ,
448
+ ) ;
449
+
450
+ let mut config = repo. config ( ) . unwrap ( ) ;
451
+
452
+ config
453
+ . set_str ( "branch.master.remote" , "branchremote" )
454
+ . unwrap ( ) ;
455
+
456
+ let default_fetch_remote =
457
+ get_default_remote_for_fetch_in_repo ( & repo) ;
458
+
459
+ assert ! (
460
+ matches!( default_fetch_remote, Ok ( remote_name) if remote_name == "branchremote" )
461
+ ) ;
462
+ }
463
+
386
464
#[ test]
387
465
fn test_default_remote_for_push ( ) {
388
466
let ( remote_dir, _remote) = repo_init ( ) . unwrap ( ) ;
0 commit comments