git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v7 0/4] Introduce libgit-rs, a Rust wrapper around libgit.a

From
Josh Steadmon <steadmon@google.com>
Date
Jan 28, 2025, 00:19 UTC
Message-ID
<cover.1738023208.git.steadmon@google.com>
In-Reply-To
<cover.1723054623.git.steadmon@google.com>
This series provides two small Rust wrapper libraries around parts of
Git: "libgit-sys", which exposes a few functions from libgit.a, and
"libgit", 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/jj-vcs/jj

There is known NEEDSWORK, but I feel that they can be addressed in follow-up changes, rather than in this series. If you feel otherwise, please let me know:

* Investigate alternative methods of managing symbol visibility &
  renaming.
* Figure out symbol versioning
Changes in V7:
* Moved the ConfigSet implementation in libgit-rs to a `config` module.
* Added doc comments for ConfigSet and its methods.
* Fix meson builds by adding new object files to `libgit_sources`
* Moved INCLUDE_LIBGIT_RS Makefile changes earlier in the series, so
  that we can make it optional to compile some of the libgitpub sources.
  Squashed V6 patch 5/5 into this series' patch 4/4.
* Don't publicly export FFI types in libgit-rs.
* Removed extraneous `-r` argument to $(RM) in the clean rules.
* Added TODO reminder in Cargo.toml about removing Cargo.lock once we
  hit a certain minimum supported Rust version.
* Style cleanup in public_symbol_export.c
Changes in V6:
* Rebased onto current master, since V5 was several months old.
* Move libgit-sys out of libgit-rs; while this sort of nesting is common
  in Rust crates with standalone repositories, it doesn't make as much
  sense when they're contained in the larger Git project's repo.
* Standardize the naming of some of the Makefile targets to always
  include a dash in the "-rs" or "-sys" suffixes.
* Clean up READMEs and crate descriptions in preparation for
  uploading to crates.io.
Changes in V5:
* When building with INCLUDE_LIBGIT_RS defined, add
  "-fvisibility=hidden" to CFLAGS. This allows us to manage symbol
  visibility in libgitpub.a without causing `make all` to rebuild from
  scratch due to changing CFLAGS.
* Avoid using c_int in the higher-level Rust API.
* Remove libgitpub.a and intermediate files with `make clean`.
Changes in V4:
* Drop V3 patch #3, which added wrappers around repository
  initialization and config access. These are not well-libified, and
  they are not necessary for JJ's proof-of-concept use case, so let's
  avoid exporting them for now.
* Set a minimum supported Rust version of 1.63. Autodetect whether our
  Rust version has c_int and c_char types; if not, define them
  ourselves.
* When building libgitpub.a via build.rs, set DEVELOPER=1 to catch
  additional errors at build time.
* In build.rs, use the make_cmd crate to portable select the correct
  invocation of GNU Make.
* Follow naming standards for _alloc() and _free() functions.
* Use String instead of CString in higher-level API.
* Move libgit_configset_alloc() and libgit_configset_free() out of
  upstream Git, to the libgitpub shim library.
* In libgitpub, initialize libgit_config_set structs in the _alloc()
  function rather than with a separate _init() function.
* Remove unnecessary comments in libgit-sys showing where the wrapped
  functions were originally defined.
* Fix clippy lint: don't reborrow configfile path references.
* Various typo fixes and `cargo fmt` fixes.
Changes in V3:
* Renamed cgit-rs to libgit-rs and cgit-sys to libgit-sys
* Makefile cleanup, particularly adding config.mak options that
  developers can set to run Rust builds and tests by default (Patch 6)
* Provide testdata configs for unit tests
* ConfigSet API now uses &Path instead of &str -- more ergonomic for
  Rust users to pass in and errors out if the path string isn't UTF-8
* Fixed unresolved dependency on libz in Cargo.toml
Calvin Wan (1):
  libgit: add higher-level libgit crate
