Skip to content

Commit 80c98b3

Browse files
committed
Use gitoxide in get_branches_info
1 parent d9c94cf commit 80c98b3

File tree

1 file changed

+97
-61
lines changed
  • asyncgit/src/sync/branch

1 file changed

+97
-61
lines changed

asyncgit/src/sync/branch/mod.rs

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ use super::{utils::bytes2string, RepoPath};
99
use crate::{
1010
error::{Error, Result},
1111
sync::{
12-
remotes::get_default_remote_for_push_in_repo,
12+
gix_repo, remotes::get_default_remote_for_push_in_repo,
1313
repository::repo, utils::get_head_repo, CommitId,
1414
},
1515
};
1616
use git2::{Branch, BranchType, Repository};
17+
use gix::remote::Direction;
1718
use scopetime::scope_time;
1819
use std::collections::HashSet;
1920

@@ -123,76 +124,111 @@ pub fn get_branches_info(
123124
) -> Result<Vec<BranchInfo>> {
124125
scope_time!("get_branches_info");
125126

126-
let repo = repo(repo_path)?;
127+
let gix_repo = gix_repo(repo_path)?;
128+
let platform = gix_repo.references()?;
129+
let head_name = gix_repo.head_name().ok().flatten();
130+
131+
let mut branches_for_display: Vec<_> = if local {
132+
platform
133+
.local_branches()?
134+
.flatten()
135+
.filter_map(|mut branch| {
136+
let branch_name = branch.name();
137+
let name = branch_name.shorten().to_string();
138+
let reference = branch_name.to_owned().to_string();
139+
// TODO:
140+
// Verify that this is sufficiently similar to `git2`’s `is_head` by looking at the
141+
// implementation of `git_branch_is_head`.
142+
let is_head =
143+
head_name.as_ref().is_some_and(|head_name| {
144+
head_name.as_ref() == branch_name
145+
});
146+
147+
let top_commit = branch.peel_to_commit().ok()?;
148+
let upstream = branch.remote_tracking_ref_name(
149+
// TODO:
150+
// Is that correct?
151+
Direction::Fetch,
152+
);
153+
154+
let upstream_branch = match upstream {
155+
Some(Ok(reference)) => Some(UpstreamBranch {
156+
reference: reference.into_owned().to_string(),
157+
}),
158+
_ => None,
159+
};
160+
161+
let remote = branch
162+
.remote_name(
163+
// TODO:
164+
// Is that correct?
165+
Direction::Fetch,
166+
)
167+
.map(|name| name.as_bstr().to_string());
168+
169+
let details = BranchDetails::Local(LocalBranch {
170+
is_head,
171+
has_upstream: upstream_branch.is_some(),
172+
upstream: upstream_branch,
173+
remote,
174+
});
127175

128-
let (filter, remotes_with_tracking) = if local {
129-
(BranchType::Local, HashSet::default())
176+
Some(BranchInfo {
177+
name,
178+
reference,
179+
top_commit_message: top_commit
180+
.message()
181+
.ok()?
182+
.title
183+
.to_string(),
184+
top_commit: top_commit.into(),
185+
details,
186+
})
187+
})
188+
.collect()
130189
} else {
131-
let remotes: HashSet<_> = repo
132-
.branches(Some(BranchType::Local))?
133-
.filter_map(|b| {
134-
let branch = b.ok()?.0;
135-
let upstream = branch.upstream();
136-
upstream
137-
.ok()?
138-
.name_bytes()
139-
.ok()
140-
.map(ToOwned::to_owned)
190+
let remotes_with_tracking: HashSet<_> = platform
191+
.local_branches()?
192+
.flatten()
193+
.filter_map(|branch| {
194+
let upstream = branch.remote_tracking_ref_name(
195+
// TODO:
196+
// Is that correct?
197+
Direction::Fetch,
198+
)?;
199+
Some(upstream.ok()?.into_owned())
141200
})
142201
.collect();
143-
(BranchType::Remote, remotes)
144-
};
145-
146-
let mut branches_for_display: Vec<BranchInfo> = repo
147-
.branches(Some(filter))?
148-
.map(|b| {
149-
let branch = b?.0;
150-
let top_commit = branch.get().peel_to_commit()?;
151-
let reference = bytes2string(branch.get().name_bytes())?;
152-
let upstream = branch.upstream();
153-
154-
let remote = repo
155-
.branch_upstream_remote(&reference)
156-
.ok()
157-
.as_ref()
158-
.and_then(git2::Buf::as_str)
159-
.map(String::from);
160202

161-
let name_bytes = branch.name_bytes()?;
203+
platform
204+
.remote_branches()?
205+
.flatten()
206+
.filter_map(|mut branch| {
207+
let branch_name = branch.name();
208+
let name = branch_name.shorten().to_string();
209+
let reference = branch_name.to_owned().to_string();
162210

163-
let upstream_branch =
164-
upstream.ok().and_then(|upstream| {
165-
bytes2string(upstream.get().name_bytes())
166-
.ok()
167-
.map(|reference| UpstreamBranch { reference })
211+
let details = BranchDetails::Remote(RemoteBranch {
212+
has_tracking: remotes_with_tracking
213+
.contains(branch_name),
168214
});
169215

170-
let details = if local {
171-
BranchDetails::Local(LocalBranch {
172-
is_head: branch.is_head(),
173-
has_upstream: upstream_branch.is_some(),
174-
upstream: upstream_branch,
175-
remote,
216+
let top_commit = branch.peel_to_commit().ok()?;
217+
218+
Some(BranchInfo {
219+
name,
220+
reference,
221+
top_commit_message: top_commit
222+
.message()
223+
.ok()?
224+
.title
225+
.to_string(),
226+
top_commit: top_commit.into(),
227+
details,
176228
})
177-
} else {
178-
BranchDetails::Remote(RemoteBranch {
179-
has_tracking: remotes_with_tracking
180-
.contains(name_bytes),
181-
})
182-
};
183-
184-
Ok(BranchInfo {
185-
name: bytes2string(name_bytes)?,
186-
reference,
187-
top_commit_message: bytes2string(
188-
top_commit.summary_bytes().unwrap_or_default(),
189-
)?,
190-
top_commit: top_commit.id().into(),
191-
details,
192229
})
193-
})
194-
.filter_map(Result::ok)
195-
.collect();
230+
.collect()
231+
};
196232

197233
branches_for_display.sort_by(|a, b| a.name.cmp(&b.name));
198234

0 commit comments

Comments
 (0)