From: Josh Steadmon <steadmon@google.com>
To: git@vger.kernel.org
Cc: calvinwan@google.com, spectral@google.com,
emilyshaffer@google.com, emrass@google.com,
rsbecker@nexbridge.com, gitster@pobox.com, mh@glandium.org,
sandals@crustytoothpaste.net, Jason@zx2c4.com,
dsimic@manjaro.org
Subject: [PATCH v2 0/5] Introduce cgit-rs, a Rust wrapper around libgit.a
Date: Fri, 9 Aug 2024 15:41:12 -0700 [thread overview]
Message-ID: <cover.1723242556.git.steadmon@google.com> (raw)
In-Reply-To: <cover.1723054623.git.steadmon@google.com>
This series provides two small Rust wrapper libraries around parts of
Git: "cgit-sys", which exposes a few functions from libgit.a, and
"cgit", which provides a more Rust-friendly interface to some of those
functions. In addition to included unit tests, at $DAYJOB we have tested
building JJ[1] with our library and used it to replace some of the
libgit2-rs uses.
[1] https://github.com/martinvonz/jj
Please find V1 cover letter here:
https://lore.kernel.org/git/cover.1723054623.git.steadmon@google.com/
Changes in V2:
* Split out the exposed C APIs into a cgit-sys module, and build nicer
Rust interfaces on top of that in cgit-rs
* Replace the proof-of-concept cgit-info binary with unit tests
* In addition to splitting common_exit() into a new file, also move the
initialization code in main() to a new init_git() function in its own
file, and include this in libgit.a. This allows us to drop V1 patch #2
[which added a wrapper around initialize_repo()]
* Remove libc dependency (by declaring an extern "C" free function, not
sure if this is the best approach)
* Add git_configset_clear_and_free to also support the above
* Use "std::env::home_dir" instead of the "home" crate due to desired
behavior on Windows. "std::env::home_dir" is deprecated, but is only
used in unit tests which will need to be rewritten anyway to provide a
testdata config.
* Use recommended empty array + PhantomData approach instead of empty
enums for wrapping opaque C structs/pointers
* Don't force CC=clang in build.rs
* Simplify conversion of PathBufs to Strings in build.rs
* Don't unnecessarily expose git_attr__true and git_attr__false in
public_symbol_export.c. That fixes `make sparse`.
* Clippy and rustfmt cleanups throughout
* Whitespace fix
Known NEEDSWORK:
* Support older Rust versions
* Investigate alternative methods of managing symbol visibility.
* Figure out symbol versioning
* Bikeshed on the name
* Makefile cleanup, particularly adding config.mak options that
developers can set to run Rust builds and tests by default
* Automate the process of exporting additional functions in cgit-sys
(possibly with a wrapper script around bindgen)
* Provide testdata configs for unit tests
* Rethink the Rust-y ConfigSet API, particularly for Path vs. &str
Calvin Wan (2):
contrib/cgit-rs: add repo initialization and config access
contrib/cgit-rs: add a subset of configset wrappers
Josh Steadmon (3):
common-main: split init and exit code into new files
contrib/cgit-rs: introduce Rust wrapper for libgit.a
config: add git_configset_alloc() and git_configset_clear_and_free()
.gitignore | 2 +
Makefile | 15 +++
common-exit.c | 26 ++++
common-init.c | 63 ++++++++++
common-init.h | 6 +
common-main.c | 83 +------------
config.c | 11 ++
config.h | 10 ++
contrib/cgit-rs/Cargo.lock | 14 +++
contrib/cgit-rs/Cargo.toml | 10 ++
contrib/cgit-rs/cgit-sys/Cargo.lock | 7 ++
contrib/cgit-rs/cgit-sys/Cargo.toml | 9 ++
contrib/cgit-rs/cgit-sys/README.md | 15 +++
contrib/cgit-rs/cgit-sys/build.rs | 32 +++++
.../cgit-rs/cgit-sys/public_symbol_export.c | 76 ++++++++++++
.../cgit-rs/cgit-sys/public_symbol_export.h | 28 +++++
contrib/cgit-rs/cgit-sys/src/lib.rs | 112 ++++++++++++++++++
contrib/cgit-rs/src/lib.rs | 82 +++++++++++++
18 files changed, 520 insertions(+), 81 deletions(-)
create mode 100644 common-exit.c
create mode 100644 common-init.c
create mode 100644 common-init.h
create mode 100644 contrib/cgit-rs/Cargo.lock
create mode 100644 contrib/cgit-rs/Cargo.toml
create mode 100644 contrib/cgit-rs/cgit-sys/Cargo.lock
create mode 100644 contrib/cgit-rs/cgit-sys/Cargo.toml
create mode 100644 contrib/cgit-rs/cgit-sys/README.md
create mode 100644 contrib/cgit-rs/cgit-sys/build.rs
create mode 100644 contrib/cgit-rs/cgit-sys/public_symbol_export.c
create mode 100644 contrib/cgit-rs/cgit-sys/public_symbol_export.h
create mode 100644 contrib/cgit-rs/cgit-sys/src/lib.rs
create mode 100644 contrib/cgit-rs/src/lib.rs
Range-diff against v1:
1: 78c2aa2ef9 ! 1: 800b37d16b common-main: split common_exit() into a new file
@@ Metadata
Author: Josh Steadmon <steadmon@google.com>
## Commit message ##
- common-main: split common_exit() into a new file
+ common-main: split init and exit code into new files
Currently, object files in libgit.a reference common_exit(), which is
contained in common-main.o. However, common-main.o also includes main(),
@@ Commit message
conflicts. Now we are trying to make libgit.a more self-contained, so
hopefully we can revisit this approach.
+ Additionally, move the initialization code out of main() into a new
+ init_git() function in its own file. Include this in libgit.a as well,
+ so that external users can share our setup code without calling our
+ main().
+
[1] https://lore.kernel.org/git/Yp+wjCPhqieTku3X@google.com/
[2] https://lore.kernel.org/git/20230517-unit-tests-v2-v2-1-21b5b60f4b32@google.com/
- Signed-off-by: Josh Steadmon <steadmon@google.com>
-
## Makefile ##
@@ Makefile: LIB_OBJS += combine-diff.o
LIB_OBJS += commit-reach.o
LIB_OBJS += commit.o
+LIB_OBJS += common-exit.o
++LIB_OBJS += common-init.o
LIB_OBJS += compat/nonblock.o
LIB_OBJS += compat/obstack.o
LIB_OBJS += compat/terminal.o
@@ common-exit.c (new)
+ return code;
+}
+ ## common-init.c (new) ##
+@@
++#define USE_THE_REPOSITORY_VARIABLE
++
++#include "git-compat-util.h"
++#include "common-init.h"
++#include "exec-cmd.h"
++#include "gettext.h"
++#include "attr.h"
++#include "repository.h"
++#include "setup.h"
++#include "strbuf.h"
++#include "trace2.h"
++
++/*
++ * Many parts of Git have subprograms communicate via pipe, expect the
++ * upstream of a pipe to die with SIGPIPE when the downstream of a
++ * pipe does not need to read all that is written. Some third-party
++ * programs that ignore or block SIGPIPE for their own reason forget
++ * to restore SIGPIPE handling to the default before spawning Git and
++ * break this carefully orchestrated machinery.
++ *
++ * Restore the way SIGPIPE is handled to default, which is what we
++ * expect.
++ */
++static void restore_sigpipe_to_default(void)
++{
++ sigset_t unblock;
++
++ sigemptyset(&unblock);
++ sigaddset(&unblock, SIGPIPE);
++ sigprocmask(SIG_UNBLOCK, &unblock, NULL);
++ signal(SIGPIPE, SIG_DFL);
++}
++
++void init_git(const char **argv)
++{
++ struct strbuf tmp = STRBUF_INIT;
++
++ trace2_initialize_clock();
++
++ /*
++ * Always open file descriptors 0/1/2 to avoid clobbering files
++ * in die(). It also avoids messing up when the pipes are dup'ed
++ * onto stdin/stdout/stderr in the child processes we spawn.
++ */
++ sanitize_stdfds();
++ restore_sigpipe_to_default();
++
++ git_resolve_executable_dir(argv[0]);
++
++ setlocale(LC_CTYPE, "");
++ git_setup_gettext();
++
++ initialize_repository(the_repository);
++
++ attr_start();
++
++ trace2_initialize();
++ trace2_cmd_start(argv);
++ trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
++
++ if (!strbuf_getcwd(&tmp))
++ tmp_original_cwd = strbuf_detach(&tmp, NULL);
++}
+
+ ## common-init.h (new) ##
+@@
++#ifndef COMMON_INIT_H
++#define COMMON_INIT_H
++
++void init_git(const char **argv);
++
++#endif /* COMMON_INIT_H */
+
## common-main.c ##
-@@ common-main.c: int main(int argc, const char **argv)
+@@
+-#define USE_THE_REPOSITORY_VARIABLE
+-
+ #include "git-compat-util.h"
+-#include "exec-cmd.h"
+-#include "gettext.h"
+-#include "attr.h"
+-#include "repository.h"
+-#include "setup.h"
+-#include "strbuf.h"
+-#include "trace2.h"
+-
+-/*
+- * Many parts of Git have subprograms communicate via pipe, expect the
+- * upstream of a pipe to die with SIGPIPE when the downstream of a
+- * pipe does not need to read all that is written. Some third-party
+- * programs that ignore or block SIGPIPE for their own reason forget
+- * to restore SIGPIPE handling to the default before spawning Git and
+- * break this carefully orchestrated machinery.
+- *
+- * Restore the way SIGPIPE is handled to default, which is what we
+- * expect.
+- */
+-static void restore_sigpipe_to_default(void)
+-{
+- sigset_t unblock;
+-
+- sigemptyset(&unblock);
+- sigaddset(&unblock, SIGPIPE);
+- sigprocmask(SIG_UNBLOCK, &unblock, NULL);
+- signal(SIGPIPE, SIG_DFL);
+-}
++#include "common-init.h"
+
+ int main(int argc, const char **argv)
+ {
+ int result;
+- struct strbuf tmp = STRBUF_INIT;
+-
+- trace2_initialize_clock();
+-
+- /*
+- * Always open file descriptors 0/1/2 to avoid clobbering files
+- * in die(). It also avoids messing up when the pipes are dup'ed
+- * onto stdin/stdout/stderr in the child processes we spawn.
+- */
+- sanitize_stdfds();
+- restore_sigpipe_to_default();
+-
+- git_resolve_executable_dir(argv[0]);
+-
+- setlocale(LC_CTYPE, "");
+- git_setup_gettext();
+-
+- initialize_repository(the_repository);
+-
+- attr_start();
+-
+- trace2_initialize();
+- trace2_cmd_start(argv);
+- trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
+-
+- if (!strbuf_getcwd(&tmp))
+- tmp_original_cwd = strbuf_detach(&tmp, NULL);
+
++ init_git(argv);
+ result = cmd_main(argc, argv);
+
/* Not exit(3), but a wrapper calling our common_exit() */
exit(result);
}
2: 5f2e816cf6 < -: ---------- repository: add initialize_repo wrapper without pointer
3: 9a846c17c8 ! 2: 3589d2d6a2 contrib/cgit-rs: introduce Rust wrapper for libgit.a
@@ Commit message
Co-authored-by: Josh Steadmon <steadmon@google.com>
Signed-off-by: Calvin Wan <calvinwan@google.com>
Signed-off-by: Kyle Lippincott <spectral@google.com>
- Signed-off-by: Josh Steadmon <steadmon@google.com>
-
## .gitignore ##
@@ .gitignore: Release/
/git.VC.db
*.dSYM
/contrib/buildsystems/out
-+/contrib/cgit-rs/target
++/contrib/cgit-rs/cgit-sys/target
## Makefile ##
@@ Makefile: CURL_CONFIG = curl-config
@@ Makefile: OBJECTS += $(XDIFF_OBJS)
OBJECTS += $(FUZZ_OBJS)
OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS)
OBJECTS += $(UNIT_TEST_OBJS)
-+OBJECTS += contrib/cgit-rs/public_symbol_export.o
++OBJECTS += contrib/cgit-rs/cgit-sys/public_symbol_export.o
ifndef NO_CURL
OBJECTS += http.o http-walker.o remote-curl.o
@@ Makefile: clean: profile-clean coverage-clean cocciclean
$(RM) $(htmldocs).tar.gz $(manpages).tar.gz
$(MAKE) -C Documentation/ clean
$(RM) Documentation/GIT-EXCLUDED-PROGRAMS
-+ $(RM) -r contrib/cgit-rs/target
++ $(RM) -r contrib/cgit-rs/cgit-sys/target
ifndef NO_PERL
$(RM) -r perl/build/
endif
@@ Makefile: $(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o \
unit-tests: $(UNIT_TEST_PROGS) t/helper/test-tool$X
$(MAKE) -C t/ unit-tests
+
-+contrib/cgit-rs/partial_symbol_export.o: contrib/cgit-rs/public_symbol_export.o libgit.a reftable/libreftable.a xdiff/lib.a
++contrib/cgit-rs/cgit-sys/partial_symbol_export.o: contrib/cgit-rs/cgit-sys/public_symbol_export.o libgit.a reftable/libreftable.a xdiff/lib.a
+ $(LD) -r $^ -o $@
+
-+contrib/cgit-rs/hidden_symbol_export.o: contrib/cgit-rs/partial_symbol_export.o
++contrib/cgit-rs/cgit-sys/hidden_symbol_export.o: contrib/cgit-rs/cgit-sys/partial_symbol_export.o
+ $(OBJCOPY) --localize-hidden $^ $@
+
-+contrib/cgit-rs/libcgit.a: contrib/cgit-rs/hidden_symbol_export.o
++contrib/cgit-rs/cgit-sys/libcgit.a: contrib/cgit-rs/cgit-sys/hidden_symbol_export.o
+ $(AR) $(ARFLAGS) $@ $^
- ## contrib/cgit-rs/Cargo.lock (new) ##
+ ## contrib/cgit-rs/cgit-sys/Cargo.lock (new) ##
@@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
-+name = "cgit"
++name = "cgit-sys"
+version = "0.1.0"
-+dependencies = [
-+ "libc",
-+]
-+
-+[[package]]
-+name = "libc"
-+version = "0.2.155"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
- ## contrib/cgit-rs/Cargo.toml (new) ##
+ ## contrib/cgit-rs/cgit-sys/Cargo.toml (new) ##
@@
+[package]
-+name = "cgit"
++name = "cgit-sys"
+version = "0.1.0"
+edition = "2021"
+build = "build.rs"
+links = "git"
+
-+[[bin]]
-+name = "cgit-test"
-+path = "src/main.rs"
-+
+[lib]
+path = "src/lib.rs"
-+
-+[dependencies]
-+libc = "0.2.155"
- ## contrib/cgit-rs/README.md (new) ##
+ ## contrib/cgit-rs/cgit-sys/README.md (new) ##
@@
+# cgit-info
+
@@ contrib/cgit-rs/README.md (new)
+Assuming you don't make any changes to the Git source, you can just work from
+`contrib/cgit-rs` and use `cargo build` or `cargo run` as usual.
- ## contrib/cgit-rs/build.rs (new) ##
+ ## contrib/cgit-rs/cgit-sys/build.rs (new) ##
@@
+use std::env;
+use std::path::PathBuf;
+
+pub fn main() -> std::io::Result<()> {
+ let crate_root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
-+ let git_root = crate_root.join("../..");
++ let git_root = crate_root.join("../../..");
+ let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+ let make_output = std::process::Command::new("make")
+ .env_remove("PROFILE")
+ .current_dir(git_root.clone())
-+ .args(&[
-+ "CC=clang",
++ .args([
+ "CFLAGS=-fvisibility=hidden",
-+ "contrib/cgit-rs/libcgit.a"
++ "contrib/cgit-rs/cgit-sys/libcgit.a",
+ ])
+ .output()
+ .expect("Make failed to run");
+ if !make_output.status.success() {
+ panic!(
-+ "Make failed:\n stdout = {}\n stderr = {}\n",
-+ String::from_utf8(make_output.stdout).unwrap(),
-+ String::from_utf8(make_output.stderr).unwrap()
++ "Make failed:\n stdout = {}\n stderr = {}\n",
++ String::from_utf8(make_output.stdout).unwrap(),
++ String::from_utf8(make_output.stderr).unwrap()
+ );
+ }
+ std::fs::copy(crate_root.join("libcgit.a"), dst.join("libcgit.a"))?;
-+ println!("cargo::rustc-link-search=native={}", dst.into_os_string().into_string().unwrap());
++ println!("cargo::rustc-link-search=native={}", dst.display());
+ println!("cargo::rustc-link-lib=cgit");
+ println!("cargo::rustc-link-lib=z");
-+ println!("cargo::rerun-if-changed={}", git_root.into_os_string().into_string().unwrap());
++ println!("cargo::rerun-if-changed={}", git_root.display());
+
+ Ok(())
+}
- ## contrib/cgit-rs/public_symbol_export.c (new) ##
+ ## contrib/cgit-rs/cgit-sys/public_symbol_export.c (new) ##
@@
+// Shim to publicly export Git symbols. These must be renamed so that the
+// original symbols can be hidden. Renaming these with a "libgit_" prefix also
+// avoid conflicts with other libraries such as libgit2.
+
-+#include "contrib/cgit-rs/public_symbol_export.h"
++#include "contrib/cgit-rs/cgit-sys/public_symbol_export.h"
+#include "version.h"
+
+#pragma GCC visibility push(default)
@@ contrib/cgit-rs/public_symbol_export.c (new)
+
+#pragma GCC visibility pop
- ## contrib/cgit-rs/public_symbol_export.h (new) ##
+ ## contrib/cgit-rs/cgit-sys/public_symbol_export.h (new) ##
@@
+#ifndef PUBLIC_SYMBOL_EXPORT_H
+#define PUBLIC_SYMBOL_EXPORT_H
@@ contrib/cgit-rs/public_symbol_export.h (new)
+
+#endif /* PUBLIC_SYMBOL_EXPORT_H */
- ## contrib/cgit-rs/src/lib.rs (new) ##
+ ## contrib/cgit-rs/cgit-sys/src/lib.rs (new) ##
@@
-+use libc::c_char;
++use std::ffi::c_char;
+
+extern "C" {
+ // From version.c
+ pub fn libgit_user_agent() -> *const c_char;
+ pub fn libgit_user_agent_sanitized() -> *const c_char;
+}
-
- ## contrib/cgit-rs/src/main.rs (new) ##
-@@
-+use std::ffi::CStr;
-+
-+fn main() {
-+ println!("Let's print some strings provided by Git");
-+ let c_buf = unsafe { cgit::libgit_user_agent() };
-+ let c_str = unsafe { CStr::from_ptr(c_buf) };
-+ println!("git_user_agent() = {:?}", c_str);
-+ println!("git_user_agent_sanitized() = {:?}",
-+ unsafe { CStr::from_ptr(cgit::libgit_user_agent_sanitized()) });
++
++#[cfg(test)]
++mod tests {
++ use std::ffi::CStr;
++
++ use super::*;
++
++ #[test]
++ fn user_agent_starts_with_git() {
++ let c_str = unsafe { CStr::from_ptr(libgit_user_agent()) };
++ let agent = c_str
++ .to_str()
++ .expect("User agent contains invalid UTF-8 data");
++ assert!(
++ agent.starts_with("git/"),
++ r#"Expected user agent to start with "git/", got: {}"#,
++ agent
++ );
++ }
++
++ #[test]
++ fn sanitized_user_agent_starts_with_git() {
++ let c_str = unsafe { CStr::from_ptr(libgit_user_agent_sanitized()) };
++ let agent = c_str
++ .to_str()
++ .expect("Sanitized user agent contains invalid UTF-8 data");
++ assert!(
++ agent.starts_with("git/"),
++ r#"Expected user agent to start with "git/", got: {}"#,
++ agent
++ );
++ }
+}
4: b84a8210a0 ! 3: 527780f816 contrib/cgit-rs: add repo initialization and config access
@@ Commit message
contrib/cgit-rs: add repo initialization and config access
Co-authored-by: Calvin Wan <calvinwan@google.com>
Signed-off-by: Calvin Wan <calvinwan@google.com>
- Signed-off-by: Josh Steadmon <steadmon@google.com>
- ## contrib/cgit-rs/public_symbol_export.c ##
+ ## contrib/cgit-rs/cgit-sys/public_symbol_export.c ##
@@
// original symbols can be hidden. Renaming these with a "libgit_" prefix also
// avoid conflicts with other libraries such as libgit2.
+#include "git-compat-util.h"
- #include "contrib/cgit-rs/public_symbol_export.h"
-+#include "attr.h"
+ #include "contrib/cgit-rs/cgit-sys/public_symbol_export.h"
++#include "common-init.h"
+#include "config.h"
+#include "setup.h"
#include "version.h"
++extern struct repository *the_repository;
++
#pragma GCC visibility push(default)
+const char *libgit_setup_git_directory(void)
@@ contrib/cgit-rs/public_symbol_export.c
+
+int libgit_config_get_int(const char *key, int *dest)
+{
-+ return git_config_get_int(key, dest);
++ return repo_config_get_int(the_repository, key, dest);
+}
+
-+void libgit_initialize_the_repository(void)
++void libgit_init_git(const char **argv)
+{
-+ initialize_the_repository();
++ init_git(argv);
+}
+
+int libgit_parse_maybe_bool(const char *val)
@@ contrib/cgit-rs/public_symbol_export.c
const char *libgit_user_agent(void)
{
return git_user_agent();
-@@ contrib/cgit-rs/public_symbol_export.c: const char *libgit_user_agent_sanitized(void)
- return git_user_agent_sanitized();
- }
-
-+const char *libgit_attr__true = git_attr__true;
-+const char *libgit_attr__false = git_attr__false;
-+
- #pragma GCC visibility pop
- ## contrib/cgit-rs/public_symbol_export.h ##
+ ## contrib/cgit-rs/cgit-sys/public_symbol_export.h ##
@@
#ifndef PUBLIC_SYMBOL_EXPORT_H
#define PUBLIC_SYMBOL_EXPORT_H
@@ contrib/cgit-rs/public_symbol_export.h
+
+int libgit_config_get_int(const char *key, int *dest);
+
-+void libgit_initialize_the_repository(void);
++void libgit_init_git(const char **argv);
+
+int libgit_parse_maybe_bool(const char *val);
+
@@ contrib/cgit-rs/public_symbol_export.h
const char *libgit_user_agent_sanitized(void);
- ## contrib/cgit-rs/src/lib.rs ##
+ ## contrib/cgit-rs/cgit-sys/src/lib.rs ##
@@
--use libc::c_char;
-+use libc::{c_char, c_int};
+-use std::ffi::c_char;
++use std::ffi::{c_char, c_int};
extern "C" {
+ pub fn libgit_setup_git_directory() -> *const c_char;
+
+ // From config.c
-+ pub fn libgit_config_get_int(key: *const c_char, dest: *mut c_int) ->c_int;
++ pub fn libgit_config_get_int(key: *const c_char, dest: *mut c_int) -> c_int;
+
-+ // From repository.c
-+ pub fn libgit_initialize_the_repository();
++ // From common-init.c
++ pub fn libgit_init_git(argv: *const *const c_char);
+
+ // From parse.c
+ pub fn libgit_parse_maybe_bool(val: *const c_char) -> c_int;
@@ contrib/cgit-rs/src/lib.rs
// From version.c
pub fn libgit_user_agent() -> *const c_char;
pub fn libgit_user_agent_sanitized() -> *const c_char;
-
- ## contrib/cgit-rs/src/main.rs ##
-@@
--use std::ffi::CStr;
-+use std::ffi::{CStr, CString};
+@@ contrib/cgit-rs/cgit-sys/src/lib.rs: extern "C" {
- fn main() {
- println!("Let's print some strings provided by Git");
-@@ contrib/cgit-rs/src/main.rs: fn main() {
- println!("git_user_agent() = {:?}", c_str);
- println!("git_user_agent_sanitized() = {:?}",
- unsafe { CStr::from_ptr(cgit::libgit_user_agent_sanitized()) });
-+
-+ println!("\nNow try passing args");
-+ let test_arg = CString::new("test_arg").unwrap();
-+ println!("git_parse_maybe_bool(...) = {:?}",
-+ unsafe { cgit::libgit_parse_maybe_bool(test_arg.as_ptr()) });
-+
-+ println!("\nCan we get an int out of our config??");
-+ unsafe {
-+ cgit::libgit_initialize_the_repository();
-+ cgit::libgit_setup_git_directory();
-+ let mut val: libc::c_int = 0;
+ #[cfg(test)]
+ mod tests {
+- use std::ffi::CStr;
++ use std::ffi::{CStr, CString};
+
+ use super::*;
+
+@@ contrib/cgit-rs/cgit-sys/src/lib.rs: mod tests {
+ agent
+ );
+ }
++
++ #[test]
++ fn parse_bools_from_strings() {
++ let arg = CString::new("true").unwrap();
++ assert_eq!(unsafe { libgit_parse_maybe_bool(arg.as_ptr()) }, 1);
++
++ let arg = CString::new("yes").unwrap();
++ assert_eq!(unsafe { libgit_parse_maybe_bool(arg.as_ptr()) }, 1);
++
++ let arg = CString::new("false").unwrap();
++ assert_eq!(unsafe { libgit_parse_maybe_bool(arg.as_ptr()) }, 0);
++
++ let arg = CString::new("no").unwrap();
++ assert_eq!(unsafe { libgit_parse_maybe_bool(arg.as_ptr()) }, 0);
++
++ let arg = CString::new("maybe").unwrap();
++ assert_eq!(unsafe { libgit_parse_maybe_bool(arg.as_ptr()) }, -1);
++ }
++
++ #[test]
++ fn access_configs() {
++ // NEEDSWORK: we need to supply a testdata config
++ let fake_argv = [std::ptr::null::<c_char>()];
++ unsafe {
++ libgit_init_git(fake_argv.as_ptr());
++ libgit_setup_git_directory();
++ }
++ let mut val: c_int = 0;
+ let key = CString::new("trace2.eventNesting").unwrap();
-+ cgit::libgit_config_get_int(
-+ key.as_ptr(),
-+ &mut val as *mut i32
-+ );
-+ println!(
-+ "git_config_get_int(\"trace2.eventNesting\") -> {:?}",
-+ val
-+ );
-+ };
++ unsafe { libgit_config_get_int(key.as_ptr(), &mut val as *mut i32) };
++ assert_eq!(val, 5);
++ }
}
5: c8befb680e ! 4: 908ad0b82f config: add git_configset_alloc
@@ Metadata
Author: Josh Steadmon <steadmon@google.com>
## Commit message ##
- config: add git_configset_alloc
+ config: add git_configset_alloc() and git_configset_clear_and_free()
- Add git_configset_alloc so that non-C external consumers can use
- configset functions without redefining config_set.
+ Add git_configset_alloc() so that and git_configset_clear_and_free()
+ functions so that callers can manage config_set structs on the heap.
+ This also allows non-C external consumers to treat config_sets as opaque
+ structs.
Co-authored-by: Calvin Wan <calvinwan@google.com>
Signed-off-by: Calvin Wan <calvinwan@google.com>
- Signed-off-by: Josh Steadmon <steadmon@google.com>
-
+ Also add _clear_and_free
+
+
## config.c ##
@@ config.c: static int config_set_element_cmp(const void *cmp_data UNUSED,
return strcmp(e1->key, e2->key);
@@ config.c: static int config_set_element_cmp(const void *cmp_data UNUSED,
void git_configset_init(struct config_set *set)
{
hashmap_init(&set->config_hash, config_set_element_cmp, NULL, 0);
+@@ config.c: void git_configset_clear(struct config_set *set)
+ set->list.items = NULL;
+ }
+
++void git_configset_clear_and_free(struct config_set *set)
++{
++ git_configset_clear(set);
++ free(set);
++}
++
+ static int config_set_callback(const char *key, const char *value,
+ const struct config_context *ctx,
+ void *cb)
## config.h ##
@@ config.h: struct config_set {
@@ config.h: struct config_set {
/**
* Initializes the config_set `cs`.
*/
+@@ config.h: int git_configset_get_string_multi(struct config_set *cs, const char *key,
+ */
+ void git_configset_clear(struct config_set *cs);
+
++/**
++ * Clears and frees a heap-allocated `config_set` structure.
++ */
++void git_configset_clear_and_free(struct config_set *cs);
++
+ /*
+ * These functions return 1 if not found, and 0 if found, leaving the found
+ * value in the 'dest' pointer.
6: 1e981a6880 ! 5: 514c744ba4 contrib/cgit-rs: add a subset of configset wrappers
@@ Metadata
## Commit message ##
contrib/cgit-rs: add a subset of configset wrappers
Signed-off-by: Calvin Wan <calvinwan@google.com>
- Signed-off-by: Josh Steadmon <steadmon@google.com>
- ## contrib/cgit-rs/Cargo.lock ##
-@@ contrib/cgit-rs/Cargo.lock: version = 3
- name = "cgit"
- version = "0.1.0"
- dependencies = [
-+ "home",
- "libc",
- ]
-
-+[[package]]
-+name = "home"
-+version = "0.5.9"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
-+dependencies = [
-+ "windows-sys",
-+]
-+
- [[package]]
- name = "libc"
- version = "0.2.155"
- source = "registry+https://github.com/rust-lang/crates.io-index"
- checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
-+
-+[[package]]
-+name = "windows-sys"
-+version = "0.52.0"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-+dependencies = [
-+ "windows-targets",
-+]
+ ## .gitignore ##
+@@ .gitignore: Release/
+ /git.VC.db
+ *.dSYM
+ /contrib/buildsystems/out
++/contrib/cgit-rs/target
+ /contrib/cgit-rs/cgit-sys/target
+
+ ## Makefile ##
+@@ Makefile: clean: profile-clean coverage-clean cocciclean
+ $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
+ $(MAKE) -C Documentation/ clean
+ $(RM) Documentation/GIT-EXCLUDED-PROGRAMS
+- $(RM) -r contrib/cgit-rs/cgit-sys/target
++ $(RM) -r contrib/cgit-rs/target contrib/cgit-rs/cgit-sys/target
+ ifndef NO_PERL
+ $(RM) -r perl/build/
+ endif
+
+ ## contrib/cgit-rs/Cargo.lock (new) ##
+@@
++# This file is automatically @generated by Cargo.
++# It is not intended for manual editing.
++version = 3
+
+[[package]]
-+name = "windows-targets"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
++name = "cgit"
++version = "0.1.0"
+dependencies = [
-+ "windows_aarch64_gnullvm",
-+ "windows_aarch64_msvc",
-+ "windows_i686_gnu",
-+ "windows_i686_gnullvm",
-+ "windows_i686_msvc",
-+ "windows_x86_64_gnu",
-+ "windows_x86_64_gnullvm",
-+ "windows_x86_64_msvc",
++ "cgit-sys",
+]
+
+[[package]]
-+name = "windows_aarch64_gnullvm"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-+
-+[[package]]
-+name = "windows_aarch64_msvc"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-+
-+[[package]]
-+name = "windows_i686_gnu"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-+
-+[[package]]
-+name = "windows_i686_gnullvm"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-+
-+[[package]]
-+name = "windows_i686_msvc"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-+
-+[[package]]
-+name = "windows_x86_64_gnu"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
++name = "cgit-sys"
++version = "0.1.0"
+
+ ## contrib/cgit-rs/Cargo.toml (new) ##
+@@
++[package]
++name = "cgit"
++version = "0.1.0"
++edition = "2021"
+
-+[[package]]
-+name = "windows_x86_64_gnullvm"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
++[lib]
++path = "src/lib.rs"
+
-+[[package]]
-+name = "windows_x86_64_msvc"
-+version = "0.52.6"
-+source = "registry+https://github.com/rust-lang/crates.io-index"
-+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
++[dependencies]
++cgit-sys = { version = "0.1.0", path = "cgit-sys" }
- ## contrib/cgit-rs/Cargo.toml ##
-@@ contrib/cgit-rs/Cargo.toml: path = "src/lib.rs"
-
- [dependencies]
- libc = "0.2.155"
-+home = "0.5.9"
-
- ## contrib/cgit-rs/public_symbol_export.c ##
-@@ contrib/cgit-rs/public_symbol_export.c: int libgit_parse_maybe_bool(const char *val)
+ ## contrib/cgit-rs/cgit-sys/public_symbol_export.c ##
+@@ contrib/cgit-rs/cgit-sys/public_symbol_export.c: int libgit_parse_maybe_bool(const char *val)
return git_parse_maybe_bool(val);
}
@@ contrib/cgit-rs/public_symbol_export.c: int libgit_parse_maybe_bool(const char *
+ return git_configset_alloc();
+}
+
++void libgit_configset_clear_and_free(struct config_set *cs)
++{
++ git_configset_clear_and_free(cs);
++}
++
+void libgit_configset_init(struct config_set *cs)
+{
+ git_configset_init(cs);
@@ contrib/cgit-rs/public_symbol_export.c: int libgit_parse_maybe_bool(const char *
{
return git_user_agent();
- ## contrib/cgit-rs/public_symbol_export.h ##
-@@ contrib/cgit-rs/public_symbol_export.h: void libgit_initialize_the_repository(void);
+ ## contrib/cgit-rs/cgit-sys/public_symbol_export.h ##
+@@ contrib/cgit-rs/cgit-sys/public_symbol_export.h: void libgit_init_git(const char **argv);
int libgit_parse_maybe_bool(const char *val);
+struct config_set *libgit_configset_alloc(void);
+
++void libgit_configset_clear_and_free(struct config_set *cs);
++
+void libgit_configset_init(struct config_set *cs);
+
+int libgit_configset_add_file(struct config_set *cs, const char *filename);
@@ contrib/cgit-rs/public_symbol_export.h: void libgit_initialize_the_repository(vo
const char *libgit_user_agent_sanitized(void);
- ## contrib/cgit-rs/src/lib.rs ##
+ ## contrib/cgit-rs/cgit-sys/src/lib.rs ##
@@
--use libc::{c_char, c_int};
-+use std::ffi::{CStr, CString};
+-use std::ffi::{c_char, c_int};
++use std::ffi::{c_char, c_int, c_void};
++
++#[allow(non_camel_case_types)]
++#[repr(C)]
++pub struct config_set {
++ _data: [u8; 0],
++ _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
++}
+
+ extern "C" {
++ pub fn free(ptr: *mut c_void);
+
-+use libc::{c_char, c_int, c_void};
+ pub fn libgit_setup_git_directory() -> *const c_char;
+
+ // From config.c
+@@ contrib/cgit-rs/cgit-sys/src/lib.rs: extern "C" {
+ // From version.c
+ pub fn libgit_user_agent() -> *const c_char;
+ pub fn libgit_user_agent_sanitized() -> *const c_char;
+
-+pub enum GitConfigSet {}
++ pub fn libgit_configset_alloc() -> *mut config_set;
++ pub fn libgit_configset_clear_and_free(cs: *mut config_set);
+
-+pub struct ConfigSet(*mut GitConfigSet);
-+impl ConfigSet {
++ pub fn libgit_configset_init(cs: *mut config_set);
++
++ pub fn libgit_configset_add_file(cs: *mut config_set, filename: *const c_char) -> c_int;
++
++ pub fn libgit_configset_get_int(
++ cs: *mut config_set,
++ key: *const c_char,
++ int: *mut c_int,
++ ) -> c_int;
+
++ pub fn libgit_configset_get_string(
++ cs: *mut config_set,
++ key: *const c_char,
++ dest: *mut *mut c_char,
++ ) -> c_int;
++
+ }
+
+ #[cfg(test)]
+
+ ## contrib/cgit-rs/src/lib.rs (new) ##
+@@
++use std::ffi::{c_char, c_int, c_void, CStr, CString};
++
++use cgit_sys::*;
++
++pub struct ConfigSet(*mut config_set);
++impl ConfigSet {
+ pub fn new() -> Self {
+ unsafe {
-+ // TODO: we need to handle freeing this when the ConfigSet is dropped
-+ // git_configset_clear(ptr) and then libc::free(ptr)
+ let ptr = libgit_configset_alloc();
+ libgit_configset_init(ptr);
+ ConfigSet(ptr)
+ }
+ }
+
++ // NEEDSWORK: maybe replace &str with &Path
+ pub fn add_files(&mut self, files: &[&str]) {
+ for file in files {
+ let rs = CString::new(*file).expect("Couldn't convert to CString");
@@ contrib/cgit-rs/src/lib.rs
+ let key = CString::new(key).expect("Couldn't convert to CString");
+ let mut val: *mut c_char = std::ptr::null_mut();
+ unsafe {
-+ if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0 {
++ if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0
++ {
+ return None;
+ }
+ let borrowed_str = CStr::from_ptr(val);
+ let owned_str = CString::from_vec_with_nul(borrowed_str.to_bytes_with_nul().to_vec());
-+ libc::free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side
++ free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side
+ Some(owned_str.unwrap())
+ }
+ }
+}
-
- extern "C" {
- pub fn libgit_setup_git_directory() -> *const c_char;
-@@ contrib/cgit-rs/src/lib.rs: extern "C" {
- // From version.c
- pub fn libgit_user_agent() -> *const c_char;
- pub fn libgit_user_agent_sanitized() -> *const c_char;
-+
-+ fn libgit_configset_alloc() -> *mut GitConfigSet;
-+
-+ fn libgit_configset_init(cs: *mut GitConfigSet);
+
-+ fn libgit_configset_add_file(cs: *mut GitConfigSet, filename: *const c_char) -> c_int;
++impl Default for ConfigSet {
++ fn default() -> Self {
++ Self::new()
++ }
++}
+
-+ pub fn libgit_configset_get_int(cs: *mut GitConfigSet, key: *const c_char, int: *mut c_int) -> c_int;
-+ pub fn libgit_configset_get_string(cs: *mut GitConfigSet, key: *const c_char, dest: *mut *mut c_char) -> c_int;
++impl Drop for ConfigSet {
++ fn drop(&mut self) {
++ unsafe {
++ libgit_configset_clear_and_free(self.0);
++ }
++ }
++}
+
- }
-
- ## contrib/cgit-rs/src/main.rs ##
-@@
- use std::ffi::{CStr, CString};
-+use home::home_dir;
-
- fn main() {
- println!("Let's print some strings provided by Git");
-@@ contrib/cgit-rs/src/main.rs: fn main() {
- val
- );
- };
-+
-+ println!("\nTry out our configset wrappers");
-+ let mut cs = cgit::ConfigSet::new();
-+ let mut path = home_dir().expect("cannot get home directory path");
-+ path.push(".gitconfig");
-+ let path:String = path.into_os_string().into_string().unwrap();
-+ cs.add_files(&["/etc/gitconfig", ".gitconfig", &path]);
-+ /*
-+ * Returns Some(x) if defined in local config, otherwise None
-+ */
-+ println!("get_configset_get_int = {:?}", cs.get_int("trace2.eventNesting"));
-+ println!("cs.get_str(\"garbage\") = {:?}", cs.get_str("this_string_does_not_exist"));
- }
++#[cfg(test)]
++mod tests {
++ use super::*;
++
++ #[test]
++ fn load_configs_via_configset() {
++ // NEEDSWORK: we need to supply a testdata config
++ let mut cs = ConfigSet::new();
++ let mut path = std::env::home_dir().expect("cannot get home directory path");
++ path.push(".gitconfig");
++ let path: String = path.into_os_string().into_string().unwrap();
++ cs.add_files(&["/etc/gitconfig", ".gitconfig", &path]);
++ assert_eq!(cs.get_int("trace2.eventNesting"), Some(5));
++ assert_eq!(cs.get_str("no_such_config_item"), None);
++ }
++}
base-commit: 557ae147e6cdc9db121269b058c757ac5092f9c9
--
2.46.0.76.ge559c4bf1a-goog
next prev parent reply other threads:[~2024-08-09 22:41 UTC|newest]
Thread overview: 217+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-07 18:21 [RFC PATCH 0/6] [RFC] Introduce cgit-rs, a Rust wrapper around libgit.a Josh Steadmon
2024-08-07 18:21 ` [RFC PATCH 1/6] common-main: split common_exit() into a new file Josh Steadmon
2024-08-07 21:21 ` Junio C Hamano
2024-08-07 22:54 ` Josh Steadmon
2024-08-07 18:21 ` [RFC PATCH 2/6] repository: add initialize_repo wrapper without pointer Josh Steadmon
2024-08-07 22:52 ` Mike Hommey
2024-08-07 23:23 ` Josh Steadmon
2024-08-07 23:29 ` Mike Hommey
2024-08-08 17:50 ` Josh Steadmon
2024-08-07 18:21 ` [RFC PATCH 3/6] contrib/cgit-rs: introduce Rust wrapper for libgit.a Josh Steadmon
2024-08-07 21:21 ` brian m. carlson
2024-08-07 21:40 ` rsbecker
2024-08-07 23:07 ` Josh Steadmon
2024-08-07 23:51 ` rsbecker
2024-08-08 17:13 ` Josh Steadmon
2024-08-08 18:43 ` rsbecker
2024-08-08 19:57 ` Junio C Hamano
2024-08-08 20:14 ` rsbecker
2024-08-12 2:00 ` rsbecker
2024-08-07 23:05 ` Josh Steadmon
2024-08-07 23:55 ` brian m. carlson
2024-08-08 2:21 ` Junio C Hamano
2024-08-08 17:15 ` Josh Steadmon
2024-08-08 18:22 ` Josh Steadmon
2024-08-08 20:18 ` Kyle Lippincott
2024-08-08 20:43 ` Josh Steadmon
2024-08-07 22:47 ` Mike Hommey
2024-08-07 23:29 ` Josh Steadmon
2024-08-08 0:17 ` Mike Hommey
2024-08-08 17:23 ` Josh Steadmon
2024-08-07 18:21 ` [RFC PATCH 4/6] contrib/cgit-rs: add repo initialization and config access Josh Steadmon
2024-08-07 21:26 ` brian m. carlson
2024-08-07 23:14 ` Josh Steadmon
2024-08-08 0:04 ` brian m. carlson
2024-08-07 18:21 ` [RFC PATCH 5/6] config: add git_configset_alloc Josh Steadmon
2024-08-07 18:21 ` [RFC PATCH 6/6] contrib/cgit-rs: add a subset of configset wrappers Josh Steadmon
2024-08-07 21:40 ` brian m. carlson
2024-08-07 21:53 ` Junio C Hamano
2024-08-08 21:44 ` Josh Steadmon
2024-09-04 17:30 ` Calvin Wan
2024-09-04 17:49 ` brian m. carlson
2024-09-06 19:37 ` Calvin Wan
2024-09-07 14:53 ` brian m. carlson
2024-09-04 18:33 ` Junio C Hamano
2024-09-04 19:03 ` brian m. carlson
2024-09-04 21:08 ` Junio C Hamano
2024-09-04 21:29 ` Josh Steadmon
2024-08-07 22:03 ` [RFC PATCH 0/6] [RFC] Introduce cgit-rs, a Rust wrapper around libgit.a brian m. carlson
2024-08-07 23:19 ` Josh Steadmon
2024-08-08 1:33 ` brian m. carlson
2024-08-09 22:16 ` Josh Steadmon
2024-08-08 11:51 ` Jason A. Donenfeld
2024-08-08 13:59 ` Dragan Simic
2024-08-08 15:38 ` rsbecker
2024-08-08 15:47 ` Dragan Simic
2024-08-08 17:20 ` Junio C Hamano
2024-08-09 19:22 ` Junio C Hamano
2024-08-09 19:29 ` Junio C Hamano
2024-08-09 22:27 ` Josh Steadmon
2024-08-09 20:54 ` Junio C Hamano
2024-08-09 22:26 ` Junio C Hamano
2024-08-09 22:28 ` Josh Steadmon
2024-08-09 22:32 ` Junio C Hamano
2024-08-09 22:41 ` Josh Steadmon [this message]
2024-08-09 22:41 ` [PATCH v2 1/5] common-main: split init and exit code into new files Josh Steadmon
2024-08-09 22:41 ` [PATCH v2 2/5] cgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2024-08-09 22:41 ` [PATCH v2 3/5] cgit-sys: add repo initialization and config access Josh Steadmon
2024-08-09 22:41 ` [PATCH v2 4/5] config: add git_configset_alloc() and git_configset_clear_and_free() Josh Steadmon
2024-08-12 9:10 ` Phillip Wood
2024-08-12 21:39 ` Josh Steadmon
2024-08-12 21:55 ` Kyle Lippincott
2024-08-13 9:51 ` phillip.wood123
2024-08-13 15:16 ` Junio C Hamano
2024-08-13 9:48 ` phillip.wood123
2024-10-02 22:12 ` Josh Steadmon
2024-08-16 11:24 ` Patrick Steinhardt
2024-10-02 22:17 ` Josh Steadmon
2024-08-09 22:41 ` [PATCH v2 5/5] cgit: add higher-level cgit crate Josh Steadmon
2024-08-12 9:26 ` Phillip Wood
2024-08-21 18:46 ` Calvin Wan
2024-08-21 19:23 ` Kyle Lippincott
2024-08-22 13:24 ` Phillip Wood
2024-08-22 9:12 ` Phillip Wood
2024-10-02 22:31 ` Josh Steadmon
2024-08-09 23:36 ` [PATCH v2 0/5] Introduce cgit-rs, a Rust wrapper around libgit.a Junio C Hamano
2024-08-10 13:15 ` Jason A. Donenfeld
2024-08-11 17:26 ` Dragan Simic
2024-08-11 23:03 ` Eric Sunshine
2024-08-11 23:23 ` Dragan Simic
2024-08-11 23:33 ` Eric Sunshine
2024-08-11 23:37 ` Dragan Simic
2024-08-12 8:15 ` Junio C Hamano
2024-08-12 9:03 ` Eric Sunshine
2024-08-12 18:11 ` Junio C Hamano
2024-08-12 21:32 ` Josh Steadmon
2024-08-16 11:39 ` Patrick Steinhardt
2024-08-16 21:38 ` brian m. carlson
2024-08-17 0:15 ` Eric Sunshine
2024-08-18 1:37 ` Junio C Hamano
2024-08-12 22:14 ` brian m. carlson
2024-08-12 18:08 ` Dragan Simic
2024-08-12 21:24 ` Josh Steadmon
2024-08-12 21:37 ` Junio C Hamano
2024-08-12 22:02 ` Junio C Hamano
2024-09-06 22:18 ` [PATCH v3 0/6] Introduce libgit-rs, " Calvin Wan
2024-09-06 22:21 ` [PATCH v3 1/6] common-main: split init and exit code into new files Calvin Wan
2024-09-06 22:21 ` [PATCH v3 2/6] libgit-sys: introduce Rust wrapper for libgit.a Calvin Wan
2024-09-06 22:39 ` Eric Sunshine
2024-09-06 23:04 ` Mike Hommey
2024-09-08 21:32 ` Junio C Hamano
2024-09-18 21:14 ` Josh Steadmon
2024-09-10 19:04 ` Calvin Wan
2024-09-18 21:14 ` Josh Steadmon
2024-09-06 22:21 ` [PATCH v3 3/6] libgit-sys: add repo initialization and config access Calvin Wan
2024-09-06 22:53 ` Eric Sunshine
2024-09-18 21:33 ` Josh Steadmon
2024-09-06 23:45 ` Junio C Hamano
2024-09-18 21:33 ` Josh Steadmon
2024-09-10 6:42 ` Patrick Steinhardt
2024-10-07 21:21 ` Josh Steadmon
2024-10-08 20:59 ` Josh Steadmon
2024-09-06 22:21 ` [PATCH v3 4/6] config: add git_configset_alloc() and git_configset_clear_and_free() Calvin Wan
2024-09-06 23:24 ` Eric Sunshine
2024-09-10 6:41 ` Patrick Steinhardt
2024-09-10 8:50 ` Phillip Wood
2024-09-10 14:44 ` Junio C Hamano
2024-09-10 19:26 ` Calvin Wan
2024-10-02 22:45 ` Josh Steadmon
2024-09-06 22:21 ` [PATCH v3 5/6] libgit: add higher-level libgit crate Calvin Wan
2024-09-07 0:09 ` Junio C Hamano
2024-09-09 20:47 ` Junio C Hamano
2024-09-10 19:04 ` Calvin Wan
2024-09-10 19:14 ` Junio C Hamano
2024-09-17 22:29 ` Josh Steadmon
2024-09-18 16:34 ` Junio C Hamano
2024-10-07 23:31 ` Josh Steadmon
2024-09-17 21:37 ` Josh Steadmon
2024-09-06 22:21 ` [PATCH v3 6/6] Makefile: add option to build and test libgit-rs and libgit-rs-sys Calvin Wan
2024-09-07 15:15 ` Sean Allred
2024-09-08 21:33 ` Junio C Hamano
2024-09-10 19:12 ` Calvin Wan
2024-09-13 19:01 ` brian m. carlson
2024-10-07 21:23 ` Josh Steadmon
2024-10-02 22:49 ` Josh Steadmon
2024-10-08 23:19 ` [PATCH v4 0/5] Introduce libgit-rs, a Rust wrapper around libgit.a Josh Steadmon
2024-10-08 23:19 ` [PATCH v4 1/5] common-main: split init and exit code into new files Josh Steadmon
2024-10-08 23:19 ` [PATCH v4 2/5] libgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2024-10-08 23:19 ` [PATCH v4 3/5] libgit-sys: also export some config_set functions Josh Steadmon
2024-10-08 23:19 ` [PATCH v4 4/5] libgit: add higher-level libgit crate Josh Steadmon
2024-10-09 6:18 ` Eric Sunshine
2024-10-09 21:21 ` Josh Steadmon
2024-10-09 22:25 ` Josh Steadmon
2024-10-08 23:19 ` [PATCH v4 5/5] Makefile: add option to build and test libgit-rs and libgit-rs-sys Josh Steadmon
2024-10-08 23:45 ` Junio C Hamano
2024-10-09 0:12 ` rsbecker
2024-10-14 20:19 ` Josh Steadmon
2024-10-09 0:01 ` Junio C Hamano
2024-10-09 21:53 ` Josh Steadmon
2024-10-10 0:52 ` Junio C Hamano
2024-10-14 20:13 ` Josh Steadmon
2024-10-09 0:10 ` Junio C Hamano
2024-10-09 22:24 ` Josh Steadmon
2024-10-15 22:50 ` [PATCH v5 0/5] Introduce libgit-rs, a Rust wrapper around libgit.a Josh Steadmon
2024-10-15 22:50 ` [PATCH v5 1/5] common-main: split init and exit code into new files Josh Steadmon
2024-10-15 22:50 ` [PATCH v5 2/5] libgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2024-10-15 22:50 ` [PATCH v5 3/5] libgit-sys: also export some config_set functions Josh Steadmon
2024-10-15 22:50 ` [PATCH v5 4/5] libgit: add higher-level libgit crate Josh Steadmon
2024-10-15 22:50 ` [PATCH v5 5/5] Makefile: add option to build and test libgit-rs and libgit-rs-sys Josh Steadmon
2024-12-03 5:36 ` [PATCH v5 0/5] Introduce libgit-rs, a Rust wrapper around libgit.a Junio C Hamano
2025-01-15 20:05 ` [PATCH v6 " Josh Steadmon
2025-01-15 20:05 ` [PATCH v6 1/5] common-main: split init and exit code into new files Josh Steadmon
2025-01-15 22:40 ` Junio C Hamano
2025-01-16 2:46 ` Junio C Hamano
2025-01-16 21:02 ` Junio C Hamano
2025-01-17 9:44 ` Patrick Steinhardt
2025-01-21 23:21 ` Josh Steadmon
2025-01-15 20:05 ` [PATCH v6 2/5] libgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2025-01-15 23:13 ` Junio C Hamano
2025-01-22 0:03 ` Josh Steadmon
2025-01-27 23:18 ` Josh Steadmon
2025-01-15 20:05 ` [PATCH v6 3/5] libgit-sys: also export some config_set functions Josh Steadmon
2025-01-15 20:05 ` [PATCH v6 4/5] libgit: add higher-level libgit crate Josh Steadmon
2025-01-21 0:00 ` brian m. carlson
2025-01-22 0:01 ` Josh Steadmon
2025-01-15 20:05 ` [PATCH v6 5/5] Makefile: add option to build and test libgit-rs and libgit-rs-sys Josh Steadmon
2025-01-15 22:31 ` [PATCH v6 0/5] Introduce libgit-rs, a Rust wrapper around libgit.a Junio C Hamano
2025-01-21 0:05 ` brian m. carlson
2025-01-21 1:17 ` Junio C Hamano
2025-01-28 0:19 ` [PATCH v7 0/4] " Josh Steadmon
2025-01-28 0:19 ` [PATCH v7 1/4] common-main: split init and exit code into new files Josh Steadmon
2025-01-28 0:19 ` [PATCH v7 2/4] libgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2025-01-28 15:08 ` Phillip Wood
2025-01-28 20:26 ` Josh Steadmon
2025-01-28 20:44 ` Junio C Hamano
2025-01-28 0:19 ` [PATCH v7 3/4] libgit-sys: also export some config_set functions Josh Steadmon
2025-01-28 15:08 ` Phillip Wood
2025-01-28 20:47 ` Josh Steadmon
2025-01-28 0:19 ` [PATCH v7 4/4] libgit: add higher-level libgit crate Josh Steadmon
2025-01-28 4:56 ` Junio C Hamano
2025-01-28 20:50 ` Josh Steadmon
2025-01-28 21:17 ` Junio C Hamano
2025-01-28 22:01 ` [PATCH v8 0/4] Introduce libgit-rs, a Rust wrapper around libgit.a Josh Steadmon
2025-01-28 22:01 ` [PATCH v8 1/4] common-main: split init and exit code into new files Josh Steadmon
2025-01-28 22:01 ` [PATCH v8 2/4] libgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2025-01-28 22:43 ` Junio C Hamano
2025-01-29 21:40 ` Josh Steadmon
2025-01-28 22:01 ` [PATCH v8 3/4] libgit-sys: also export some config_set functions Josh Steadmon
2025-01-28 22:01 ` [PATCH v8 4/4] libgit: add higher-level libgit crate Josh Steadmon
2025-01-29 15:24 ` [PATCH v8 0/4] Introduce libgit-rs, a Rust wrapper around libgit.a Phillip Wood
2025-01-29 21:42 ` Josh Steadmon
2025-01-29 21:50 ` [PATCH v9 " Josh Steadmon
2025-01-29 21:50 ` [PATCH v9 1/4] common-main: split init and exit code into new files Josh Steadmon
2025-01-29 21:50 ` [PATCH v9 2/4] libgit-sys: introduce Rust wrapper for libgit.a Josh Steadmon
2025-01-29 21:50 ` [PATCH v9 3/4] libgit-sys: also export some config_set functions Josh Steadmon
2025-01-29 21:50 ` [PATCH v9 4/4] libgit: add higher-level libgit crate Josh Steadmon
2025-01-30 10:49 ` [PATCH v9 0/4] Introduce libgit-rs, a Rust wrapper around libgit.a phillip.wood123
2025-01-30 19:32 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1723242556.git.steadmon@google.com \
--to=steadmon@google.com \
--cc=Jason@zx2c4.com \
--cc=calvinwan@google.com \
--cc=dsimic@manjaro.org \
--cc=emilyshaffer@google.com \
--cc=emrass@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mh@glandium.org \
--cc=rsbecker@nexbridge.com \
--cc=sandals@crustytoothpaste.net \
--cc=spectral@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).