Volume XXII, number 279Tuesday, October 6, 2026Latest message 1 hour ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

RFC patchMove rust gitcore crate to a different subdirectory

18 messages between Feb 5, 2026 and Sep 18, 2026, from Mike Hommey, brian m. carlson, Junio C Hamano, Tuomas Ahola.

Plain Markdown or JSON for tools and agents. Diffs are folded; open one to read it.

Mike HommeyFeb 4, 2026, 23:22 UTC on lore

While `src/` is the default directory convention for Rust projects, it is too generic in the context of a multi-language project that is barely starting to (optionally) use Rust code.

Additionally, having `Cargo.toml` at the top-level of the repository implies that one can run `cargo build` directly, but this doesn't produce anything useful on its own.

Moving all Rust-specific files into a dedicated `rust/` subdirectory makes things clearer.

---

The above is a post hoc justification. I do think it makes sense to do, but I should mention my real immediate motivation.

git-cinnabar, a git remote helper used to talk to Mercurial servers, is a project based on libgit (the C parts). As such, its repository includes the git codebase as a submodule.

As of about 3 years ago, most code that is not libgit in git-cinnabar is written in Rust, and is published on crates.io.

Part of publishing on crates.io involves running `cargo publish`, which does `cargo package` under the hood. `cargo package` has the feature of... not including directories that contain a Cargo.toml, so upgrading libgit to 2.52.0 breaks the publishing process because all of the git source code is skipped, and git-cinnabar can't be built as a result.

Of course, what this means is that this change is merely kicking the can down the road, because the problem will reappear when the rust code becomes non-optional in Git, thus why I'm making this RFC at the moment.

 .gitignore                    |  2 ++
 Makefile                      | 12 ++++++------
 meson.build                   |  2 +-
 Cargo.toml => rust/Cargo.toml |  1 +
 {src => rust}/cargo-meson.sh  |  0
 {src => rust}/lib.rs          |  0
 {src => rust}/meson.build     |  0
 {src => rust}/varint.rs       |  0
 8 files changed, 10 insertions(+), 7 deletions(-)
 rename Cargo.toml => rust/Cargo.toml (89%)
 rename {src => rust}/cargo-meson.sh (100%)
 rename {src => rust}/lib.rs (100%)
 rename {src => rust}/meson.build (100%)
 rename {src => rust}/varint.rs (100%)
Show changes to 9 files +10 −7

.gitignore, Makefile, meson.build, Cargo.toml, rust/Cargo.toml, src/cargo-meson.sh, src/lib.rs, src/meson.build, src/varint.rs

diff --git a/.gitignore b/.gitignore
index 78a45cb5be..c7453b6fb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -258,3 +258,5 @@ Release/
 /contrib/buildsystems/out
 /contrib/libgit-rs/target
 /contrib/libgit-sys/target
+/rust/target
+/rust/Cargo.lock
diff --git a/Makefile b/Makefile
index 8aa489f3b6..d7e9b7fd75 100644
--- a/Makefile
+++ b/Makefile
@@ -939,9 +939,9 @@ TEST_SHELL_PATH = $(SHELL_PATH)
 LIB_FILE = libgit.a
 
 ifdef DEBUG
-RUST_TARGET_DIR = target/debug
+RUST_TARGET_DIR = rust/target/debug
 else
-RUST_TARGET_DIR = target/release
+RUST_TARGET_DIR = rust/target/release
 endif
 
 ifeq ($(uname_S),Windows)
@@ -1545,8 +1545,8 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
 
 UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
 
-RUST_SOURCES += src/lib.rs
-RUST_SOURCES += src/varint.rs
+RUST_SOURCES += rust/lib.rs
+RUST_SOURCES += rust/varint.rs
 
 GIT-VERSION-FILE: FORCE
 	@OLD=$$(cat $@ 2>/dev/null || :) && \
@@ -3007,8 +3007,8 @@ scalar$X: scalar.o GIT-LDFLAGS $(GITLIBS)
 $(LIB_FILE): $(LIB_OBJS)
 	$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
 
-$(RUST_LIB): Cargo.toml $(RUST_SOURCES)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
+$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
 
 .PHONY: rust
 rust: $(RUST_LIB)
diff --git a/meson.build b/meson.build
index dd52efd1c8..6732198042 100644
--- a/meson.build
+++ b/meson.build
@@ -1723,7 +1723,7 @@ libgit_sources += version_def_h
 cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust'))
 rust_option = get_option('rust').disable_auto_if(not cargo.found())
 if rust_option.allowed()
-  subdir('src')
+  subdir('rust')
   libgit_c_args += '-DWITH_RUST'
 
   if host_machine.system() == 'windows'
diff --git a/Cargo.toml b/rust/Cargo.toml
similarity index 89%
rename from Cargo.toml
rename to rust/Cargo.toml
index 2f51bf5d5f..29e6d1f4e1 100644
--- a/Cargo.toml
+++ b/rust/Cargo.toml
@@ -6,5 +6,6 @@ rust-version = "1.49.0"
 
 [lib]
 crate-type = ["staticlib"]
+path = "lib.rs"
 
 [dependencies]
diff --git a/src/cargo-meson.sh b/rust/cargo-meson.sh
similarity index 100%
rename from src/cargo-meson.sh
rename to rust/cargo-meson.sh
diff --git a/src/lib.rs b/rust/lib.rs
similarity index 100%
rename from src/lib.rs
rename to rust/lib.rs
diff --git a/src/meson.build b/rust/meson.build
similarity index 100%
rename from src/meson.build
rename to rust/meson.build
diff --git a/src/varint.rs b/rust/varint.rs
similarity index 100%
rename from src/varint.rs
rename to rust/varint.rs
-- 
2.53.0.1.g318204b87e.dirty
brian m. carlsonFeb 5, 2026, 00:10 UTC in reply to Mike Hommey on lore

Re: [RFC PATCH] Move rust gitcore crate to a different subdirectory

On 2026-02-04 at 23:22:08, Mike Hommey wrote:
Show 10 quoted lines
> While `src/` is the default directory convention for Rust projects, it
> is too generic in the context of a multi-language project that is barely
> starting to (optionally) use Rust code.
> 
> Additionally, having `Cargo.toml` at the top-level of the repository
> implies that one can run `cargo build` directly, but this doesn't
> produce anything useful on its own.
> 
> Moving all Rust-specific files into a dedicated `rust/` subdirectory
> makes things clearer.

If we're going to do this, we should place the `src` directory under the `rust` subdirectory to maintain the normal layout. There are many tools that depend on this repository layout and we want to make it as easy as possible for people to use native, standard tooling to build things.

Note that I don't have strong opinions for or against placing the Rust code in a subdirectory, but I do very much want the standard layout to be honoured.

Show 19 quoted lines
> The above is a post hoc justification. I do think it makes sense to do,
> but I should mention my real immediate motivation.
> 
> git-cinnabar, a git remote helper used to talk to Mercurial servers, is
> a project based on libgit (the C parts). As such, its repository
> includes the git codebase as a submodule.
> 
> As of about 3 years ago, most code that is not libgit in git-cinnabar is
> written in Rust, and is published on crates.io.
> 
> Part of publishing on crates.io involves running `cargo publish`, which
> does `cargo package` under the hood. `cargo package` has the feature
> of... not including directories that contain a Cargo.toml, so upgrading
> libgit to 2.52.0 breaks the publishing process because all of the git
> source code is skipped, and git-cinnabar can't be built as a result.
> 
> Of course, what this means is that this change is merely kicking the can
> down the road, because the problem will reappear when the rust code
> becomes non-optional in Git, thus why I'm making this RFC at the moment.

Perhaps you could ask Cargo upstream to add a feature to override that in the meantime (or add such a feature yourself). I can imagine other uses for such a feature.

-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Mike HommeyFeb 5, 2026, 01:45 UTC in reply to brian m. carlson on lore