Josh Steadmon (3):
  common-main: split init and exit code into new files
  libgit-sys: introduce Rust wrapper for libgit.a
  libgit-sys: also export some config_set functions
 .gitignore                                |   2 +
 Makefile                                  |  45 +++++++++
 common-exit.c                             |  26 ++++++
 common-init.c                             |  63 +++++++++++++
 common-init.h                             |   6 ++
 common-main.c                             |  83 +----------------
 contrib/libgit-rs/Cargo.lock              |  77 ++++++++++++++++
 contrib/libgit-rs/Cargo.toml              |  17 ++++
 contrib/libgit-rs/README.md               |  13 +++
 contrib/libgit-rs/build.rs                |   4 +
 contrib/libgit-rs/src/config.rs           | 106 ++++++++++++++++++++++
 contrib/libgit-rs/src/lib.rs              |   1 +
 contrib/libgit-rs/testdata/config1        |   2 +
 contrib/libgit-rs/testdata/config2        |   2 +
 contrib/libgit-rs/testdata/config3        |   2 +
 contrib/libgit-sys/Cargo.lock             |  69 ++++++++++++++
 contrib/libgit-sys/Cargo.toml             |  19 ++++
 contrib/libgit-sys/README.md              |   4 +
 contrib/libgit-sys/build.rs               |  35 +++++++
 contrib/libgit-sys/public_symbol_export.c |  51 +++++++++++
 contrib/libgit-sys/public_symbol_export.h |  18 ++++
 contrib/libgit-sys/src/lib.rs             |  79 ++++++++++++++++
 meson.build                               |   2 +
 t/Makefile                                |  15 +++
 24 files changed, 660 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/libgit-rs/Cargo.lock
 create mode 100644 contrib/libgit-rs/Cargo.toml
 create mode 100644 contrib/libgit-rs/README.md
 create mode 100644 contrib/libgit-rs/build.rs
 create mode 100644 contrib/libgit-rs/src/config.rs
 create mode 100644 contrib/libgit-rs/src/lib.rs
 create mode 100644 contrib/libgit-rs/testdata/config1
 create mode 100644 contrib/libgit-rs/testdata/config2
 create mode 100644 contrib/libgit-rs/testdata/config3
 create mode 100644 contrib/libgit-sys/Cargo.lock
 create mode 100644 contrib/libgit-sys/Cargo.toml
 create mode 100644 contrib/libgit-sys/README.md
 create mode 100644 contrib/libgit-sys/build.rs
 create mode 100644 contrib/libgit-sys/public_symbol_export.c
 create mode 100644 contrib/libgit-sys/public_symbol_export.h
 create mode 100644 contrib/libgit-sys/src/lib.rs
Range-diff against v6:
1:  ff6cd62397 ! 1:  cd0cb9aa04 common-main: split init and exit code into new files
    @@ common-main.c
     -
     -	return code;
     -}
    +
    + ## meson.build ##
    +@@ meson.build: libgit_sources = [
    +   'commit-graph.c',
    +   'commit-reach.c',
    +   'commit.c',
    ++  'common-exit.c',
    ++  'common-init.c',
    +   'compat/nonblock.c',
    +   'compat/obstack.c',
    +   'compat/terminal.c',
2:  5fc66cdb16 ! 2:  f1502b8590 libgit-sys: introduce Rust wrapper for libgit.a
    @@ .gitignore: Release/
     +/contrib/libgit-sys/target
     
      ## Makefile ##
    +@@ Makefile: include shared.mak
    + # Define LINK_FUZZ_PROGRAMS if you want `make all` to also build the fuzz test
    + # programs in oss-fuzz/.
    + #
    ++# Define INCLUDE_LIBGIT_RS if you want `make all` and `make test` to build and
    ++# test the Rust crate in contrib/libgit-sys.
    ++#
    + # === Optional library: libintl ===
    + #
    + # Define NO_GETTEXT if you don't want Git output to be translated.
     @@ Makefile: CURL_CONFIG = curl-config
      GCOV = gcov
      STRIP = strip
    @@ Makefile: CURL_CONFIG = curl-config
      
      export TCL_PATH TCLTK_PATH
      
    -@@ Makefile: OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS)
    - OBJECTS += $(UNIT_TEST_OBJS)
    +@@ Makefile: ifdef FSMONITOR_OS_SETTINGS
    + 	COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o
    + endif
    + 
    ++ifdef INCLUDE_LIBGIT_RS
    ++	# Enable symbol hiding in contrib/libgit-sys/libgitpub.a without making
    ++	# us rebuild the whole tree every time we run a Rust build.
    ++	BASIC_CFLAGS += -fvisibility=hidden
    ++endif
    ++
    + ifeq ($(TCLTK_PATH),)
    + NO_TCLTK = NoThanks
    + endif
    +@@ Makefile: OBJECTS += $(UNIT_TEST_OBJS)
      OBJECTS += $(CLAR_TEST_OBJS)
      OBJECTS += $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
    -+OBJECTS += contrib/libgit-sys/public_symbol_export.o
      
    ++ifdef INCLUDE_LIBGIT_RS
    ++	OBJECTS += contrib/libgit-sys/public_symbol_export.o
    ++endif
    ++
      ifndef NO_CURL
      	OBJECTS += http.o http-walker.o remote-curl.o
    + endif
     @@ 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/libgit-sys/target
    -+	$(RM) -r contrib/libgit-sys/partial_symbol_export.o
    -+	$(RM) -r contrib/libgit-sys/hidden_symbol_export.o
    -+	$(RM) -r contrib/libgit-sys/libgitpub.a
    ++	$(RM) contrib/libgit-sys/partial_symbol_export.o
    ++	$(RM) contrib/libgit-sys/hidden_symbol_export.o
    ++	$(RM) contrib/libgit-sys/libgitpub.a
      ifndef NO_PERL
      	$(RM) -r perl/build/
      endif
    @@ Makefile: $(CLAR_TEST_PROG): $(UNIT_TEST_DIR)/clar.suite $(CLAR_TEST_OBJS) $(GIT
      unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X
      	$(MAKE) -C t/ unit-tests
     +
    ++.PHONY: libgit-sys
    ++libgit-sys:
    ++	$(QUIET)(\
    ++		cd contrib/libgit-sys && \
    ++		cargo build \
    ++	)
    ++ifdef INCLUDE_LIBGIT_RS
    ++all:: libgit-sys
    ++endif
    ++
     +contrib/libgit-sys/partial_symbol_export.o: contrib/libgit-sys/public_symbol_export.o libgit.a reftable/libreftable.a xdiff/lib.a
     +	$(LD) -r $^ -o $@
     +
    @@ contrib/libgit-sys/Cargo.toml (new)
     +edition = "2021"
     +build = "build.rs"
     +links = "gitpub"
    -+rust-version = "1.63"
    ++rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from
    ++                      # version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/
     +description = "Native bindings to a portion of libgit"
     +
     +[lib]
    @@ contrib/libgit-sys/build.rs (new)
     +        .env_remove("PROFILE")
     +        .current_dir(git_root.clone())
     +        .args([
    -+            "CFLAGS=-fvisibility=hidden",
    ++            "INCLUDE_LIBGIT_RS=YesPlease",
     +            "contrib/libgit-sys/libgitpub.a",
     +        ])
     +        .output()
    @@ contrib/libgit-sys/build.rs (new)
     
      ## contrib/libgit-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
    -+// avoids conflicts with other libraries such as libgit2.
    ++/* 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
    ++ * avoids conflicts with other libraries such as libgit2.
    ++ */
     +
     +#include "git-compat-util.h"
     +#include "contrib/libgit-sys/public_symbol_export.h"
    @@ contrib/libgit-sys/src/lib.rs (new)
     +        );
     +    }
     +}
    +
    + ## t/Makefile ##
    +@@ t/Makefile: perf:
    + 
    + .PHONY: pre-clean $(T) aggregate-results clean valgrind perf \
    + 	check-chainlint clean-chainlint test-chainlint $(UNIT_TESTS)
    ++
    ++.PHONY: libgit-sys-test
    ++libgit-sys-test:
    ++	$(QUIET)(\
    ++		cd ../contrib/libgit-sys && \
    ++		cargo test \
    ++	)
    ++ifdef INCLUDE_LIBGIT_RS
    ++all:: libgit-sys-test
    ++endif
