Skip to content

Commit 3433353

Browse files
committed
remote: Update git_fetch_options to use RemoteUpdateFlags
This includes a hacky solution since the `update_flag` field uses C bitfields, which are not natively supported in Rust.
1 parent 6cb97bc commit 3433353

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

libgit2-sys/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ pub struct git_fetch_options {
398398
pub version: c_int,
399399
pub callbacks: git_remote_callbacks,
400400
pub prune: git_fetch_prune_t,
401-
pub update_fetchhead: c_int,
401+
pub update_flags: c_uint,
402402
pub download_tags: git_remote_autotag_option_t,
403403
pub proxy_opts: git_proxy_options,
404404
pub depth: c_int,

src/remote.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub struct FetchOptions<'cb> {
4444
depth: i32,
4545
proxy: Option<ProxyOptions<'cb>>,
4646
prune: FetchPrune,
47-
update_fetchhead: bool,
47+
update_flags: RemoteUpdateFlags,
4848
download_tags: AutotagOption,
4949
follow_redirects: RemoteRedirect,
5050
custom_headers: Vec<CString>,
@@ -507,7 +507,7 @@ impl<'cb> FetchOptions<'cb> {
507507
callbacks: None,
508508
proxy: None,
509509
prune: FetchPrune::Unspecified,
510-
update_fetchhead: true,
510+
update_flags: RemoteUpdateFlags::UPDATE_FETCHHEAD,
511511
download_tags: AutotagOption::Unspecified,
512512
follow_redirects: RemoteRedirect::Initial,
513513
custom_headers: Vec::new(),
@@ -538,7 +538,17 @@ impl<'cb> FetchOptions<'cb> {
538538
///
539539
/// Defaults to `true`.
540540
pub fn update_fetchhead(&mut self, update: bool) -> &mut Self {
541-
self.update_fetchhead = update;
541+
self.update_flags
542+
.set(RemoteUpdateFlags::UPDATE_FETCHHEAD, update);
543+
self
544+
}
545+
546+
/// Set whether to report unchanged tips in the update_tips callback.
547+
///
548+
/// Defaults to `false`.
549+
pub fn report_unchanged(&mut self, update: bool) -> &mut Self {
550+
self.update_flags
551+
.set(RemoteUpdateFlags::REPORT_UNCHANGED, update);
542552
self
543553
}
544554

@@ -603,7 +613,11 @@ impl<'cb> Binding for FetchOptions<'cb> {
603613
.map(|m| m.raw())
604614
.unwrap_or_else(|| ProxyOptions::new().raw()),
605615
prune: crate::call::convert(&self.prune),
606-
update_fetchhead: crate::call::convert(&self.update_fetchhead),
616+
// HACK: `libgit2` uses C bitfields, which do not have a guaranteed memory layout.
617+
// Reversing the bits ensures that the bitfields are set whether the bits are laid out
618+
// from left to right or right to left, but will not work on other memory layouts.
619+
update_flags: (self.update_flags.bits() | self.update_flags.bits().reverse_bits())
620+
as c_uint,
607621
download_tags: crate::call::convert(&self.download_tags),
608622
depth: self.depth,
609623
follow_redirects: self.follow_redirects.raw(),

systest/build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ fn main() {
2424
// this field is marked as const which ctest complains about
2525
(struct_ == "git_rebase_operation" && f == "id") ||
2626
// the real name of this field is ref but that is a reserved keyword
27-
(struct_ == "git_worktree_add_options" && f == "reference")
27+
(struct_ == "git_worktree_add_options" && f == "reference") ||
28+
// the `update_flags` field consists of 2 bitfields
29+
(struct_ == "git_fetch_options" && f == "update_flags")
2830
});
2931
cfg.skip_signededness(|s| match s {
3032
s if s.ends_with("_cb") => true,

0 commit comments

Comments
 (0)