Skip to content

Expose git_merge_file function from libgit2 to repo.rs of git2-rs #635

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions libgit2-sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_void, size_t};
#[cfg(feature = "ssh")]
use libssh2_sys as libssh2;
use std::ffi::CStr;
use std::os::raw::c_ushort;

pub const GIT_OID_RAWSZ: usize = 20;
pub const GIT_OID_HEXSZ: usize = GIT_OID_RAWSZ * 2;
Expand Down Expand Up @@ -3854,6 +3855,82 @@ extern "C" {
) -> c_int;
}

#[repr(C)]
pub struct git_merge_file_options {
pub version: c_uint,

/// Label for the ancestor file side of the conflict which will be prepended
/// to labels in diff3-format merge files.
pub ancestor_label: *const c_char,

/// Label for our file side of the conflict which will be prepended
/// to labels in merge files.
pub our_label: *const c_char,

/// Label for their file side of the conflict which will be prepended
/// to labels in merge files.
pub their_label: *const c_char,

/// The file to favor in region conflicts.
pub favor: git_merge_file_favor_t,

/// see `git_merge_file_flag_t`
pub flags: c_uint,
pub marker_size: c_ushort,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct git_merge_file_input {
pub version: c_uint,
/// Pointer to the contents of the file.
pub ptr: *const c_char,
/// Size of the contents pointed to in `ptr`.
pub size: size_t,
/// File name of the conflicted file, or `NULL` to not merge the path.
pub path: *const c_char,
/// File mode of the conflicted file, or `0` to not merge the mode.
pub mode: c_uint,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct git_merge_file_result {
/// True if the output was automerged, false if the output contains
/// conflict markers.
pub automergeable: c_uint,

/// The path that the resultant merge file should use, or NULL if a
/// filename conflict would occur.
pub path: *const c_char,

/// The mode that the resultant merge file should use.
pub mode: c_uint,

/// The contents of the merge.
pub ptr: *const c_char,

/// The length of the merge contents.
pub len: size_t,
}

extern "C" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this get merged (hah!) with the general block of function definitions elsewhere in this file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was worrying to make it mess at the beginning so they were put together, now they've been moved to the right places.

pub fn git_merge_file_options_init(opts: *mut git_merge_file_options, version: c_uint)
-> c_int;
pub fn git_merge_file_input_init(opts: *mut git_merge_file_input, version: c_uint) -> c_int;

pub fn git_merge_file(
out: *mut git_merge_file_result,
ancestor: *const git_merge_file_input,
ours: *const git_merge_file_input,
theirs: *const git_merge_file_input,
opts: *const git_merge_file_options,
) -> c_int;

// Not used?
pub fn git_merge_file_result_free(result: *mut git_merge_file_result);
}

pub fn init() {
use std::sync::Once;

Expand Down
32 changes: 31 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ pub use crate::index::{
};
pub use crate::indexer::{IndexerProgress, Progress};
pub use crate::mempack::Mempack;
pub use crate::merge::{AnnotatedCommit, MergeOptions};
pub use crate::merge::{
AnnotatedCommit, MergeFileInput, MergeFileOptions, MergeFileResult, MergeOptions,
};
pub use crate::message::{message_prettify, DEFAULT_COMMENT_CHAR};
pub use crate::note::{Note, Notes};
pub use crate::object::Object;
Expand Down Expand Up @@ -1049,6 +1051,34 @@ pub enum FileMode {
Commit,
}

impl From<u32> for FileMode {
fn from(mode: u32) -> Self {
match mode {
raw::GIT_FILEMODE_UNREADABLE => FileMode::Unreadable,
raw::GIT_FILEMODE_TREE => FileMode::Tree,
raw::GIT_FILEMODE_BLOB => FileMode::Blob,
raw::GIT_FILEMODE_BLOB_EXECUTABLE => FileMode::BlobExecutable,
raw::GIT_FILEMODE_LINK => FileMode::Link,
raw::GIT_FILEMODE_COMMIT => FileMode::Commit,
mode => panic!("unknown file mode: {}", mode),
}
}
}

impl Into<u32> for FileMode {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW this is typically phrase as From<FileMode> for u32, but if FileMode is an enum I think it would be better to set the discriminants to the raw::* values and that way enum_value as u32 should work for this purpose.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we don't need Into<u32> trait implementation but just use file_mode as u32 when needed?

fn into(self) -> u32 {
let ret = match self {
FileMode::Unreadable => raw::GIT_FILEMODE_UNREADABLE,
FileMode::Tree => raw::GIT_FILEMODE_TREE,
FileMode::Blob => raw::GIT_FILEMODE_BLOB,
FileMode::BlobExecutable => raw::GIT_FILEMODE_BLOB_EXECUTABLE,
FileMode::Link => raw::GIT_FILEMODE_LINK,
FileMode::Commit => raw::GIT_FILEMODE_COMMIT,
};
ret as u32
}
}

bitflags! {
/// Return codes for submodule status.
///
Expand Down
Loading