From 1bc06a2b941dbeef4c52b2c73d659fdd1ed910ba Mon Sep 17 00:00:00 2001 From: "YSTYLE-L.X.Y" Date: Wed, 20 May 2026 15:34:39 +0800 Subject: [PATCH 1/3] add OpenHarmony (OHOS) target support On OpenHarmony the user/process model is sandbox-based. libgit2's owner validation (GIT_OPT_SET_OWNER_VALIDATION) compares file UID with process EUID, which is not applicable and causes spurious "not owned by current user" errors (code=Owner -36). This disables owner validation on all OHOS targets (cfg(target_env = "ohos"): aarch64/armv7/x86_64) via a std::sync::Once in the repository opening entry points. Also adds cross-compilation instructions to CONTRIBUTING.md. --- CONTRIBUTING.md | 29 +++++++++++++++++++++++++++++ asyncgit/src/sync/repository.rs | 19 +++++++++++++++++++ asyncgit/src/sync/utils.rs | 3 +++ 3 files changed, 51 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c443e502a5..e023dbadaf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,5 +22,34 @@ good first issue, you can take a look at [issues labelled with too much context so that people not familiar with the codebase yet can still make a contribution. +## Cross-compiling for OpenHarmony + +GitUI can be built for OpenHarmony (target `aarch64-unknown-linux-ohos`). This requires the [OpenHarmony SDK](https://www.openharmony.cn/) native toolchain. + +First, install the `aarch64-unknown-linux-ohos` Rust target: + +```sh +rustup target add aarch64-unknown-linux-ohos +``` + +Set the following environment variables (adjust paths to your OHOS SDK location): + +```sh +export OHOS_SDK=/path/to/ohos-sdk +export CC_aarch64_unknown_linux_ohos="$OHOS_SDK/native/llvm/bin/clang" +export CXX_aarch64_unknown_linux_ohos="$OHOS_SDK/native/llvm/bin/clang++" +export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_OHOS_LINKER="$OHOS_SDK/native/llvm/bin/clang" +export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_OHOS_AR="$OHOS_SDK/native/llvm/bin/llvm-ar" +export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_OHOS_RUSTFLAGS="-C link-arg=--sysroot=$OHOS_SDK/native/sysroot -C link-arg=-L$OHOS_SDK/native/sysroot/usr/lib/aarch64-linux-ohos -C link-arg=-Wl,--allow-multiple-definition -C link-arg=-Wl,--undefined-version -C link-arg=-Wl,--defsym=__xpg_strerror_r=0" +``` + +Then build: + +```sh +cargo build --target aarch64-unknown-linux-ohos --release +``` + +> **Note:** On OpenHarmony the user/process model is sandbox-based. GitUI automatically disables libgit2's owner validation on OHOS targets to avoid spurious "not owned by current user" errors. + [discord-server]: https://discord.gg/rZv4uxSQx3 [good-first-issues]: https://github.com/gitui-org/gitui/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22 diff --git a/asyncgit/src/sync/repository.rs b/asyncgit/src/sync/repository.rs index c49795fb7c..ecfbcdb55c 100644 --- a/asyncgit/src/sync/repository.rs +++ b/asyncgit/src/sync/repository.rs @@ -7,6 +7,22 @@ use git2::{Repository, RepositoryOpenFlags}; use crate::error::Result; +#[cfg(target_env = "ohos")] +use std::sync::Once; + +#[cfg(target_env = "ohos")] +static INIT_OHOS: Once = Once::new(); + +#[cfg(target_env = "ohos")] +pub(crate) fn init_ohos_owner_validation() { + INIT_OHOS.call_once(|| { + #[allow(unsafe_code)] + unsafe { + git2::opts::set_verify_owner_validation(false).ok(); + } + }); +} + /// pub type RepoPathRef = RefCell; @@ -55,6 +71,9 @@ impl From<&str> for RepoPath { } pub fn repo(repo_path: &RepoPath) -> Result { + #[cfg(target_env = "ohos")] + init_ohos_owner_validation(); + let repo = Repository::open_ext( repo_path.gitpath(), RepositoryOpenFlags::FROM_ENV, diff --git a/asyncgit/src/sync/utils.rs b/asyncgit/src/sync/utils.rs index 148e29baa9..8b15fff54d 100644 --- a/asyncgit/src/sync/utils.rs +++ b/asyncgit/src/sync/utils.rs @@ -26,6 +26,9 @@ pub struct Head { /// pub fn repo_open_error(repo_path: &RepoPath) -> Option { + #[cfg(target_env = "ohos")] + super::repository::init_ohos_owner_validation(); + if let Err(e) = Repository::open_ext( repo_path.gitpath(), RepositoryOpenFlags::FROM_ENV, From 5b1e7565b376e347f867154f6e1489ae687a95f6 Mon Sep 17 00:00:00 2001 From: "YSTYLE-L.X.Y" Date: Wed, 20 May 2026 15:37:49 +0800 Subject: [PATCH 2/3] docs: add OHOS SDK download link and default install paths --- CONTRIBUTING.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e023dbadaf..54a53216c3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,12 @@ make a contribution. ## Cross-compiling for OpenHarmony -GitUI can be built for OpenHarmony (target `aarch64-unknown-linux-ohos`). This requires the [OpenHarmony SDK](https://www.openharmony.cn/) native toolchain. +GitUI can be built for OpenHarmony (target `aarch64-unknown-linux-ohos`). This requires the OpenHarmony SDK native toolchain. + +Download the SDK command-line tools from [HarmonyOS Developer](https://developer.huawei.com/consumer/cn/download/command-line-tools-for-hmos). After installation, the default SDK path is typically: + +- Linux: `~/command-line-tools/sdk/default/openharmony` +- macOS: `~/Library/command-line-tools/sdk/default/openharmony` First, install the `aarch64-unknown-linux-ohos` Rust target: From 621ff5b4bfc392eaa2dfeff83e9e14fb3dd15cad Mon Sep 17 00:00:00 2001 From: "YSTYLE-L.X.Y" Date: Thu, 21 May 2026 21:54:53 +0800 Subject: [PATCH 3/3] fix: use git2-based LogWalker on OHOS to avoid gix InsufficientSlots panic On OpenHarmony, gix-odb fails with InsufficientSlots { current: 32, needed: 4 } when loading pack indices during commit log walking. This happens because LogWalkerWithoutFilter uses gix which has a limited slot map for managing ODB index files. Fall back to git2-based LogWalker on OHOS targets, which can handle both filtered and unfiltered log walking without this issue. --- asyncgit/src/revlog.rs | 64 ++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/asyncgit/src/revlog.rs b/asyncgit/src/revlog.rs index 774d5140ef..93d15c8103 100644 --- a/asyncgit/src/revlog.rs +++ b/asyncgit/src/revlog.rs @@ -1,11 +1,12 @@ use crate::{ error::Result, sync::{ - gix_repo, repo, CommitId, LogWalker, LogWalkerWithoutFilter, - RepoPath, SharedCommitFilterFn, + repo, CommitId, LogWalker, RepoPath, SharedCommitFilterFn, }, AsyncGitNotification, Error, }; +#[cfg(not(target_env = "ohos"))] +use crate::sync::{gix_repo, LogWalkerWithoutFilter}; use crossbeam_channel::Sender; use scopetime::scope_time; use std::{ @@ -200,25 +201,45 @@ impl AsyncLog { sender: &Sender, filter: Option, ) -> Result<()> { - filter.map_or_else( - || { - Self::fetch_helper_without_filter( - repo_path, - arc_current, - arc_background, - sender, - ) - }, - |filter| { - Self::fetch_helper_with_filter( - repo_path, - arc_current, - arc_background, - sender, - filter, - ) - }, - ) + #[cfg(target_env = "ohos")] + { + Self::fetch_helper_with_filter( + repo_path, + arc_current, + arc_background, + sender, + filter.unwrap_or_else(|| { + Arc::new(Box::new( + |_: &git2::Repository, _: &CommitId| { + Ok(true) + }, + )) + }), + ) + } + + #[cfg(not(target_env = "ohos"))] + { + filter.map_or_else( + || { + Self::fetch_helper_without_filter( + repo_path, + arc_current, + arc_background, + sender, + ) + }, + |filter| { + Self::fetch_helper_with_filter( + repo_path, + arc_current, + arc_background, + sender, + filter, + ) + }, + ) + } } fn fetch_helper_with_filter( @@ -265,6 +286,7 @@ impl AsyncLog { Ok(()) } + #[cfg(not(target_env = "ohos"))] fn fetch_helper_without_filter( repo_path: &RepoPath, arc_current: &Arc>,