Re: [RFC PATCH] Move rust gitcore crate to a different subdirectory

On Thu, Feb 05, 2026 at 12:10:28AM +0000, brian m. carlson wrote:
Show 16 quoted lines
> On 2026-02-04 at 23:22:08, Mike Hommey wrote:
> > While `src/` is the default directory convention for Rust projects, it
> > is too generic in the context of a multi-language project that is barely
> > starting to (optionally) use Rust code.
> > 
> > Additionally, having `Cargo.toml` at the top-level of the repository
> > implies that one can run `cargo build` directly, but this doesn't
> > produce anything useful on its own.
> > 
> > Moving all Rust-specific files into a dedicated `rust/` subdirectory
> > makes things clearer.
> 
> If we're going to do this, we should place the `src` directory under the
> `rust` subdirectory to maintain the normal layout.  There are many tools
> that depend on this repository layout and we want to make it as easy as
> possible for people to use native, standard tooling to build things.

Not that I'm going to argue your preference, but I'm curious what tools you'd know that would not support a layout different than the typical one, because that means they're broken with some existing crates (e.g. those from https://github.com/servo/servo/) and should probably be fixed.

It might also be worth moving into a rust/gitcore/src directory too, including the crate name in the path.

Show 27 quoted lines
> Note that I don't have strong opinions for or against placing the Rust
> code in a subdirectory, but I do very much want the standard layout to
> be honoured.
> 
> > The above is a post hoc justification. I do think it makes sense to do,
> > but I should mention my real immediate motivation.
> > 
> > git-cinnabar, a git remote helper used to talk to Mercurial servers, is
> > a project based on libgit (the C parts). As such, its repository
> > includes the git codebase as a submodule.
> > 
> > As of about 3 years ago, most code that is not libgit in git-cinnabar is
> > written in Rust, and is published on crates.io.
> > 
> > Part of publishing on crates.io involves running `cargo publish`, which
> > does `cargo package` under the hood. `cargo package` has the feature
> > of... not including directories that contain a Cargo.toml, so upgrading
> > libgit to 2.52.0 breaks the publishing process because all of the git
> > source code is skipped, and git-cinnabar can't be built as a result.
> > 
> > Of course, what this means is that this change is merely kicking the can
> > down the road, because the problem will reappear when the rust code
> > becomes non-optional in Git, thus why I'm making this RFC at the moment.
> 
> Perhaps you could ask Cargo upstream to add a feature to override that
> in the meantime (or add such a feature yourself).  I can imagine other
> uses for such a feature.

I'm not sure this would be well received, considering there are already `exclude` and `include` fields to control such things, and they explicitly and purposely don't act on directories with a Cargo.toml:

| Regardless of whether exclude or include is specified, the following
| files are always excluded:
|   - Any sub-packages will be skipped (any subdirectory that contains a
|     Cargo.toml file).
|   - A directory named target in the root of the package will be skipped.
https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields
Mike
brian m. carlsonFeb 5, 2026, 02:06 UTC in reply to Mike Hommey on lore

Re: [RFC PATCH] Move rust gitcore crate to a different subdirectory

On 2026-02-05 at 01:45:53, Mike Hommey wrote:
Show 23 quoted lines
> On Thu, Feb 05, 2026 at 12:10:28AM +0000, brian m. carlson wrote:
> > On 2026-02-04 at 23:22:08, Mike Hommey wrote:
> > > While `src/` is the default directory convention for Rust projects, it
> > > is too generic in the context of a multi-language project that is barely
> > > starting to (optionally) use Rust code.
> > > 
> > > Additionally, having `Cargo.toml` at the top-level of the repository
> > > implies that one can run `cargo build` directly, but this doesn't
> > > produce anything useful on its own.
> > > 
> > > Moving all Rust-specific files into a dedicated `rust/` subdirectory
> > > makes things clearer.
> > 
> > If we're going to do this, we should place the `src` directory under the
> > `rust` subdirectory to maintain the normal layout.  There are many tools
> > that depend on this repository layout and we want to make it as easy as
> > possible for people to use native, standard tooling to build things.
> 
> Not that I'm going to argue your preference, but I'm curious what tools
> you'd know that would not support a layout different than the typical
> one, because that means they're broken with some existing crates (e.g.
> those from https://github.com/servo/servo/) and should probably be
> fixed.

One of my goals is to see if we can get Git's Rust code to compile with mrustc since that might make it easier for NonStop, as well as some Linux OSes on obsolete architectures.

I can tell you from my experience that mrustc's cargo implementation is extremely limited and does only the bare minimum in terms of functionality. It already needs some help to work with static libraries, but I'd really like to minimize the work that needs to be done on it since it's not lovely code, and using a standard layout is going to help with minimizing the necessary changes. I will admit that I haven't tested using a non-standard layout, but I fully expect it will not work based on my experience of the codebase.

Certainly people may think this is folly, but it costs nothing for us to keep the standard layout and make the porting process a little easier.

-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Mike HommeyFeb 5, 2026, 04:55 UTC in reply to brian m. carlson on lore

Re: [RFC PATCH] Move rust gitcore crate to a different subdirectory

On Thu, Feb 05, 2026 at 02:06:32AM +0000, brian m. carlson wrote:
Show 8 quoted lines
> I can tell you from my experience that mrustc's cargo implementation is
> extremely limited and does only the bare minimum in terms of
> functionality.  It already needs some help to work with static
> libraries, but I'd really like to minimize the work that needs to be
> done on it since it's not lovely code, and using a standard layout is
> going to help with minimizing the necessary changes.  I will admit that
> I haven't tested using a non-standard layout, but I fully expect it will
> not work based on my experience of the codebase.

For what it's worth, it looks like mrustc supports non-standard layout just fine[1], and that's not totally surprising, because the rustc codebase used to use non-standard layouts a lot (although that's not true anymore)

1. https://github.com/thepowersgang/mrustc/blob/7ff9513adb7cdbe0f8799e7b1f2e4df00ae21a14/tools/minicargo/manifest.cpp#L772
Mike HommeyFeb 9, 2026, 22:48 UTC in reply to Mike Hommey on lore

[PATCH v2] Move rust gitcore crate to a different subdirectory

While `src/` is the default directory convention for Rust projects, it is too generic in the context of a multi-language project that is barely starting to (optionally) use Rust code.

Additionally, having `Cargo.toml` at the top-level of the repository implies that one can run `cargo build` directly, but this doesn't produce anything useful on its own.

Moving all Rust-specific files into a dedicated `rust/` subdirectory makes things clearer.

Signed-off-by: Mike Hommey <mh@glandium.org>
---
 .gitignore                    |  2 ++
 Makefile                      | 12 ++++++------
 meson.build                   |  2 +-
 Cargo.toml => rust/Cargo.toml |  0
 {src => rust}/cargo-meson.sh  |  0
 {src => rust}/meson.build     |  6 +++---
 {src => rust/src}/lib.rs      |  0
 {src => rust/src}/varint.rs   |  0
 8 files changed, 12 insertions(+), 10 deletions(-)
 rename Cargo.toml => rust/Cargo.toml (100%)
 rename {src => rust}/cargo-meson.sh (100%)
 rename {src => rust}/meson.build (87%)
 rename {src => rust/src}/lib.rs (100%)
 rename {src => rust/src}/varint.rs (100%)
Show changes to 9 files +12 −10

.gitignore, Makefile, meson.build, Cargo.toml, src/cargo-meson.sh, src/meson.build, rust/meson.build, src/lib.rs, src/varint.rs

diff --git a/.gitignore b/.gitignore
index 78a45cb5be..c7453b6fb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -258,3 +258,5 @@ Release/
 /contrib/buildsystems/out
 /contrib/libgit-rs/target
 /contrib/libgit-sys/target
+/rust/target
+/rust/Cargo.lock
diff --git a/Makefile b/Makefile
index 8aa489f3b6..b60af704ed 100644
--- a/Makefile
+++ b/Makefile
@@ -939,9 +939,9 @@ TEST_SHELL_PATH = $(SHELL_PATH)
 LIB_FILE = libgit.a
 
 ifdef DEBUG
-RUST_TARGET_DIR = target/debug
+RUST_TARGET_DIR = rust/target/debug
 else
-RUST_TARGET_DIR = target/release
+RUST_TARGET_DIR = rust/target/release
 endif
 
 ifeq ($(uname_S),Windows)
@@ -1545,8 +1545,8 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
 
 UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
 
-RUST_SOURCES += src/lib.rs
-RUST_SOURCES += src/varint.rs
+RUST_SOURCES += rust/src/lib.rs
+RUST_SOURCES += rust/src/varint.rs
 
 GIT-VERSION-FILE: FORCE
 	@OLD=$$(cat $@ 2>/dev/null || :) && \
@@ -3007,8 +3007,8 @@ scalar$X: scalar.o GIT-LDFLAGS $(GITLIBS)
 $(LIB_FILE): $(LIB_OBJS)
 	$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
 
-$(RUST_LIB): Cargo.toml $(RUST_SOURCES)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
+$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
 
 .PHONY: rust
 rust: $(RUST_LIB)
diff --git a/meson.build b/meson.build
index dd52efd1c8..3a92936241 100644
--- a/meson.build
+++ b/meson.build
@@ -1723,7 +1723,7 @@ libgit_sources += version_def_h
 cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust'))
 rust_option = get_option('rust').disable_auto_if(not cargo.found())
 if rust_option.allowed()
-  subdir('src')
+  subdir('rust/src')
   libgit_c_args += '-DWITH_RUST'
 
   if host_machine.system() == 'windows'
diff --git a/Cargo.toml b/rust/Cargo.toml
similarity index 100%
rename from Cargo.toml
rename to rust/Cargo.toml
diff --git a/src/cargo-meson.sh b/rust/cargo-meson.sh
similarity index 100%
rename from src/cargo-meson.sh
rename to rust/cargo-meson.sh
diff --git a/src/meson.build b/rust/meson.build
similarity index 87%
rename from src/meson.build
rename to rust/meson.build
index 25b9ad5a14..9490272521 100644
--- a/src/meson.build
+++ b/rust/meson.build
@@ -10,7 +10,7 @@ libgit_rs_sources = [
 cargo_command = [
   shell,
   meson.current_source_dir() / 'cargo-meson.sh',
-  meson.project_source_root(),
+  meson.current_source_dir(),
   meson.current_build_dir(),
 ]
 if get_option('buildtype') == 'release'
@@ -19,7 +19,7 @@ endif
 
 libgit_rs = custom_target('git_rs',
   input: libgit_rs_sources + [
-    meson.project_source_root() / 'Cargo.toml',
+    meson.current_source_dir() / 'Cargo.toml',
   ],
   output: 'libgitcore.a',
   command: cargo_command,
@@ -31,7 +31,7 @@ if get_option('tests')
     args: [
       'test',
       '--manifest-path',
-      meson.project_source_root() / 'Cargo.toml',
+      meson.current_source_dir() / 'Cargo.toml',
       '--target-dir',
       meson.current_build_dir() / 'target',
     ],
diff --git a/src/lib.rs b/rust/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to rust/src/lib.rs
diff --git a/src/varint.rs b/rust/src/varint.rs
similarity index 100%
rename from src/varint.rs
rename to rust/src/varint.rs
-- 
2.52.0
Mike HommeySep 9, 2026, 01:38 UTC in reply to Mike Hommey on lore

[PATCH v3] Move rust gitcore crate to a different subdirectory

Having `Cargo.toml` at the top-level of the repository implies that one can run `cargo build` directly, but this doesn't produce anything useful on its own.

Additionally, when including the git source as a submodule of a Rust project, it prevents the git source from being included at all in the crate package because cargo skips directories that contain a Cargo.toml, assuming that everything in the directory is relevant to the crate.

This moves all Rust-specific files into a dedicated `rust/` subdirectory.

Signed-off-by: Mike Hommey <mh@glandium.org>
---
 .gitignore                     |  2 ++
 Makefile                       | 26 ++++++++++++++------------
 meson.build                    |  2 +-
 Cargo.toml => rust/Cargo.toml  |  0
 {src => rust}/cargo-meson.sh   |  0
 {src => rust}/meson.build      |  6 +++---
 {src => rust/src}/csum_file.rs |  0
 {src => rust/src}/hash.rs      |  0
 {src => rust/src}/lib.rs       |  0
 {src => rust/src}/loose.rs     |  0
 {src => rust/src}/varint.rs    |  0
 11 files changed, 20 insertions(+), 16 deletions(-)
 rename Cargo.toml => rust/Cargo.toml (100%)
 rename {src => rust}/cargo-meson.sh (100%)
 rename {src => rust}/meson.build (88%)
 rename {src => rust/src}/csum_file.rs (100%)
 rename {src => rust/src}/hash.rs (100%)
 rename {src => rust/src}/lib.rs (100%)
 rename {src => rust/src}/loose.rs (100%)
 rename {src => rust/src}/varint.rs (100%)
Show changes to 12 files +20 −16

.gitignore, Makefile, meson.build, Cargo.toml, src/cargo-meson.sh, src/meson.build, rust/meson.build, src/csum_file.rs, src/hash.rs, src/lib.rs, src/loose.rs, src/varint.rs

diff --git a/.gitignore b/.gitignore
index 4da58c6754..3ac0685800 100644
--- a/.gitignore
+++ b/.gitignore
@@ -261,3 +261,5 @@ Release/
 /contrib/buildsystems/out
 /contrib/libgit-rs/target
 /contrib/libgit-sys/target
+/rust/target
+/rust/Cargo.lock
diff --git a/Makefile b/Makefile
index d4b775953d..7991fa378d 100644
--- a/Makefile
+++ b/Makefile
@@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib
 else
 RUST_LIB_NAME = libgitcore.a
 endif
-RUST_LIB = target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
+RUST_LIB = rust/target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
 endif
 
 GITLIBS = common-main.o $(LIB_FILE)
@@ -1571,11 +1571,13 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
 
 UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
 
-RUST_SOURCES += src/csum_file.rs
-RUST_SOURCES += src/hash.rs
-RUST_SOURCES += src/lib.rs
-RUST_SOURCES += src/loose.rs
-RUST_SOURCES += src/varint.rs
+RUST_SOURCES += rust/src/csum_file.rs
+RUST_SOURCES += rust/src/hash.rs
+RUST_SOURCES += rust/src/lib.rs
+RUST_SOURCES += rust/src/loose.rs
+RUST_SOURCES += rust/src/varint.rs
+RUST_SOURCES += rust/src/lib.rs
+RUST_SOURCES += rust/src/varint.rs
 
 GIT-VERSION-FILE: FORCE
 	@OLD=$$(cat $@ 2>/dev/null || :) && \
@@ -3038,8 +3040,8 @@ $(LIB_FILE): $(LIB_OBJS)
 
 ifndef NO_RUST
 ifeq ($(RUST_TARGETS),)
-$(RUST_LIB): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
+$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
 else
 ifneq ($(words $(RUST_TARGETS)),1)
 ifneq ($(uname_S),Darwin)
@@ -3047,9 +3049,9 @@ $(error Building universal Rust libraries requires macOS (lipo is not available
 endif
 endif
 
-RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
-$(RUST_MEMBER_LIBS): target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS) --target $*
+RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),rust/target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
+$(RUST_MEMBER_LIBS): rust/target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS) --target $*
 
 $(RUST_LIB): $(RUST_MEMBER_LIBS)
 	$(call mkdir_p_parent_template)
@@ -3913,7 +3915,7 @@ clean: profile-clean coverage-clean cocciclean
 	$(RM) $(FUZZ_PROGRAMS)
 	$(RM) $(SP_OBJ)
 	$(RM) $(HCC)
-	$(RM) -r Cargo.lock target/
+	$(RM) -r Cargo.lock rust/target/
 	$(RM) version-def.h
 	$(RM) -r $(dep_dirs) $(compdb_dir) compile_commands.json
 	$(RM) $(test_bindir_programs)
diff --git a/meson.build b/meson.build
index d86f2acd2b..b91d30666e 100644
--- a/meson.build
+++ b/meson.build
@@ -1782,7 +1782,7 @@ libgit_sources += version_def_h
 
 rust_option = get_option('rust')
 if rust_option.allowed()
-  subdir('src')
+  subdir('rust/src')
   libgit_c_args += '-DWITH_RUST'
 
   if host_machine.system() == 'windows'
diff --git a/Cargo.toml b/rust/Cargo.toml
similarity index 100%
rename from Cargo.toml
rename to rust/Cargo.toml
diff --git a/src/cargo-meson.sh b/rust/cargo-meson.sh
similarity index 100%
rename from src/cargo-meson.sh
rename to rust/cargo-meson.sh
diff --git a/src/meson.build b/rust/meson.build
similarity index 88%
rename from src/meson.build
rename to rust/meson.build
index 41a4b231e6..495931f75a 100644
--- a/src/meson.build
+++ b/rust/meson.build
@@ -13,7 +13,7 @@ libgit_rs_sources = [
 cargo_command = [
   shell,
   meson.current_source_dir() / 'cargo-meson.sh',
-  meson.project_source_root(),
+  meson.current_source_dir(),
   meson.current_build_dir(),
 ]
 if get_option('buildtype') == 'release'
@@ -22,7 +22,7 @@ endif
 
 libgit_rs = custom_target('git_rs',
   input: libgit_rs_sources + [
-    meson.project_source_root() / 'Cargo.toml',
+    meson.current_source_dir() / 'Cargo.toml',
   ],
   output: 'libgitcore.a',
   command: cargo_command,
@@ -35,7 +35,7 @@ if get_option('tests')
     args: [
       'test',
       '--manifest-path',
-      meson.project_source_root() / 'Cargo.toml',
+      meson.current_source_dir() / 'Cargo.toml',
       '--target-dir',
       meson.current_build_dir() / 'target',
     ],
diff --git a/src/csum_file.rs b/rust/src/csum_file.rs
similarity index 100%
rename from src/csum_file.rs
rename to rust/src/csum_file.rs
diff --git a/src/hash.rs b/rust/src/hash.rs
similarity index 100%
rename from src/hash.rs
rename to rust/src/hash.rs
diff --git a/src/lib.rs b/rust/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to rust/src/lib.rs
diff --git a/src/loose.rs b/rust/src/loose.rs
similarity index 100%
rename from src/loose.rs
rename to rust/src/loose.rs
diff --git a/src/varint.rs b/rust/src/varint.rs
similarity index 100%
rename from src/varint.rs
rename to rust/src/varint.rs
-- 
2.55.0.806.gb8242b093d.dirty
Junio C HamanoSep 9, 2026, 19:54 UTC in reply to Mike Hommey on lore

Re: [PATCH v3] Move rust gitcore crate to a different subdirectory

Mike Hommey <mh@glandium.org> writes:
Show 12 quoted lines
> 
> Having `Cargo.toml` at the top-level of the repository implies that one
> can run `cargo build` directly, but this doesn't produce anything useful
> on its own.
>
> Additionally, when including the git source as a submodule of a Rust
> project, it prevents the git source from being included at all in the
> crate package because cargo skips directories that contain a Cargo.toml,
> assuming that everything in the directory is relevant to the crate.
>
> This moves all Rust-specific files into a dedicated `rust/`
> subdirectory.

Very readable and understandable. It is customary in this project to write that last sentence in imperative mood, though. I.e. "Move all files there".

> Signed-off-by: Mike Hommey <mh@glandium.org>
Show 10 quoted lines
> diff --git a/.gitignore b/.gitignore
> index 4da58c6754..3ac0685800 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -261,3 +261,5 @@ Release/
>  /contrib/buildsystems/out
>  /contrib/libgit-rs/target
>  /contrib/libgit-sys/target
> +/rust/target
> +/rust/Cargo.lock

There are /target/ and /Cargo.lock listed in this file; aren't these two entries meant to _replace_ them? I am wondering if they need to disappear as part of this patfch.

Show 13 quoted lines
> diff --git a/Makefile b/Makefile
> index d4b775953d..7991fa378d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1571,11 +1571,13 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
>  
>  UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
>  
> -RUST_SOURCES += src/csum_file.rs
> -RUST_SOURCES += src/hash.rs
> -RUST_SOURCES += src/lib.rs
> -RUST_SOURCES += src/loose.rs
> -RUST_SOURCES += src/varint.rs
Show 7 quoted lines
> +RUST_SOURCES += rust/src/csum_file.rs
> +RUST_SOURCES += rust/src/hash.rs
> +RUST_SOURCES += rust/src/lib.rs
> +RUST_SOURCES += rust/src/loose.rs
> +RUST_SOURCES += rust/src/varint.rs
> +RUST_SOURCES += rust/src/lib.rs
> +RUST_SOURCES += rust/src/varint.rs

Two files, lib and varint, are listed twice here. A rebase error or something?

Show 6 quoted lines
> @@ -3913,7 +3915,7 @@ clean: profile-clean coverage-clean cocciclean
>  	$(RM) $(FUZZ_PROGRAMS)
>  	$(RM) $(SP_OBJ)
>  	$(RM) $(HCC)
> -	$(RM) -r Cargo.lock target/
> +	$(RM) -r Cargo.lock rust/target/

The Cargo.lock file does not move together with the rest? That contradicts with what .gitignore says, doesn't it?

brian m. carlsonSep 9, 2026, 21:13 UTC in reply to Mike Hommey on lore

Re: [PATCH v3] Move rust gitcore crate to a different subdirectory

On 2026-09-09 at 01:38:58, Mike Hommey wrote:
Show 8 quoted lines
> Having `Cargo.toml` at the top-level of the repository implies that one
> can run `cargo build` directly, but this doesn't produce anything useful
> on its own.
> 
> Additionally, when including the git source as a submodule of a Rust
> project, it prevents the git source from being included at all in the
> crate package because cargo skips directories that contain a Cargo.toml,
> assuming that everything in the directory is relevant to the crate.

So what I understand is that you have a project which has Git as a submodule and you want to include the Git source code into the crate package for that project. In other words, you're vendoring Git to use its C components, but not its Rust components.

If that's the case, how do you plan that to work in a few releases when Git 3.0 comes out and the Rust components become mandatory? If you don't plan for it to work, wouldn't it be better to adopt a different strategy now rather than implementing a workaround that will be broken in a short time?

-- 
brian m. carlson (they/them)
Toronto, Ontario, CA
Tuomas AholaSep 10, 2026, 06:27 UTC in reply to Mike Hommey on lore

Re: [PATCH v3] Move rust gitcore crate to a different subdirectory

Mike Hommey <mh@glandium.org> wrote:
> [...]
Show 12 quoted lines
> diff --git a/meson.build b/meson.build
> index d86f2acd2b..b91d30666e 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1782,7 +1782,7 @@ libgit_sources += version_def_h
>  
>  rust_option = get_option('rust')
>  if rust_option.allowed()
> -  subdir('src')
> +  subdir('rust/src')
>    libgit_c_args += '-DWITH_RUST'
>  
I think that's bound to fail---there's no meson.build in rust/src, right?
--Tuomas
Mike HommeySep 10, 2026, 12:05 UTC in reply to brian m. carlson on lore

Re: [PATCH v3] Move rust gitcore crate to a different subdirectory

On Wed, Sep 09, 2026 at 09:13:49PM +0000, brian m. carlson wrote:
Show 14 quoted lines
> On 2026-09-09 at 01:38:58, Mike Hommey wrote:
> > Having `Cargo.toml` at the top-level of the repository implies that one
> > can run `cargo build` directly, but this doesn't produce anything useful
> > on its own.
> > 
> > Additionally, when including the git source as a submodule of a Rust
> > project, it prevents the git source from being included at all in the
> > crate package because cargo skips directories that contain a Cargo.toml,
> > assuming that everything in the directory is relevant to the crate.
> 
> So what I understand is that you have a project which has Git as a
> submodule and you want to include the Git source code into the crate
> package for that project.  In other words, you're vendoring Git to use
> its C components, but not its Rust components.
Indeed.
> If that's the case, how do you plan that to work in a few releases when
> Git 3.0 comes out and the Rust components become mandatory?

Assuming the crate doesn't grow to the point of adding a dependency on libgit-rs or libgit-sys, I'm thinking of publishing the gitcore crate to crates.io in a namespaced manner (although if it could be published by the git project that would be even better).

Mike
Mike HommeySep 10, 2026, 12:09 UTC in reply to Junio C Hamano on lore

Re: [PATCH v3] Move rust gitcore crate to a different subdirectory

On Wed, Sep 09, 2026 at 12:54:35PM -0700, Junio C Hamano wrote:
Show 35 quoted lines
> Mike Hommey <mh@glandium.org> writes:
> > 
> > Having `Cargo.toml` at the top-level of the repository implies that one
> > can run `cargo build` directly, but this doesn't produce anything useful
> > on its own.
> >
> > Additionally, when including the git source as a submodule of a Rust
> > project, it prevents the git source from being included at all in the
> > crate package because cargo skips directories that contain a Cargo.toml,
> > assuming that everything in the directory is relevant to the crate.
> >
> > This moves all Rust-specific files into a dedicated `rust/`
> > subdirectory.
> 
> Very readable and understandable.  It is customary in this project
> to write that last sentence in imperative mood, though.  I.e.  "Move
> all files there".
> 
> > Signed-off-by: Mike Hommey <mh@glandium.org>
> 
> 
> > diff --git a/.gitignore b/.gitignore
> > index 4da58c6754..3ac0685800 100644
> > --- a/.gitignore
> > +++ b/.gitignore
> > @@ -261,3 +261,5 @@ Release/
> >  /contrib/buildsystems/out
> >  /contrib/libgit-rs/target
> >  /contrib/libgit-sys/target
> > +/rust/target
> > +/rust/Cargo.lock
> 
> There are /target/ and /Cargo.lock listed in this file; aren't these
> two entries meant to _replace_ them?  I am wondering if they need to
> disappear as part of this patfch.

This and the RUST_SOURCES thing you raised are rebase errors, apparently.

Show 9 quoted lines
> > @@ -3913,7 +3915,7 @@ clean: profile-clean coverage-clean cocciclean
> >  	$(RM) $(FUZZ_PROGRAMS)
> >  	$(RM) $(SP_OBJ)
> >  	$(RM) $(HCC)
> > -	$(RM) -r Cargo.lock target/
> > +	$(RM) -r Cargo.lock rust/target/
> 
> The Cargo.lock file does not move together with the rest?  That
> contradicts with what .gitignore says, doesn't it?
Huh, thanks for noticing this one.
Mike
Mike HommeySep 10, 2026, 12:10 UTC in reply to Mike Hommey on lore

[PATCH v4] Move rust gitcore crate to a different subdirectory

Having `Cargo.toml` at the top-level of the repository implies that one can run `cargo build` directly, but this doesn't produce anything useful on its own.

Additionally, when including the git source as a submodule of a Rust project, it prevents the git source from being included at all in the crate package because cargo skips directories that contain a Cargo.toml, assuming that everything in the directory is relevant to the crate.

Move all Rust-specific files into a dedicated `rust/` subdirectory.
Signed-off-by: Mike Hommey <mh@glandium.org>
---
 .gitignore                     |  4 ++--
 Makefile                       | 24 ++++++++++++------------
 meson.build                    |  2 +-
 Cargo.toml => rust/Cargo.toml  |  0
 build.rs => rust/build.rs      |  0
 {src => rust}/cargo-meson.sh   |  0
 {src => rust}/meson.build      | 16 ++++++++--------
 {src => rust/src}/csum_file.rs |  0
 {src => rust/src}/hash.rs      |  0
 {src => rust/src}/lib.rs       |  0
 {src => rust/src}/loose.rs     |  0
 {src => rust/src}/varint.rs    |  0
 12 files changed, 23 insertions(+), 23 deletions(-)
 rename Cargo.toml => rust/Cargo.toml (100%)
 rename build.rs => rust/build.rs (100%)
 rename {src => rust}/cargo-meson.sh (100%)
 rename {src => rust}/meson.build (81%)
 rename {src => rust/src}/csum_file.rs (100%)
 rename {src => rust/src}/hash.rs (100%)
 rename {src => rust/src}/lib.rs (100%)
 rename {src => rust/src}/loose.rs (100%)
 rename {src => rust/src}/varint.rs (100%)
Show changes to 13 files +23 −23

.gitignore, Makefile, meson.build, Cargo.toml, build.rs, src/cargo-meson.sh, src/meson.build, rust/meson.build, src/csum_file.rs, src/hash.rs, src/lib.rs, src/loose.rs, src/varint.rs

diff --git a/.gitignore b/.gitignore
index 4da58c6754..add6597643 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
 /fuzz_corpora
-/target/
-/Cargo.lock
 /GIT-BUILD-DIR
 /GIT-BUILD-OPTIONS
 /GIT-CFLAGS
@@ -261,3 +259,5 @@ Release/
 /contrib/buildsystems/out
 /contrib/libgit-rs/target
 /contrib/libgit-sys/target
+/rust/target
+/rust/Cargo.lock
diff --git a/Makefile b/Makefile
index d4b775953d..38dc3cc548 100644
--- a/Makefile
+++ b/Makefile
@@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib
 else
 RUST_LIB_NAME = libgitcore.a
 endif
-RUST_LIB = target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
+RUST_LIB = rust/target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
 endif
 
 GITLIBS = common-main.o $(LIB_FILE)
@@ -1571,11 +1571,11 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
 
 UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
 
-RUST_SOURCES += src/csum_file.rs
-RUST_SOURCES += src/hash.rs
-RUST_SOURCES += src/lib.rs
-RUST_SOURCES += src/loose.rs
-RUST_SOURCES += src/varint.rs
+RUST_SOURCES += rust/src/csum_file.rs
+RUST_SOURCES += rust/src/hash.rs
+RUST_SOURCES += rust/src/lib.rs
+RUST_SOURCES += rust/src/loose.rs
+RUST_SOURCES += rust/src/varint.rs
 
 GIT-VERSION-FILE: FORCE
 	@OLD=$$(cat $@ 2>/dev/null || :) && \
@@ -3038,8 +3038,8 @@ $(LIB_FILE): $(LIB_OBJS)
 
 ifndef NO_RUST
 ifeq ($(RUST_TARGETS),)
-$(RUST_LIB): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
+$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
 else
 ifneq ($(words $(RUST_TARGETS)),1)
 ifneq ($(uname_S),Darwin)
@@ -3047,9 +3047,9 @@ $(error Building universal Rust libraries requires macOS (lipo is not available
 endif
 endif
 
-RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
-$(RUST_MEMBER_LIBS): target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS) --target $*
+RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),rust/target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
+$(RUST_MEMBER_LIBS): rust/target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS) --target $*
 
 $(RUST_LIB): $(RUST_MEMBER_LIBS)
 	$(call mkdir_p_parent_template)
@@ -3913,7 +3913,7 @@ clean: profile-clean coverage-clean cocciclean
 	$(RM) $(FUZZ_PROGRAMS)
 	$(RM) $(SP_OBJ)
 	$(RM) $(HCC)
-	$(RM) -r Cargo.lock target/
+	$(RM) -r rust/Cargo.lock rust/target/
 	$(RM) version-def.h
 	$(RM) -r $(dep_dirs) $(compdb_dir) compile_commands.json
 	$(RM) $(test_bindir_programs)
diff --git a/meson.build b/meson.build
index d86f2acd2b..c7ff7c2a73 100644
--- a/meson.build
+++ b/meson.build
@@ -1782,7 +1782,7 @@ libgit_sources += version_def_h
 
 rust_option = get_option('rust')
 if rust_option.allowed()
-  subdir('src')
+  subdir('rust')
   libgit_c_args += '-DWITH_RUST'
 
   if host_machine.system() == 'windows'
diff --git a/Cargo.toml b/rust/Cargo.toml
similarity index 100%
rename from Cargo.toml
rename to rust/Cargo.toml
diff --git a/build.rs b/rust/build.rs
similarity index 100%
rename from build.rs
rename to rust/build.rs
diff --git a/src/cargo-meson.sh b/rust/cargo-meson.sh
similarity index 100%
rename from src/cargo-meson.sh
rename to rust/cargo-meson.sh
diff --git a/src/meson.build b/rust/meson.build
similarity index 81%
rename from src/meson.build
rename to rust/meson.build
index 41a4b231e6..4c617371a5 100644
--- a/src/meson.build
+++ b/rust/meson.build
@@ -1,9 +1,9 @@
 libgit_rs_sources = [
-  'csum_file.rs',
-  'hash.rs',
-  'lib.rs',
-  'loose.rs',
-  'varint.rs',
+  'src/csum_file.rs',
+  'src/hash.rs',
+  'src/lib.rs',
+  'src/loose.rs',
+  'src/varint.rs',
 ]
 
 # Unfortunately we must use a wrapper command to move the output file into the
@@ -13,7 +13,7 @@ libgit_rs_sources = [
 cargo_command = [
   shell,
   meson.current_source_dir() / 'cargo-meson.sh',
-  meson.project_source_root(),
+  meson.current_source_dir(),
   meson.current_build_dir(),
 ]
 if get_option('buildtype') == 'release'
@@ -22,7 +22,7 @@ endif
 
 libgit_rs = custom_target('git_rs',
   input: libgit_rs_sources + [
-    meson.project_source_root() / 'Cargo.toml',
+    meson.current_source_dir() / 'Cargo.toml',
   ],
   output: 'libgitcore.a',
   command: cargo_command,
@@ -35,7 +35,7 @@ if get_option('tests')
     args: [
       'test',
       '--manifest-path',
-      meson.project_source_root() / 'Cargo.toml',
+      meson.current_source_dir() / 'Cargo.toml',
       '--target-dir',
       meson.current_build_dir() / 'target',
     ],
diff --git a/src/csum_file.rs b/rust/src/csum_file.rs
similarity index 100%
rename from src/csum_file.rs
rename to rust/src/csum_file.rs
diff --git a/src/hash.rs b/rust/src/hash.rs
similarity index 100%
rename from src/hash.rs
rename to rust/src/hash.rs
diff --git a/src/lib.rs b/rust/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to rust/src/lib.rs
diff --git a/src/loose.rs b/rust/src/loose.rs
similarity index 100%
rename from src/loose.rs
rename to rust/src/loose.rs
diff --git a/src/varint.rs b/rust/src/varint.rs
similarity index 100%
rename from src/varint.rs
rename to rust/src/varint.rs
-- 
2.55.0.807.gc06c3eb732
Junio C HamanoSep 10, 2026, 12:21 UTC in reply to Tuomas Ahola on lore

Re: [PATCH v3] Move rust gitcore crate to a different subdirectory

Tuomas Ahola <taahol@utu.fi> writes:
Show 18 quoted lines
> Mike Hommey <mh@glandium.org> wrote:
>
>> [...]
>
>> diff --git a/meson.build b/meson.build
>> index d86f2acd2b..b91d30666e 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -1782,7 +1782,7 @@ libgit_sources += version_def_h
>>  
>>  rust_option = get_option('rust')
>>  if rust_option.allowed()
>> -  subdir('src')
>> +  subdir('rust/src')
>>    libgit_c_args += '-DWITH_RUST'
>>  
>
> I think that's bound to fail---there's no meson.build in rust/src, right?

Thanks for catching it. Indeed our CI builds are failing since this topic was injested in 'seen'.

Will kick it out and wait for updates.
Thanks.
Junio C HamanoSep 10, 2026, 17:45 UTC in reply to Mike Hommey on lore

Re: [PATCH v4] Move rust gitcore crate to a different subdirectory

Mike Hommey <mh@glandium.org> writes:
> Subject: Re: [PATCH v4] Move rust gitcore crate to a different subdirectory
Documentation/SubmittingPatches::[[summary-section]]
Show 13 quoted lines
> Having `Cargo.toml` at the top-level of the repository implies that one
> can run `cargo build` directly, but this doesn't produce anything useful
> on its own.
>
> Additionally, when including the git source as a submodule of a Rust
> project, it prevents the git source from being included at all in the
> crate package because cargo skips directories that contain a Cargo.toml,
> assuming that everything in the directory is relevant to the crate.
>
> Move all Rust-specific files into a dedicated `rust/` subdirectory.
>
> Signed-off-by: Mike Hommey <mh@glandium.org>
> ---
This still leaves the source tree in somewhat inconsistent state.
https://github.com/git/git/actions/runs/34505483626/job/102966561269#step:5:120

I do not offhand know if ci/run-rust-checks.sh needs updating or the moving of files needs tweaking to avoid the breakage, though.

Mike HommeySep 17, 2026, 06:04 UTC in reply to Junio C Hamano on lore

[PATCH v5] move rust gitcore crate to a different subdirectory

Having `Cargo.toml` at the top-level of the repository implies that one can run `cargo build` directly, but this doesn't produce anything useful on its own.

Additionally, when including the git source as a submodule of a Rust project, it prevents the git source from being included at all in the crate package because cargo skips directories that contain a Cargo.toml, assuming that everything in the directory is relevant to the crate.

Move all Rust-specific files into a dedicated `rust/` subdirectory.
Signed-off-by: Mike Hommey <mh@glandium.org>
---
 .gitignore                     |  4 ++--
 Makefile                       | 24 ++++++++++++------------
 ci/run-rust-checks.sh          |  6 +++---
 meson.build                    |  2 +-
 Cargo.toml => rust/Cargo.toml  |  0
 build.rs => rust/build.rs      |  0
 {src => rust}/cargo-meson.sh   |  0
 {src => rust}/meson.build      | 16 ++++++++--------
 {src => rust/src}/csum_file.rs |  0
 {src => rust/src}/hash.rs      |  0
 {src => rust/src}/lib.rs       |  0
 {src => rust/src}/loose.rs     |  0
 {src => rust/src}/varint.rs    |  0
 13 files changed, 26 insertions(+), 26 deletions(-)
 rename Cargo.toml => rust/Cargo.toml (100%)
 rename build.rs => rust/build.rs (100%)
 rename {src => rust}/cargo-meson.sh (100%)
 rename {src => rust}/meson.build (81%)
 rename {src => rust/src}/csum_file.rs (100%)
 rename {src => rust/src}/hash.rs (100%)
 rename {src => rust/src}/lib.rs (100%)
 rename {src => rust/src}/loose.rs (100%)
 rename {src => rust/src}/varint.rs (100%)
Show changes to 14 files +26 −26

.gitignore, Makefile, ci/run-rust-checks.sh, meson.build, Cargo.toml, build.rs, src/cargo-meson.sh, src/meson.build, rust/meson.build, src/csum_file.rs, src/hash.rs, src/lib.rs, src/loose.rs, src/varint.rs

diff --git a/.gitignore b/.gitignore
index 4da58c6754..add6597643 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
 /fuzz_corpora
-/target/
-/Cargo.lock
 /GIT-BUILD-DIR
 /GIT-BUILD-OPTIONS
 /GIT-CFLAGS
@@ -261,3 +259,5 @@ Release/
 /contrib/buildsystems/out
 /contrib/libgit-rs/target
 /contrib/libgit-sys/target
+/rust/target
+/rust/Cargo.lock
diff --git a/Makefile b/Makefile
index c649c93c51..67e74c30cc 100644
--- a/Makefile
+++ b/Makefile
@@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib
 else
 RUST_LIB_NAME = libgitcore.a
 endif
-RUST_LIB = target$(if $(CARGO_BUILD_TARGET),/$(CARGO_BUILD_TARGET))/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
+RUST_LIB = rust/target$(if $(CARGO_BUILD_TARGET),/$(CARGO_BUILD_TARGET))/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
 endif
 
 GITLIBS = common-main.o $(LIB_FILE)
@@ -1571,11 +1571,11 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
 
 UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
 
-RUST_SOURCES += src/csum_file.rs
-RUST_SOURCES += src/hash.rs
-RUST_SOURCES += src/lib.rs
-RUST_SOURCES += src/loose.rs
-RUST_SOURCES += src/varint.rs
+RUST_SOURCES += rust/src/csum_file.rs
+RUST_SOURCES += rust/src/hash.rs
+RUST_SOURCES += rust/src/lib.rs
+RUST_SOURCES += rust/src/loose.rs
+RUST_SOURCES += rust/src/varint.rs
 
 GIT-VERSION-FILE: FORCE
 	@OLD=$$(cat $@ 2>/dev/null || :) && \
@@ -3038,8 +3038,8 @@ $(LIB_FILE): $(LIB_OBJS)
 
 ifndef NO_RUST
 ifeq ($(RUST_TARGETS),)
-$(RUST_LIB): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
+$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
 else
 ifneq ($(words $(RUST_TARGETS)),1)
 ifneq ($(uname_S),Darwin)
@@ -3047,9 +3047,9 @@ $(error Building universal Rust libraries requires macOS (lipo is not available
 endif
 endif
 
-RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
-$(RUST_MEMBER_LIBS): target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
-	$(QUIET_CARGO)cargo build $(CARGO_ARGS) --target $*
+RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),rust/target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
+$(RUST_MEMBER_LIBS): rust/target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
+	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS) --target $*
 
 $(RUST_LIB): $(RUST_MEMBER_LIBS)
 	$(call mkdir_p_parent_template)
@@ -3913,7 +3913,7 @@ clean: profile-clean coverage-clean cocciclean
 	$(RM) $(FUZZ_PROGRAMS)
 	$(RM) $(SP_OBJ)
 	$(RM) $(HCC)
-	$(RM) -r Cargo.lock target/
+	$(RM) -r rust/Cargo.lock rust/target/
 	$(RM) version-def.h
 	$(RM) -r $(dep_dirs) $(compdb_dir) compile_commands.json
 	$(RM) $(test_bindir_programs)
diff --git a/ci/run-rust-checks.sh b/ci/run-rust-checks.sh
index b5ad9e8dc6..47fccc3a02 100755
--- a/ci/run-rust-checks.sh
+++ b/ci/run-rust-checks.sh
@@ -4,17 +4,17 @@
 
 set +x
 
-if ! group "Check Rust formatting" cargo fmt --all --check
+if ! group "Check Rust formatting" cargo fmt --manifest-path rust/Cargo.toml --all --check
 then
 	RET=1
 fi
 
-if ! group "Check for common Rust mistakes" cargo clippy --all-targets --all-features -- -Dwarnings
+if ! group "Check for common Rust mistakes" cargo clippy --manifest-path rust/Cargo.toml --all-targets --all-features -- -Dwarnings
 then
 	RET=1
 fi
 
-if ! group "Check for minimum required Rust version" cargo msrv verify
+if ! group "Check for minimum required Rust version" cargo msrv --path rust verify
 then
 	RET=1
 fi
diff --git a/meson.build b/meson.build
index 0a95d90d21..432e306b21 100644
--- a/meson.build
+++ b/meson.build
@@ -1795,7 +1795,7 @@ libgit_sources += version_def_h
 
 rust_option = get_option('rust')
 if rust_option.allowed()
-  subdir('src')
+  subdir('rust')
   libgit_c_args += '-DWITH_RUST'
 
   if host_machine.system() == 'windows'
diff --git a/Cargo.toml b/rust/Cargo.toml
similarity index 100%
rename from Cargo.toml
rename to rust/Cargo.toml
diff --git a/build.rs b/rust/build.rs
similarity index 100%
rename from build.rs
rename to rust/build.rs
diff --git a/src/cargo-meson.sh b/rust/cargo-meson.sh
similarity index 100%
rename from src/cargo-meson.sh
rename to rust/cargo-meson.sh
diff --git a/src/meson.build b/rust/meson.build
similarity index 81%
rename from src/meson.build
rename to rust/meson.build
index 41a4b231e6..4c617371a5 100644
--- a/src/meson.build
+++ b/rust/meson.build
@@ -1,9 +1,9 @@
 libgit_rs_sources = [
-  'csum_file.rs',
-  'hash.rs',
-  'lib.rs',
-  'loose.rs',
-  'varint.rs',
+  'src/csum_file.rs',
+  'src/hash.rs',
+  'src/lib.rs',
+  'src/loose.rs',
+  'src/varint.rs',
 ]
 
 # Unfortunately we must use a wrapper command to move the output file into the
@@ -13,7 +13,7 @@ libgit_rs_sources = [
 cargo_command = [
   shell,
   meson.current_source_dir() / 'cargo-meson.sh',
-  meson.project_source_root(),
+  meson.current_source_dir(),
   meson.current_build_dir(),
 ]
 if get_option('buildtype') == 'release'
@@ -22,7 +22,7 @@ endif
 
 libgit_rs = custom_target('git_rs',
   input: libgit_rs_sources + [
-    meson.project_source_root() / 'Cargo.toml',
+    meson.current_source_dir() / 'Cargo.toml',
   ],
   output: 'libgitcore.a',
   command: cargo_command,
@@ -35,7 +35,7 @@ if get_option('tests')
     args: [
       'test',
       '--manifest-path',
-      meson.project_source_root() / 'Cargo.toml',
+      meson.current_source_dir() / 'Cargo.toml',
       '--target-dir',
       meson.current_build_dir() / 'target',
     ],
diff --git a/src/csum_file.rs b/rust/src/csum_file.rs
similarity index 100%
rename from src/csum_file.rs
rename to rust/src/csum_file.rs
diff --git a/src/hash.rs b/rust/src/hash.rs
similarity index 100%
rename from src/hash.rs
rename to rust/src/hash.rs
diff --git a/src/lib.rs b/rust/src/lib.rs
similarity index 100%
rename from src/lib.rs
rename to rust/src/lib.rs
diff --git a/src/loose.rs b/rust/src/loose.rs
similarity index 100%
rename from src/loose.rs
rename to rust/src/loose.rs
diff --git a/src/varint.rs b/rust/src/varint.rs
similarity index 100%
rename from src/varint.rs
rename to rust/src/varint.rs
-- 
2.55.0.807.gc06c3eb732
Junio C HamanoSep 18, 2026, 08:20 UTC in reply to Mike Hommey on lore

Re: [PATCH v5] move rust gitcore crate to a different subdirectory

Mike Hommey <mh@glandium.org> writes:
Show 13 quoted lines
> Having `Cargo.toml` at the top-level of the repository implies that one
> can run `cargo build` directly, but this doesn't produce anything useful
> on its own.
>
> Additionally, when including the git source as a submodule of a Rust
> project, it prevents the git source from being included at all in the
> crate package because cargo skips directories that contain a Cargo.toml,
> assuming that everything in the directory is relevant to the crate.
>
> Move all Rust-specific files into a dedicated `rust/` subdirectory.
>
> Signed-off-by: Mike Hommey <mh@glandium.org>
> ---

It would have been a friendly thing to do to describe what base was chosen, especially with a few other topics in flight that touch the build procedure for Rust part of the system recently, here below the three-dash line.

It seems that this patch is designed to apply cleanly on top of Git 2.56-rc1, which already has these topics merged, so I do not have to worry about conflicts with them when queueing this patch, which is good.

Show 23 quoted lines
>  .gitignore                     |  4 ++--
>  Makefile                       | 24 ++++++++++++------------
>  ci/run-rust-checks.sh          |  6 +++---
>  meson.build                    |  2 +-
>  Cargo.toml => rust/Cargo.toml  |  0
>  build.rs => rust/build.rs      |  0
>  {src => rust}/cargo-meson.sh   |  0
>  {src => rust}/meson.build      | 16 ++++++++--------
>  {src => rust/src}/csum_file.rs |  0
>  {src => rust/src}/hash.rs      |  0
>  {src => rust/src}/lib.rs       |  0
>  {src => rust/src}/loose.rs     |  0
>  {src => rust/src}/varint.rs    |  0
>  13 files changed, 26 insertions(+), 26 deletions(-)
>  rename Cargo.toml => rust/Cargo.toml (100%)
>  rename build.rs => rust/build.rs (100%)
>  rename {src => rust}/cargo-meson.sh (100%)
>  rename {src => rust}/meson.build (81%)
>  rename {src => rust/src}/csum_file.rs (100%)
>  rename {src => rust/src}/hash.rs (100%)
>  rename {src => rust/src}/lib.rs (100%)
>  rename {src => rust/src}/loose.rs (100%)
>  rename {src => rust/src}/varint.rs (100%)

So things in src/ move to either rust/ directory or rust/src/ directory.

Show 11 quoted lines
> diff --git a/Makefile b/Makefile
> index c649c93c51..67e74c30cc 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib
>  else
>  RUST_LIB_NAME = libgitcore.a
>  endif
> -RUST_LIB = target$(if $(CARGO_BUILD_TARGET),/$(CARGO_BUILD_TARGET))/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
> +RUST_LIB = rust/target$(if $(CARGO_BUILD_TARGET),/$(CARGO_BUILD_TARGET))/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
>  endif

This part was touched by a few topics in the recent past and I didn't want to resolve conflicts there. This patch being on top of these two topics makes my life easier and is very much appreciated.

Show 14 quoted lines
> @@ -1571,11 +1571,11 @@ CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o
>  
>  UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
>  
> -RUST_SOURCES += src/csum_file.rs
> -RUST_SOURCES += src/hash.rs
> -RUST_SOURCES += src/lib.rs
> -RUST_SOURCES += src/loose.rs
> -RUST_SOURCES += src/varint.rs
> +RUST_SOURCES += rust/src/csum_file.rs
> +RUST_SOURCES += rust/src/hash.rs
> +RUST_SOURCES += rust/src/lib.rs
> +RUST_SOURCES += rust/src/loose.rs
> +RUST_SOURCES += rust/src/varint.rs
So the sources are all in rust/src/ directory now.
Show 11 quoted lines
> -$(RUST_LIB): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> -	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
> +$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> +	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
> ...
> -RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
> -$(RUST_MEMBER_LIBS): target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> -	$(QUIET_CARGO)cargo build $(CARGO_ARGS) --target $*
> +RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),rust/target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
> +$(RUST_MEMBER_LIBS): rust/target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> +	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS) --target $*

Is the reason why we now need to sprinkle --manifest-path all over is because rust/Cargo.toml is a non-standard place for cargo tool? Not complaining, but am wondering if it is simpler to set and export CARGO_MANIFEST_DIR from the Makefile.

Show 10 quoted lines
> diff --git a/meson.build b/meson.build
> index 0a95d90d21..432e306b21 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1795,7 +1795,7 @@ libgit_sources += version_def_h
>  
>  rust_option = get_option('rust')
>  if rust_option.allowed()
> -  subdir('src')
> +  subdir('rust')
Not 'rust/src'?  Just double-checking.
Show 8 quoted lines
> @@ -13,7 +13,7 @@ libgit_rs_sources = [
>  cargo_command = [
>    shell,
>    meson.current_source_dir() / 'cargo-meson.sh',
> -  meson.project_source_root(),
> +  meson.current_source_dir(),
>    meson.current_build_dir(),
>  ]
What is this change about?
Mike HommeySep 18, 2026, 15:02 UTC in reply to Junio C Hamano on lore

Re: [PATCH v5] move rust gitcore crate to a different subdirectory

On Fri, Sep 18, 2026 at 01:20:51AM -0700, Junio C Hamano wrote:
Show 9 quoted lines
> It would have been a friendly thing to do to describe what base was
> chosen, especially with a few other topics in flight that touch the
> build procedure for Rust part of the system recently, here below the
> three-dash line.  
> 
> It seems that this patch is designed to apply cleanly on top of Git
> 2.56-rc1, which already has these topics merged, so I do not have to
> worry about conflicts with them when queueing this patch, which is
> good.

I must admit I hadn't given much thought about where this would be applied, but it was based off master at the time of refreshing the patch, which was, indeed, v2.56.0-rc1.

> So things in src/ move to either rust/ directory or rust/src/
> directory.

Correct. Mostly rs files (except build.rs) move to rust/src/, and the rest to rust/.

Show 16 quoted lines
> > -$(RUST_LIB): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> > -	$(QUIET_CARGO)cargo build $(CARGO_ARGS)
> > +$(RUST_LIB): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> > +	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS)
> > ...
> > -RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
> > -$(RUST_MEMBER_LIBS): target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> > -	$(QUIET_CARGO)cargo build $(CARGO_ARGS) --target $*
> > +RUST_MEMBER_LIBS = $(foreach target,$(RUST_TARGETS),rust/target/$(target)/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME))
> > +$(RUST_MEMBER_LIBS): rust/target/%/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME): rust/Cargo.toml $(RUST_SOURCES) $(LIB_FILE)
> > +	$(QUIET_CARGO)cargo build --manifest-path rust/Cargo.toml $(CARGO_ARGS) --target $*
> 
> Is the reason why we now need to sprinkle --manifest-path all over
> is because rust/Cargo.toml is a non-standard place for cargo tool?
> Not complaining, but am wondering if it is simpler to set and export
> CARGO_MANIFEST_DIR from the Makefile.

It's non-standard in the sense that it's not Cargo.toml is $PWD. An alternative could be to `cd rust` before running cargo commands.

Show 12 quoted lines
> > diff --git a/meson.build b/meson.build
> > index 0a95d90d21..432e306b21 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -1795,7 +1795,7 @@ libgit_sources += version_def_h
> >  
> >  rust_option = get_option('rust')
> >  if rust_option.allowed()
> > -  subdir('src')
> > +  subdir('rust')
> 
> Not 'rust/src'?  Just double-checking.

Not rust/src because the rust meson.build was moved to rust/, not rust/src. It felt like it was in src/ along the .rs files just because there was no other place for it in the first place.

Show 10 quoted lines
> > @@ -13,7 +13,7 @@ libgit_rs_sources = [
> >  cargo_command = [
> >    shell,
> >    meson.current_source_dir() / 'cargo-meson.sh',
> > -  meson.project_source_root(),
> > +  meson.current_source_dir(),
> >    meson.current_build_dir(),
> >  ]
> 
> What is this change about?

IIRC project_source_root is the git top-level directory, and current_source_dir is the one containing meson.build. Keeping project_source_root would put the target directory at the git top-level, which would be different from what the Makefile does (since it doesn't pass a --target-dir)

Mike

Back to recent threads