Skip to content

Commit 4ff0db9

Browse files
committed
Get default push remote from configuration
1 parent 21810a4 commit 4ff0db9

File tree

2 files changed

+99
-7
lines changed

2 files changed

+99
-7
lines changed

Diff for: asyncgit/src/sync/remotes/mod.rs

+94-5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,65 @@ pub fn get_default_remote(repo_path: &RepoPath) -> Result<String> {
5151
get_default_remote_in_repo(&repo)
5252
}
5353

54+
/// Gets the current branch the user is on.
55+
/// Returns none if they are not on a branch
56+
/// and Err if there was a problem finding the branch
57+
fn get_current_branch(
58+
repo: &Repository,
59+
) -> Result<Option<git2::Branch>> {
60+
for b in repo.branches(None)? {
61+
let branch = b?.0;
62+
if branch.is_head() {
63+
return Ok(Some(branch));
64+
}
65+
}
66+
Ok(None)
67+
}
68+
69+
/// Tries to find the default repo to push to based on configuration.
70+
///
71+
/// > remote.pushDefault
72+
/// >
73+
/// > The remote to push to by default. Overrides branch.<name>.remote for all branches, and is
74+
/// > overridden by branch.<name>.pushRemote for specific branches.
75+
///
76+
/// [git-config-remote-push-default]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-remotepushDefault
77+
///
78+
/// Falls back to `get_default_remote_in_repo`.
79+
pub fn get_default_remote_for_push(
80+
repo_path: &RepoPath,
81+
) -> Result<String> {
82+
let repo = repo(repo_path)?;
83+
get_default_remote_for_push_in_repo(&repo)
84+
}
85+
86+
pub(crate) fn get_default_remote_for_push_in_repo(
87+
repo: &Repository,
88+
) -> Result<String> {
89+
scope_time!("get_default_remote_for_push_in_repo");
90+
91+
let config = repo.config()?;
92+
93+
let branch = get_current_branch(repo)?;
94+
95+
if let Some(branch) = branch {
96+
let remote_name = bytes2string(branch.name_bytes()?)?;
97+
98+
let entry_name =
99+
format!("branch.{}.pushRemote", &remote_name);
100+
101+
if let Ok(entry) = config.get_entry(&entry_name) {
102+
return bytes2string(entry.value_bytes());
103+
}
104+
105+
if let Ok(entry) = config.get_entry("remote.pushDefault") {
106+
return bytes2string(entry.value_bytes());
107+
}
108+
}
109+
110+
get_default_remote_in_repo(repo)
111+
}
112+
54113
/// see `get_default_remote`
55114
pub(crate) fn get_default_remote_in_repo(
56115
repo: &Repository,
@@ -272,7 +331,7 @@ mod tests {
272331
fn test_default_remote_inconclusive() {
273332
let (remote_dir, _remote) = repo_init().unwrap();
274333
let remote_path = remote_dir.path().to_str().unwrap();
275-
let (repo_dir, _repo) = repo_clone(remote_path).unwrap();
334+
let (repo_dir, repo) = repo_clone(remote_path).unwrap();
276335
let repo_path: &RepoPath = &repo_dir
277336
.into_path()
278337
.as_os_str()
@@ -299,9 +358,39 @@ mod tests {
299358
]
300359
);
301360

302-
let res =
303-
get_default_remote_in_repo(&repo(repo_path).unwrap());
304-
assert_eq!(res.is_err(), true);
305-
assert!(matches!(res, Err(Error::NoDefaultRemoteFound)));
361+
let default_push_remote =
362+
get_default_remote_for_push_in_repo(&repo);
363+
364+
assert!(matches!(
365+
default_push_remote,
366+
Err(Error::NoDefaultRemoteFound)
367+
));
368+
369+
let mut config = repo.config().unwrap();
370+
371+
config
372+
.set_str("remote.pushDefault", "defaultreporemote")
373+
.unwrap();
374+
375+
let default_push_remote =
376+
get_default_remote_for_push_in_repo(&repo);
377+
378+
assert!(
379+
matches!(default_push_remote, Ok(remote_name) if remote_name == "defaultreporemote")
380+
);
381+
382+
config
383+
.set_str(
384+
"branch.master.pushRemote",
385+
"defaultbranchremote",
386+
)
387+
.unwrap();
388+
389+
let default_push_remote =
390+
get_default_remote_for_push_in_repo(&repo);
391+
392+
assert!(
393+
matches!(default_push_remote, Ok(remote_name) if remote_name == "defaultbranchremote")
394+
);
306395
}
307396
}

Diff for: src/popups/push.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use asyncgit::{
1616
extract_username_password, need_username_password,
1717
BasicAuthCredential,
1818
},
19-
get_branch_remote, get_default_remote, RepoPathRef,
19+
get_branch_remote,
20+
remotes::get_default_remote_for_push,
21+
RepoPathRef,
2022
},
2123
AsyncGitNotification, AsyncPush, PushRequest, PushType,
2224
RemoteProgress, RemoteProgressState,
@@ -132,7 +134,8 @@ impl PushPopup {
132134
remote
133135
} else {
134136
log::info!("push: branch '{}' has no upstream - looking up default remote",self.branch);
135-
let remote = get_default_remote(&self.repo.borrow())?;
137+
let remote =
138+
get_default_remote_for_push(&self.repo.borrow())?;
136139
log::info!(
137140
"push: branch '{}' to remote '{}'",
138141
self.branch,

0 commit comments

Comments
 (0)