3:  03f39b6c3a < -:  ---------- libgit-sys: also export some config_set functions
5:  84706f0db7 ! 3:  d67d3648d1 Makefile: add option to build and test libgit-rs and libgit-rs-sys
    @@
      ## Metadata ##
    -Author: Calvin Wan <calvinwan@google.com>
    +Author: Josh Steadmon <steadmon@google.com>
     
      ## Commit message ##
    -    Makefile: add option to build and test libgit-rs and libgit-rs-sys
    +    libgit-sys: also export some config_set functions
     
    -    Add libgitrs, libgitrs-sys, libgitrs-test, and libgitrs-sys-test targets
    -    to their respective Makefiles so they can be built and tested without
    -    having to run cargo build/test.
    +    In preparation for implementing a higher-level Rust API for accessing
    +    Git configs, export some of the upstream configset API via libgitpub and
    +    libgit-sys. Since this will be exercised as part of the higher-level API
    +    in the next commit, no tests have been added for libgit-sys.
     
    -    Add build variable, INCLUDE_LIBGIT_RS, that when set, automatically
    -    builds and tests libgit-rs and libgit-rs-sys when `make all` is run.
    +    While we're at it, add git_configset_alloc() and git_configset_free()
    +    functions in libgitpub 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: Josh Steadmon <steadmon@google.com>
    +    Co-authored-by: Calvin Wan <calvinwan@google.com>
         Signed-off-by: Calvin Wan <calvinwan@google.com>
    +    Signed-off-by: Josh Steadmon <steadmon@google.com>
     
    - ## Makefile ##
    -@@ Makefile: include shared.mak
    - # Define LINK_FUZZ_PROGRAMS if you want `make all` to also build the fuzz test
    - # programs in oss-fuzz/.
    - #
    -+# Define INCLUDE_LIBGIT_RS if you want `make all` and `make test` to build and
    -+# test the Rust crates in contrib/libgit-rs/ and contrib/libgit-rs/libgit-sys/.
    -+#
    - # === Optional library: libintl ===
    - #
    - # Define NO_GETTEXT if you don't want Git output to be translated.
    -@@ Makefile: ifdef FSMONITOR_OS_SETTINGS
    - 	COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o
    - endif
    + ## contrib/libgit-sys/public_symbol_export.c ##
    +@@
    +  */
      
    -+ifdef INCLUDE_LIBGIT_RS
    -+	# Enable symbol hiding in contrib/libgit-rs/libgit-sys/libgitpub.a
    -+	# without making us rebuild the whole tree every time we run a Rust
    -+	# build.
    -+	BASIC_CFLAGS += -fvisibility=hidden
    -+endif
    -+
    - ifeq ($(TCLTK_PATH),)
    - NO_TCLTK = NoThanks
    - endif
    -@@ Makefile: build-unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG)
    - unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X
    - 	$(MAKE) -C t/ unit-tests
    + #include "git-compat-util.h"
    ++#include "config.h"
    + #include "contrib/libgit-sys/public_symbol_export.h"
    + #include "version.h"
      
    -+.PHONY: libgit-sys
    -+libgit-sys:
    -+	$(QUIET)(\
    -+		cd contrib/libgit-sys && \
    -+		cargo build \
    -+	)
    -+.PHONY: libgit-rs
    -+libgit-rs:
    -+	$(QUIET)(\
    -+		cd contrib/libgit-rs && \
    -+		cargo build \
    -+	)
    -+ifdef INCLUDE_LIBGIT_RS
    -+all:: libgit-rs
    -+endif
    -+
    - contrib/libgit-sys/partial_symbol_export.o: contrib/libgit-sys/public_symbol_export.o libgit.a reftable/libreftable.a xdiff/lib.a
    - 	$(LD) -r $^ -o $@
    + #pragma GCC visibility push(default)
      
    ++struct libgit_config_set *libgit_configset_alloc(void)
    ++{
    ++	struct config_set *cs = xmalloc(sizeof(struct config_set));
    ++	git_configset_init(cs);
    ++	return (struct libgit_config_set *) cs;
    ++}
    ++
    ++void libgit_configset_free(struct libgit_config_set *cs)
    ++{
    ++	git_configset_clear((struct config_set *) cs);
    ++	free((struct config_set *) cs);
    ++}
    ++
    ++int libgit_configset_add_file(struct libgit_config_set *cs, const char *filename)
    ++{
    ++	return git_configset_add_file((struct config_set *) cs, filename);
    ++}
    ++
    ++int libgit_configset_get_int(struct libgit_config_set *cs, const char *key, int *dest)
    ++{
    ++	return git_configset_get_int((struct config_set *) cs, key, dest);
    ++}
    ++
    ++int libgit_configset_get_string(struct libgit_config_set *cs, const char *key, char **dest)
    ++{
    ++	return git_configset_get_string((struct config_set *) cs, key, dest);
    ++}
    ++
    + const char *libgit_user_agent(void)
    + {
    + 	return git_user_agent();
     
    - ## contrib/libgit-sys/build.rs ##
    -@@ contrib/libgit-sys/build.rs: pub fn main() -> std::io::Result<()> {
    -         .env_remove("PROFILE")
    -         .current_dir(git_root.clone())
    -         .args([
    --            "CFLAGS=-fvisibility=hidden",
    -+            "INCLUDE_LIBGIT_RS=YesPlease",
    -             "contrib/libgit-sys/libgitpub.a",
    -         ])
    -         .output()
    + ## contrib/libgit-sys/public_symbol_export.h ##
    +@@
    + #ifndef PUBLIC_SYMBOL_EXPORT_H
    + #define PUBLIC_SYMBOL_EXPORT_H
    + 
    ++struct libgit_config_set *libgit_configset_alloc(void);
    ++
    ++void libgit_configset_free(struct libgit_config_set *cs);
    ++
    ++int libgit_configset_add_file(struct libgit_config_set *cs, const char *filename);
    ++
    ++int libgit_configset_get_int(struct libgit_config_set *cs, const char *key, int *dest);
    ++
    ++int libgit_configset_get_string(struct libgit_config_set *cs, const char *key, char **dest);
    ++
    + const char *libgit_user_agent(void);
    + 
    + const char *libgit_user_agent_sanitized(void);
     
    - ## t/Makefile ##
    -@@ t/Makefile: perf:
    + ## contrib/libgit-sys/src/lib.rs ##
    +@@
    + #[cfg(has_std__ffi__c_char)]
    +-use std::ffi::c_char;
    ++use std::ffi::{c_char, c_int};
    + 
    + #[cfg(not(has_std__ffi__c_char))]
    + #[allow(non_camel_case_types)]
    + pub type c_char = i8;
    + 
    ++#[cfg(not(has_std__ffi__c_char))]
    ++#[allow(non_camel_case_types)]
    ++pub type c_int = i32;
    ++
    + extern crate libz_sys;
    + 
    ++#[allow(non_camel_case_types)]
    ++#[repr(C)]
    ++pub struct libgit_config_set {
    ++    _data: [u8; 0],
    ++    _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
    ++}
    ++
    + extern "C" {
    +     pub fn libgit_user_agent() -> *const c_char;
    +     pub fn libgit_user_agent_sanitized() -> *const c_char;
    ++
    ++    pub fn libgit_configset_alloc() -> *mut libgit_config_set;
    ++    pub fn libgit_configset_free(cs: *mut libgit_config_set);
    ++
    ++    pub fn libgit_configset_add_file(cs: *mut libgit_config_set, filename: *const c_char) -> c_int;
    ++
    ++    pub fn libgit_configset_get_int(
    ++        cs: *mut libgit_config_set,
    ++        key: *const c_char,
    ++        int: *mut c_int,
    ++    ) -> c_int;
    ++
    ++    pub fn libgit_configset_get_string(
    ++        cs: *mut libgit_config_set,
    ++        key: *const c_char,
    ++        dest: *mut *mut c_char,
    ++    ) -> c_int;
    ++
    + }
      
    - .PHONY: pre-clean $(T) aggregate-results clean valgrind perf \
    - 	check-chainlint clean-chainlint test-chainlint $(UNIT_TESTS)
    -+
    -+.PHONY: libgit-sys-test
    -+libgit-sys-test:
    -+	$(QUIET)(\
    -+		cd ../contrib/libgit-sys && \
    -+		cargo test \
    -+	)
    -+.PHONY: libgit-rs-test
    -+libgit-rs-test:
    -+	$(QUIET)(\
    -+		cd ../contrib/libgit-rs && \
    -+		cargo test \
    -+	)
    -+ifdef INCLUDE_LIBGIT_RS
    -+all:: libgit-sys-test libgit-rs-test
    -+endif
    + #[cfg(test)]
4:  65166ea0c0 ! 4:  88425bb0b1 libgit: add higher-level libgit crate
    @@ .gitignore: Release/
      /contrib/libgit-sys/target
     
      ## Makefile ##
    +@@ Makefile: include shared.mak
    + # programs in oss-fuzz/.
    + #
    + # Define INCLUDE_LIBGIT_RS if you want `make all` and `make test` to build and
    +-# test the Rust crate in contrib/libgit-sys.
    ++# test the Rust crates in contrib/libgit-sys and contrib/libgit-rs.
    + #
    + # === Optional library: libintl ===
    + #
     @@ 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/libgit-sys/target
    -+	$(RM) -r contrib/libgit-rs/target contrib/libgit-sys/target
    - 	$(RM) -r contrib/libgit-sys/partial_symbol_export.o
    - 	$(RM) -r contrib/libgit-sys/hidden_symbol_export.o
    - 	$(RM) -r contrib/libgit-sys/libgitpub.a
    ++	$(RM) -r contrib/libgit-sys/target contrib/libgit-rs/target
    + 	$(RM) contrib/libgit-sys/partial_symbol_export.o
    + 	$(RM) contrib/libgit-sys/hidden_symbol_export.o
    + 	$(RM) contrib/libgit-sys/libgitpub.a
    +@@ Makefile: build-unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG)
    + unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X
    + 	$(MAKE) -C t/ unit-tests
    + 
    +-.PHONY: libgit-sys
    ++.PHONY: libgit-sys libgit-rs
    + libgit-sys:
    + 	$(QUIET)(\
    + 		cd contrib/libgit-sys && \
    + 		cargo build \
    + 	)
    ++libgit-rs:
    ++	$(QUIET)(\
    ++		cd contrib/libgit-rs && \
    ++		cargo build \
    ++	)
    + ifdef INCLUDE_LIBGIT_RS
    +-all:: libgit-sys
    ++all:: libgit-sys libgit-rs
    + endif
    + 
    + contrib/libgit-sys/partial_symbol_export.o: contrib/libgit-sys/public_symbol_export.o libgit.a reftable/libreftable.a xdiff/lib.a
     
      ## contrib/libgit-rs/Cargo.lock (new) ##
     @@
    @@ contrib/libgit-rs/Cargo.toml (new)
     +version = "0.1.0"
     +edition = "2021"
     +build = "build.rs"
    -+rust-version = "1.63"
    ++rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from
    ++                      # version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/
    ++
     +
     +[lib]
     +path = "src/lib.rs"
    @@ contrib/libgit-rs/build.rs (new)
     +    ac.emit_has_path("std::ffi::c_char");
     +}
     
    - ## contrib/libgit-rs/src/lib.rs (new) ##
    + ## contrib/libgit-rs/src/config.rs (new) ##
     @@
     +use std::ffi::{c_void, CStr, CString};
     +use std::path::Path;
    @@ contrib/libgit-rs/src/lib.rs (new)
     +
     +#[cfg(not(has_std__ffi__c_char))]
     +#[allow(non_camel_case_types)]
    -+pub type c_char = i8;
    ++type c_char = i8;
     +
     +#[cfg(not(has_std__ffi__c_char))]
     +#[allow(non_camel_case_types)]
    -+pub type c_int = i32;
    ++type c_int = i32;
     +
     +use libgit_sys::*;
     +
    ++/// A ConfigSet is an in-memory cache for config-like files such as `.gitmodules` or `.gitconfig`.
    ++/// It does not support all config directives; notably, it will not process `include` or
    ++/// `includeIf` directives (but it will store them so that callers can choose whether and how to
    ++/// handle them).
     +pub struct ConfigSet(*mut libgit_config_set);
     +impl ConfigSet {
    ++    /// Allocate a new ConfigSet
     +    pub fn new() -> Self {
     +        unsafe { ConfigSet(libgit_configset_alloc()) }
     +    }
     +
    ++    /// Load the given files into the ConfigSet; conflicting directives in later files will
    ++    /// override those given in earlier files.
     +    pub fn add_files(&mut self, files: &[&Path]) {
     +        for file in files {
     +            let pstr = file.to_str().expect("Invalid UTF-8");
    @@ contrib/libgit-rs/src/lib.rs (new)
     +        }
     +    }
     +
    ++    /// Load the value for the given key and attempt to parse it as an i32. Dies with a fatal error
    ++    /// if the value cannot be parsed. Returns None if the key is not present.
     +    pub fn get_int(&mut self, key: &str) -> Option<i32> {
     +        let key = CString::new(key).expect("Couldn't convert to CString");
     +        let mut val: c_int = 0;
    @@ contrib/libgit-rs/src/lib.rs (new)
     +        Some(val.into())
     +    }
     +
    ++    /// Clones the value for the given key. Dies with a fatal error if the value cannot be
    ++    /// converted to a String. Returns None if the key is not present.
     +    pub fn get_string(&mut self, key: &str) -> Option<String> {
     +        let key = CString::new(key).expect("Couldn't convert key to CString");
     +        let mut val: *mut c_char = std::ptr::null_mut();
    @@ contrib/libgit-rs/src/lib.rs (new)
     +    }
     +}
     
    + ## contrib/libgit-rs/src/lib.rs (new) ##
    +@@
    ++pub mod config;
    +
      ## contrib/libgit-rs/testdata/config1 (new) ##
     @@
     +[trace2]
    @@ contrib/libgit-sys/src/lib.rs: pub struct libgit_config_set {
          pub fn libgit_user_agent() -> *const c_char;
          pub fn libgit_user_agent_sanitized() -> *const c_char;
      
    +
    + ## t/Makefile ##
    +@@ t/Makefile: perf:
    + .PHONY: pre-clean $(T) aggregate-results clean valgrind perf \
    + 	check-chainlint clean-chainlint test-chainlint $(UNIT_TESTS)
    + 
    +-.PHONY: libgit-sys-test
    ++.PHONY: libgit-sys-test libgit-rs-test
    + libgit-sys-test:
    + 	$(QUIET)(\
    + 		cd ../contrib/libgit-sys && \
    + 		cargo test \
    + 	)
    ++libgit-rs-test:
    ++	$(QUIET)(\
    ++		cd ../contrib/libgit-rs && \
    ++		cargo test \
    ++	)
    + ifdef INCLUDE_LIBGIT_RS
    +-all:: libgit-sys-test
    ++all:: libgit-sys-test libgit-rs-test
    + endif
base-commit: 757161efcca150a9a96b312d9e780a071e601a03
-- 
2.48.1.262.g85cc9f2d1e-goog
Previous: Junio C HamanoNext: Josh Steadmon
Message 189 of 217 in “[RFC] Introduce cgit-rs, a Rust wrapper around libgit.a”
  1. 0/6 [RFC] Introduce cgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Aug 7, 2024
  2. 1/6 common-main: split common_exit() into a new fileJosh Steadmon, Aug 7, 2024
  3. Junio C HamanoAug 7, 2024
  4. Josh SteadmonAug 7, 2024
  5. 2/6 repository: add initialize_repo wrapper without pointerJosh Steadmon, Aug 7, 2024
  6. Mike HommeyAug 7, 2024
  7. Josh SteadmonAug 7, 2024
  8. Mike HommeyAug 7, 2024
  9. Josh SteadmonAug 8, 2024
  10. 3/6 contrib/cgit-rs: introduce Rust wrapper for libgit.aJosh Steadmon, Aug 7, 2024
  11. brian m. carlsonAug 7, 2024
  12. rsbecker@nexbridge.comAug 7, 2024
  13. Josh SteadmonAug 7, 2024
  14. rsbecker@nexbridge.comAug 7, 2024
  15. Josh SteadmonAug 8, 2024
  16. rsbecker@nexbridge.comAug 8, 2024
  17. Junio C HamanoAug 8, 2024
  18. rsbecker@nexbridge.comAug 8, 2024
  19. rsbecker@nexbridge.comAug 12, 2024
  20. Josh SteadmonAug 7, 2024
  21. brian m. carlsonAug 7, 2024
  22. Junio C HamanoAug 8, 2024
  23. Josh SteadmonAug 8, 2024
  24. Josh SteadmonAug 8, 2024
  25. Kyle LippincottAug 8, 2024
  26. Josh SteadmonAug 8, 2024
  27. Mike HommeyAug 7, 2024
  28. Josh SteadmonAug 7, 2024
  29. Mike HommeyAug 8, 2024
  30. Josh SteadmonAug 8, 2024
  31. 4/6 contrib/cgit-rs: add repo initialization and config accessJosh Steadmon, Aug 7, 2024
  32. brian m. carlsonAug 7, 2024
  33. Josh SteadmonAug 7, 2024
  34. brian m. carlsonAug 8, 2024
  35. 5/6 config: add git_configset_allocJosh Steadmon, Aug 7, 2024
  36. 6/6 contrib/cgit-rs: add a subset of configset wrappersJosh Steadmon, Aug 7, 2024
  37. brian m. carlsonAug 7, 2024
  38. Junio C HamanoAug 7, 2024
  39. Josh SteadmonAug 8, 2024
  40. Calvin WanSep 4, 2024
  41. brian m. carlsonSep 4, 2024
  42. Calvin WanSep 6, 2024
  43. brian m. carlsonSep 7, 2024
  44. Junio C HamanoSep 4, 2024
  45. brian m. carlsonSep 4, 2024
  46. Junio C HamanoSep 4, 2024
  47. Josh SteadmonSep 4, 2024
  48. brian m. carlsonAug 7, 2024
  49. Josh SteadmonAug 7, 2024
  50. brian m. carlsonAug 8, 2024
  51. Josh SteadmonAug 9, 2024
  52. Jason A. DonenfeldAug 8, 2024
  53. Dragan SimicAug 8, 2024
  54. rsbecker@nexbridge.comAug 8, 2024
  55. Dragan SimicAug 8, 2024
  56. Junio C HamanoAug 8, 2024
  57. Junio C HamanoAug 9, 2024
  58. Junio C HamanoAug 9, 2024
  59. Josh SteadmonAug 9, 2024
  60. Junio C HamanoAug 9, 2024
  61. Junio C HamanoAug 9, 2024
  62. Josh SteadmonAug 9, 2024
  63. Junio C HamanoAug 9, 2024
  64. 0/5 Introduce cgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Aug 9, 2024
  65. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Aug 9, 2024
  66. 2/5 cgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Aug 9, 2024
  67. 3/5 cgit-sys: add repo initialization and config accessJosh Steadmon, Aug 9, 2024
  68. 4/5 config: add git_configset_alloc() and git_configset_clear_and_free()Josh Steadmon, Aug 9, 2024
  69. Phillip WoodAug 12, 2024
  70. Josh SteadmonAug 12, 2024
  71. Kyle LippincottAug 12, 2024
  72. phillip.wood123@gmail.comAug 13, 2024
  73. Junio C HamanoAug 13, 2024
  74. phillip.wood123@gmail.comAug 13, 2024
  75. Josh SteadmonOct 2, 2024
  76. Patrick SteinhardtAug 16, 2024
  77. Josh SteadmonOct 2, 2024
  78. 5/5 cgit: add higher-level cgit crateJosh Steadmon, Aug 9, 2024
  79. Phillip WoodAug 12, 2024
  80. Calvin WanAug 21, 2024
  81. Kyle LippincottAug 21, 2024
  82. Phillip WoodAug 22, 2024
  83. Phillip WoodAug 22, 2024
  84. Josh SteadmonOct 2, 2024
  85. Junio C HamanoAug 9, 2024
  86. Jason A. DonenfeldAug 10, 2024
  87. Dragan SimicAug 11, 2024
  88. Eric SunshineAug 11, 2024
  89. Dragan SimicAug 11, 2024
  90. Eric SunshineAug 11, 2024
  91. Dragan SimicAug 11, 2024
  92. Junio C HamanoAug 12, 2024
  93. Eric SunshineAug 12, 2024
  94. Junio C HamanoAug 12, 2024
  95. Josh SteadmonAug 12, 2024
  96. Patrick SteinhardtAug 16, 2024
  97. brian m. carlsonAug 16, 2024
  98. Eric SunshineAug 17, 2024
  99. Junio C HamanoAug 18, 2024
  100. brian m. carlsonAug 12, 2024
  101. Dragan SimicAug 12, 2024
  102. Josh SteadmonAug 12, 2024
  103. Junio C HamanoAug 12, 2024
  104. Junio C HamanoAug 12, 2024
  105. 0/6 Introduce libgit-rs, a Rust wrapper around libgit.aCalvin Wan, Sep 6, 2024
  106. 1/6 common-main: split init and exit code into new filesCalvin Wan, Sep 6, 2024
  107. 2/6 libgit-sys: introduce Rust wrapper for libgit.aCalvin Wan, Sep 6, 2024
  108. Eric SunshineSep 6, 2024
  109. Mike HommeySep 6, 2024
  110. Junio C HamanoSep 8, 2024
  111. Josh SteadmonSep 18, 2024
  112. Calvin WanSep 10, 2024
  113. Josh SteadmonSep 18, 2024
  114. 3/6 libgit-sys: add repo initialization and config accessCalvin Wan, Sep 6, 2024
  115. Eric SunshineSep 6, 2024
  116. Josh SteadmonSep 18, 2024
  117. Junio C HamanoSep 6, 2024
  118. Josh SteadmonSep 18, 2024
  119. Patrick SteinhardtSep 10, 2024
  120. Josh SteadmonOct 7, 2024
  121. Josh SteadmonOct 8, 2024
  122. 4/6 config: add git_configset_alloc() and git_configset_clear_and_free()Calvin Wan, Sep 6, 2024
  123. Eric SunshineSep 6, 2024
  124. Patrick SteinhardtSep 10, 2024
  125. Phillip WoodSep 10, 2024
  126. Junio C HamanoSep 10, 2024
  127. Calvin WanSep 10, 2024
  128. Josh SteadmonOct 2, 2024
  129. 5/6 libgit: add higher-level libgit crateCalvin Wan, Sep 6, 2024
  130. Junio C HamanoSep 7, 2024
  131. Junio C HamanoSep 9, 2024
  132. Calvin WanSep 10, 2024
  133. Junio C HamanoSep 10, 2024
  134. Josh SteadmonSep 17, 2024
  135. Junio C HamanoSep 18, 2024
  136. Josh SteadmonOct 7, 2024
  137. Josh SteadmonSep 17, 2024
  138. 6/6 Makefile: add option to build and test libgit-rs and libgit-rs-sysCalvin Wan, Sep 6, 2024
  139. Sean AllredSep 7, 2024
  140. Junio C HamanoSep 8, 2024
  141. Calvin WanSep 10, 2024
  142. brian m. carlsonSep 13, 2024
  143. Josh SteadmonOct 7, 2024
  144. Josh SteadmonOct 2, 2024
  145. 0/5 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Oct 8, 2024
  146. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Oct 8, 2024
  147. 2/5 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Oct 8, 2024
  148. 3/5 libgit-sys: also export some config_set functionsJosh Steadmon, Oct 8, 2024
  149. 4/5 libgit: add higher-level libgit crateJosh Steadmon, Oct 8, 2024
  150. Eric SunshineOct 9, 2024
  151. Josh SteadmonOct 9, 2024
  152. Josh SteadmonOct 9, 2024
  153. 5/5 Makefile: add option to build and test libgit-rs and libgit-rs-sysJosh Steadmon, Oct 8, 2024
  154. Junio C HamanoOct 8, 2024
  155. rsbecker@nexbridge.comOct 9, 2024
  156. Josh SteadmonOct 14, 2024
  157. Junio C HamanoOct 9, 2024
  158. Josh SteadmonOct 9, 2024
  159. Junio C HamanoOct 10, 2024
  160. Josh SteadmonOct 14, 2024
  161. Junio C HamanoOct 9, 2024
  162. Josh SteadmonOct 9, 2024
  163. 0/5 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Oct 15, 2024
  164. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Oct 15, 2024
  165. 2/5 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Oct 15, 2024
  166. 3/5 libgit-sys: also export some config_set functionsJosh Steadmon, Oct 15, 2024
  167. 4/5 libgit: add higher-level libgit crateJosh Steadmon, Oct 15, 2024
  168. 5/5 Makefile: add option to build and test libgit-rs and libgit-rs-sysJosh Steadmon, Oct 15, 2024
  169. Junio C HamanoDec 3, 2024
  170. 0/5 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 15, 2025
  171. 1/5 common-main: split init and exit code into new filesJosh Steadmon, Jan 15, 2025
  172. Junio C HamanoJan 15, 2025
  173. Junio C HamanoJan 16, 2025
  174. Junio C HamanoJan 16, 2025
  175. Patrick SteinhardtJan 17, 2025
  176. Josh SteadmonJan 21, 2025
  177. 2/5 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 15, 2025
  178. Junio C HamanoJan 15, 2025
  179. Josh SteadmonJan 22, 2025
  180. Josh SteadmonJan 27, 2025
  181. 3/5 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 15, 2025
  182. 4/5 libgit: add higher-level libgit crateJosh Steadmon, Jan 15, 2025
  183. brian m. carlsonJan 21, 2025
  184. Josh SteadmonJan 22, 2025
  185. 5/5 Makefile: add option to build and test libgit-rs and libgit-rs-sysJosh Steadmon, Jan 15, 2025
  186. Junio C HamanoJan 15, 2025
  187. brian m. carlsonJan 21, 2025
  188. Junio C HamanoJan 21, 2025
  189. 0/4 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 28, 2025
  190. 1/4 common-main: split init and exit code into new filesJosh Steadmon, Jan 28, 2025
  191. 2/4 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 28, 2025
  192. Phillip WoodJan 28, 2025
  193. Josh SteadmonJan 28, 2025
  194. Junio C HamanoJan 28, 2025
  195. 3/4 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 28, 2025
  196. Phillip WoodJan 28, 2025
  197. Josh SteadmonJan 28, 2025
  198. 4/4 libgit: add higher-level libgit crateJosh Steadmon, Jan 28, 2025
  199. Junio C HamanoJan 28, 2025
  200. Josh SteadmonJan 28, 2025
  201. Junio C HamanoJan 28, 2025
  202. 0/4 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 28, 2025
  203. 1/4 common-main: split init and exit code into new filesJosh Steadmon, Jan 28, 2025
  204. 2/4 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 28, 2025
  205. Junio C HamanoJan 28, 2025
  206. Josh SteadmonJan 29, 2025
  207. 3/4 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 28, 2025
  208. 4/4 libgit: add higher-level libgit crateJosh Steadmon, Jan 28, 2025
  209. Phillip WoodJan 29, 2025
  210. Josh SteadmonJan 29, 2025
  211. 0/4 Introduce libgit-rs, a Rust wrapper around libgit.aJosh Steadmon, Jan 29, 2025
  212. 1/4 common-main: split init and exit code into new filesJosh Steadmon, Jan 29, 2025
  213. 2/4 libgit-sys: introduce Rust wrapper for libgit.aJosh Steadmon, Jan 29, 2025
  214. 3/4 libgit-sys: also export some config_set functionsJosh Steadmon, Jan 29, 2025
  215. 4/4 libgit: add higher-level libgit crateJosh Steadmon, Jan 29, 2025
  216. phillip.wood123@gmail.comJan 30, 2025
  217. Junio C HamanoJan 30, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.