Skip to content

Commit

Permalink
Move store_git_tree to Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
glandium committed Jun 24, 2024
1 parent 0d42fe2 commit 8a165c6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 39 deletions.
20 changes: 4 additions & 16 deletions src/cinnabar-fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,23 +553,11 @@ void store_replace_map(struct object_id *result) {
strbuf_release(&buf);
}

void store_git_tree(struct strslice tree_buf, const struct object_id *reference,
struct object_id *result)
void unpack_object_entry(struct object_entry *oe, char **buf,
unsigned long *len)
{
struct object_entry *oe = NULL;
if (reference) {
oe = get_object_entry(reference);
}
if (oe) {
struct strslice ref_tree;
unsigned long len;
ref_tree.buf = gfi_unpack_entry(oe, &len);
ref_tree.len = len;
store_git_object(OBJ_TREE, tree_buf, result, &ref_tree, oe);
free((char*)ref_tree.buf);
} else {
store_git_object(OBJ_TREE, tree_buf, result, NULL, NULL);
}
// Note: ownership is given out.
*buf = gfi_unpack_entry(oe, len);
}

void store_git_object(enum object_type type, const struct strslice buf,
Expand Down
3 changes: 3 additions & 0 deletions src/cinnabar-fast-import.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ int maybe_handle_command(struct reader *helper_input, int helper_output,

struct object_entry *get_object_entry(const struct object_id *oid);

void unpack_object_entry(struct object_entry *oe, char **buf,
unsigned long *len);

void store_git_tree(struct strslice tree_buf,
const struct object_id *reference,
struct object_id *result);
Expand Down
56 changes: 33 additions & 23 deletions src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::io::{copy, BufRead, BufReader, Read, Write};
use std::iter::{repeat, IntoIterator};
use std::mem;
use std::num::NonZeroU32;
use std::os::raw::c_int;
use std::os::raw::{c_char, c_int, c_ulong};
use std::process::{Command, Stdio};
use std::ptr;
use std::sync::Mutex;
Expand Down Expand Up @@ -48,7 +48,7 @@ use crate::hg_data::{hash_data, GitAuthorship, HgAuthorship, HgCommitter};
use crate::libcinnabar::{git_notes_tree, hg_notes_tree, strslice, strslice_mut, AsStrSlice};
use crate::libgit::{
config_get_value, die, for_each_ref_in, get_oid_blob, object_entry, object_id, object_type,
resolve_ref, FileMode, RefTransaction,
resolve_ref, FfiBox, FileMode, RefTransaction,
};
use crate::oid::ObjectId;
use crate::progress::{progress_enabled, Progress};
Expand Down Expand Up @@ -1381,12 +1381,9 @@ fn store_changesets_metadata(store: &Store) -> CommitId {
tree.extend_from_slice(b"\0");
tree.extend_from_slice(blob.as_raw_bytes());
}
let mut tid = object_id::default();
unsafe {
store_git_tree(tree.as_str_slice(), std::ptr::null(), &mut tid);
}
let tid = store_git_tree(&tree, None);
let mut commit = Vec::new();
writeln!(commit, "tree {}", GitObjectId::from(tid)).ok();
writeln!(commit, "tree {}", tid).ok();
let heads = store.changeset_heads();
for (head, _) in heads.branch_heads() {
writeln!(commit, "parent {}", head.to_git(store).unwrap()).ok();
Expand Down Expand Up @@ -1431,7 +1428,6 @@ pub fn set_changeset_heads(store: &Store, new_heads: ChangesetHeads) {

extern "C" {
pub fn ensure_store_init();
fn store_git_tree(tree_buf: strslice, reference: *const object_id, result: *mut object_id);
fn store_git_object(
typ: object_type,
buf: strslice,
Expand All @@ -1441,6 +1437,7 @@ extern "C" {
);
pub fn do_set_replace(replaced: *const object_id, replace_with: *const object_id);
fn get_object_entry(oid: *const object_id) -> *const object_entry;
fn unpack_object_entry(oe: *const object_entry, buf: *mut *mut c_char, len: *mut c_ulong);
}

pub fn store_git_blob(blob_buf: &[u8]) -> BlobId {
Expand All @@ -1457,6 +1454,32 @@ pub fn store_git_blob(blob_buf: &[u8]) -> BlobId {
}
}

pub fn store_git_tree(tree_buf: &[u8], reference: Option<TreeId>) -> TreeId {
unsafe {
let mut oe = ptr::null();
let mut ref_tree = None;
if let Some(reference) = reference {
oe = get_object_entry(&reference.into());
if !oe.is_null() {
let mut reftree_buf = ptr::null_mut();
let mut len = 0;
unpack_object_entry(oe, &mut reftree_buf, &mut len);
ref_tree = Some(FfiBox::from_raw_parts(reftree_buf as *mut u8, len as usize));
}
}
let mut result = object_id::default();
let ref_tree = ref_tree.as_ref().map(|x| x.as_str_slice());
store_git_object(
object_type::OBJ_TREE,
tree_buf.as_str_slice(),
&mut result,
ref_tree.as_ref().map_or(ptr::null(), |x| x as *const _),
oe,
);
TreeId::from_unchecked(result.into())
}
}

pub fn store_git_commit(commit_buf: &[u8]) -> CommitId {
unsafe {
let mut result = object_id::default();
Expand Down Expand Up @@ -1653,16 +1676,7 @@ fn create_git_tree(
tree_buf.extend_from_slice(b"\0");
tree_buf.extend_from_slice(oid.as_raw_bytes());
}
let mut result = object_id::default();
let ref_tree = ref_tree_id.map(GitObjectId::from).map(object_id::from);
unsafe {
store_git_tree(
tree_buf.as_str_slice(),
ref_tree.as_ref().map_or(ptr::null(), |x| x as *const _),
&mut result,
);
}
let result = TreeId::from_unchecked(result.into());
let result = store_git_tree(&tree_buf, ref_tree_id);
if merge_tree_id.is_none() {
store
.tree_cache_
Expand All @@ -1686,11 +1700,7 @@ fn store_changeset(
.ok_or(GraftError::NoGraft)?;
let changeset = raw_changeset.parse().unwrap();
let manifest_tree_id = GitManifestTreeId::from_unchecked(match changeset.manifest() {
m if m.is_null() => unsafe {
let mut tid = object_id::default();
store_git_tree([].as_str_slice(), std::ptr::null(), &mut tid);
TreeId::from_unchecked(GitObjectId::from(tid))
},
m if m.is_null() => store_git_tree(&[], None),
m => {
let git_manifest_id = m.to_git(store).unwrap();
let manifest_commit = RawCommit::read(git_manifest_id.into()).unwrap();
Expand Down

0 comments on commit 8a165c6

Please sign in to comment.