Source: stgit Version: 2.6.1-1 Severity: important Tags: patch User: [email protected] Usertags: gix-0.86 X-Debbugs-Cc: [email protected]
Dear maintainer, I am preparing a rust-gix transition to 0.86, which will likely be uploaded in the coming days. stgit currently depends on gix 0.83, so it needs a dependency bump and port. I have attached a debdiff fixing this. Best regards, Simon Quigley [email protected]
diff -Nru stgit-2.6.1/debian/changelog stgit-2.6.1/debian/changelog --- stgit-2.6.1/debian/changelog 2026-07-20 12:53:23.000000000 -0500 +++ stgit-2.6.1/debian/changelog 2026-08-20 11:57:19.000000000 -0500 @@ -1,3 +1,10 @@ +stgit (2.6.1-1.1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Port to gix 0.86 via gix-0.86.patch, remove gix 0.83 patch. + + -- Simon Quigley <[email protected]> Thu, 20 Aug 2026 11:57:19 -0500 + stgit (2.6.1-1) unstable; urgency=medium * New upstream release. diff -Nru stgit-2.6.1/debian/control stgit-2.6.1/debian/control --- stgit-2.6.1/debian/control 2026-07-20 12:53:23.000000000 -0500 +++ stgit-2.6.1/debian/control 2026-08-20 11:57:19.000000000 -0500 @@ -24,7 +24,7 @@ librust-curl-dev, librust-encoding-rs-dev, librust-flate2-dev, - librust-gix-dev (>= 0.83), + librust-gix-dev (>= 0.86), librust-indexmap-dev, librust-is-terminal-dev, librust-jiff-dev (>= 0.2.1), diff -Nru stgit-2.6.1/debian/patches/gix-0.86.patch stgit-2.6.1/debian/patches/gix-0.86.patch --- stgit-2.6.1/debian/patches/gix-0.86.patch 1969-12-31 18:00:00.000000000 -0600 +++ stgit-2.6.1/debian/patches/gix-0.86.patch 2026-08-20 11:57:19.000000000 -0500 @@ -0,0 +1,429 @@ +Description: Port to gix 0.86 + Bump the gix crate from 0.84 to 0.86 and update call sites for the + gix-config 0.59 API that gix 0.86 re-exports. A version-only bump does + not compile. + . + gix::config::File no longer takes a lifetime, so File<'static> and + CommitOptions<'_> lose that parameter. Snapshot::string() now returns + Option<BString> rather than Option<Cow<BStr>>, so CommitOptions stores + BString and for_label() takes s.as_ref(). + . + Snapshot::string_by and boolean_by are gone. Look up dotted keys with + string() / boolean() / try_boolean(), which stgit already uses for + keys such as branch.{name}.remote. try_boolean() is Result<Option<bool>> + rather than Option<Result<bool>>, so drop the extra transpose() on the + autostash lookups. + . + SectionRef::num_values() moved to BodyRef (section.body().num_values()). + value_names() yields String rather than BStr, so skip to_str() and pass + the name through to value(). File::rename_section's new subsection is + IntoBStringOpt (Option<BString>), not Option<Cow<BStr>>. + . + Snapshot::trusted_path returns Result<Option<PathBuf>, _> instead of an + Option that needs transpose(). Hook path construction can use PathBuf + directly; editor lookup maps PathBuf with into_os_string(). +Author: Simon Quigley <[email protected]> +Origin: vendor +Forwarded: no +Last-Update: 2026-08-20 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -43,7 +43,7 @@ clap = { version = "~4.6", default-featu + ctrlc = "3.4" + encoding_rs = "0.8" + flate2 = "1" +-gix = { version = "0.84", default-features = false, features = [ ++gix = { version = "0.86", default-features = false, features = [ + "command", + "revision", + "sha1", +--- a/src/alias.rs ++++ b/src/alias.rs +@@ -100,15 +100,9 @@ where + .filter(|section| section.header().subsection_name() == Some("alias".into())) + { + for value_name in section.value_names() { +- let name = value_name.to_str().map_err(|_| { +- anyhow!( +- "alias name `{}` in {} is not valid UTF-8", +- value_name.to_str_lossy(), +- config_source_str(section.meta().source), +- ) +- })?; ++ let name = value_name.as_str(); + if let Some(value) = section +- .value(value_name) ++ .value(name) + .and_then(|v| (!v.is_empty()).then_some(v)) + { + if !exclude(name) { +--- a/src/cmd/branch/list.rs ++++ b/src/cmd/branch/list.rs +@@ -101,7 +101,7 @@ pub(super) fn dispatch(repo: &gix::Repos + stdout.set_color(&color_spec)?; + + let description = config +- .string_by("branch", Some(branchname.into()), "description") ++ .string(format!("branch.{branchname}.description").as_str()) + .unwrap_or_default(); + if description.is_empty() { + writeln!(stdout)?; +--- a/src/cmd/branch/mod.rs ++++ b/src/cmd/branch/mod.rs +@@ -151,7 +151,7 @@ fn set_description( + value.delete(); + } + if let Ok(section) = local_config_file.section("branch", Some(branchname.into())) { +- if section.num_values() == 0 { ++ if section.body().num_values() == 0 { + local_config_file.remove_section_by_id(section.id()); + } + } +@@ -171,11 +171,7 @@ fn set_description( + + fn get_stgit_parent(config: &gix::config::Snapshot, branchname: &PartialRefName) -> Option<String> { + config +- .string_by( +- "branch", +- Some(format!("{branchname}.stgit").as_str().into()), +- "parentbranch", +- ) ++ .string(format!("branch.{branchname}.stgit.parentbranch").as_str()) + .and_then(|bs| bs.to_str().ok().map(str::to_string)) + } + +@@ -202,7 +198,7 @@ fn set_stgit_parent( + value.delete(); + } + if let Ok(section) = local_config_file.section("branch", Some(subsection.as_str().into())) { +- if section.num_values() == 0 { ++ if section.body().num_values() == 0 { + local_config_file.remove_section_by_id(section.id()); + } + } +--- a/src/cmd/branch/rename.rs ++++ b/src/cmd/branch/rename.rs +@@ -84,8 +84,7 @@ pub(super) fn dispatch(repo: &gix::Repos + .section("branch", Some(old_section_name)) + .is_ok() + { +- let new_section_name = +- std::borrow::Cow::Owned(BString::from(format!("{new_branchname}.stgit"))); ++ let new_section_name = BString::from(format!("{new_branchname}.stgit")); + local_config_file + .rename_section( + "branch", +--- a/src/cmd/pick.rs ++++ b/src/cmd/pick.rs +@@ -297,7 +297,7 @@ fn pick_picks( + {body}" + ) + } else if matches.get_flag("expose") { +- let expose_format = config.string_by("stgit", Some("pick".into()), "expose-format"); ++ let expose_format = config.string("stgit.pick.expose-format"); + let expose_format = expose_format + .as_ref() + .map(|bs| bs.to_str().ok()) +--- a/src/cmd/pull.rs ++++ b/src/cmd/pull.rs +@@ -101,11 +101,7 @@ fn run(matches: &ArgMatches) -> Result<( + let config = repo.config_snapshot(); + let policy = PullPolicy::from_str( + &config +- .string_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "pull-policy", +- ) ++ .string(format!("branch.{branch_name}.stgit.pull-policy").as_str()) + .or_else(|| config.string("stgit.pull-policy")) + .map(|bs| bs.to_str_lossy().to_string()) + .unwrap_or_else(|| "pull".to_string()), +@@ -125,7 +121,7 @@ fn run(matches: &ArgMatches) -> Result<( + } + PullPolicy::Pull | PullPolicy::FetchRebase => { + parent_remote = config +- .string_by("branch", Some(branch_name.as_str().into()), "remote") ++ .string(format!("branch.{branch_name}.remote").as_str()) + .and_then(|bs| bs.to_str().map(str::to_string).ok()); + let remote_name = matches + .get_one::<String>("repository") +@@ -163,11 +159,7 @@ fn run(matches: &ArgMatches) -> Result<( + let rebase_target = match policy { + PullPolicy::Pull => { + let pull_cmd = config +- .string_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "pullcmd", +- ) ++ .string(format!("branch.{branch_name}.stgit.pullcmd").as_str()) + .or_else(|| config.string("stgit.pullcmd")) + .and_then(|bs| bs.to_str().map(str::to_string).ok()) + .unwrap_or_else(|| "git pull".to_string()); +@@ -183,11 +175,7 @@ fn run(matches: &ArgMatches) -> Result<( + } + PullPolicy::FetchRebase => { + let fetch_cmd = config +- .string_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "fetchcmd", +- ) ++ .string(format!("branch.{branch_name}.stgit.fetchcmd").as_str()) + .or_else(|| config.string("stgit.fetchcmd")) + .and_then(|bs| bs.to_str().map(str::to_string).ok()) + .unwrap_or_else(|| "git fetch".to_string()); +@@ -203,11 +191,8 @@ fn run(matches: &ArgMatches) -> Result<( + Some(target_id) + } + PullPolicy::Rebase => { +- let parent_branch_name = config.string_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "parentbranch", +- ); ++ let parent_branch_name = ++ config.string(format!("branch.{branch_name}.stgit.parentbranch").as_str()); + let parent_branch_name = parent_branch_name.as_ref().and_then(|bs| bs.to_str().ok()); + + let parent_object = if let Some(name) = parent_branch_name { +@@ -227,11 +212,7 @@ fn run(matches: &ArgMatches) -> Result<( + + if let Some(rebase_target) = rebase_target { + let rebase_cmd = config +- .string_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "rebasecmd", +- ) ++ .string(format!("branch.{branch_name}.stgit.rebasecmd").as_str()) + .or_else(|| config.string("stgit.rebasecmd")) + .and_then(|bs| bs.to_str().map(str::to_string).ok()) + .unwrap_or_else(|| "git reset --hard".to_string()); +--- a/src/cmd/rebase.rs ++++ b/src/cmd/rebase.rs +@@ -175,12 +175,7 @@ fn run(matches: &ArgMatches) -> Result<( + true + } else { + config +- .boolean_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "autostash", +- ) +- .transpose() ++ .try_boolean(format!("branch.{branch_name}.stgit.autostash").as_str()) + .unwrap_or_else(|e| { + crate::print_warning_message( + matches, +@@ -189,16 +184,13 @@ fn run(matches: &ArgMatches) -> Result<( + Some(false) + }) + .or_else(|| { +- config +- .try_boolean("stgit.autostash") +- .transpose() +- .unwrap_or_else(|e| { +- crate::print_warning_message( +- matches, +- &format!("Invalid config value `stgit.autostash`: {e}"), +- ); +- Some(false) +- }) ++ config.try_boolean("stgit.autostash").unwrap_or_else(|e| { ++ crate::print_warning_message( ++ matches, ++ &format!("Invalid config value `stgit.autostash`: {e}"), ++ ); ++ Some(false) ++ }) + }) + .unwrap_or(false) + }; +@@ -225,11 +217,7 @@ fn run(matches: &ArgMatches) -> Result<( + .execute("rebase (pop)")?; + + let rebase_cmd = config +- .string_by( +- "branch", +- Some(format!("{branch_name}.stgit").as_str().into()), +- "rebasecmd", +- ) ++ .string(format!("branch.{branch_name}.stgit.rebasecmd").as_str()) + .or_else(|| config.string("stgit.rebasecmd")) + .and_then(|bs| bs.to_str().map(str::to_string).ok()) + .unwrap_or_else(|| "git reset --hard".to_string()); +--- a/src/ext/repository.rs ++++ b/src/ext/repository.rs +@@ -1,9 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + +-use std::borrow::Cow; +- + use anyhow::{anyhow, Result}; +-use bstr::{BStr, ByteSlice}; ++use bstr::{BString, ByteSlice}; + + use crate::{ + stupid::Stupid, +@@ -42,7 +40,7 @@ pub(crate) trait RepositoryExtended { + + /// Get repository-local config file which can be used to change local + /// configuration. +- fn local_config_file(&self) -> Result<gix::config::File<'static>>; ++ fn local_config_file(&self) -> Result<gix::config::File>; + + /// Write repository-local config file. + fn write_local_config(&self, file: gix::config::File) -> Result<()>; +@@ -73,7 +71,7 @@ pub(crate) trait RepositoryExtended { + message: &Message, + tree_id: gix::ObjectId, + parent_ids: impl IntoIterator<Item = gix::ObjectId>, +- options: &CommitOptions<'_>, ++ options: &CommitOptions, + ) -> Result<gix::ObjectId>; + + /// [`gix::Repository::rev_parse_single()`] with StGit-specific error mapping. +@@ -88,9 +86,9 @@ pub(crate) trait RepositoryExtended { + } + + /// Options for creating a git commit object. +-pub(crate) struct CommitOptions<'a> { ++pub(crate) struct CommitOptions { + /// The target encoding for the commit message. +- pub(crate) commit_encoding: Option<Cow<'a, BStr>>, ++ pub(crate) commit_encoding: Option<BString>, + + /// Determine whether the commit object should be signed with GPG. + pub(crate) gpgsign: bool, +@@ -171,7 +169,7 @@ impl RepositoryExtended for gix::Reposit + } + } + +- fn local_config_file(&self) -> Result<gix::config::File<'static>> { ++ fn local_config_file(&self) -> Result<gix::config::File> { + let source = gix::config::Source::Local; + + let local_config_path = self.common_dir().join( +@@ -233,11 +231,11 @@ impl RepositoryExtended for gix::Reposit + message: &Message, + tree_id: gix::ObjectId, + parent_ids: impl IntoIterator<Item = gix::ObjectId>, +- options: &CommitOptions<'_>, ++ options: &CommitOptions, + ) -> Result<gix::ObjectId> { + let commit_encoding = match &options.commit_encoding { + Some(s) => { +- let encoding = encoding_rs::Encoding::for_label(s) ++ let encoding = encoding_rs::Encoding::for_label(s.as_ref()) + .ok_or_else(|| anyhow!("unhandled i18n.commitEncoding `{s}`"))?; + Some(encoding) + } +--- a/src/hook.rs ++++ b/src/hook.rs +@@ -3,7 +3,6 @@ + //! Support for using git repository hooks. + + use std::{ +- borrow::Cow, + io::Write, + path::{Path, PathBuf}, + }; +@@ -18,22 +17,21 @@ use crate::wrap::Message; + /// Returns None if the hook script is not found or is not executable. + fn get_hook_path(repo: &gix::Repository, hook_name: &str) -> Result<Option<PathBuf>> { + let config = repo.config_snapshot(); +- let hooks_path = +- if let Some(core_hooks_path) = config.trusted_path("core.hookspath").transpose()? { +- if core_hooks_path.is_absolute() { +- core_hooks_path +- } else if repo.is_bare() { +- // The hooks path is relative to GIT_DIR in the case of a bare repo +- Cow::Owned(repo.common_dir().join(core_hooks_path)) +- } else { +- // The hooks path is relative to the root of the working tree otherwise +- let work_dir = repo.workdir().expect("non-bare repo must have work dir"); +- Cow::Owned(work_dir.join(core_hooks_path)) +- } ++ let hooks_path = if let Some(core_hooks_path) = config.trusted_path("core.hookspath")? { ++ if core_hooks_path.is_absolute() { ++ core_hooks_path ++ } else if repo.is_bare() { ++ // The hooks path is relative to GIT_DIR in the case of a bare repo ++ repo.common_dir().join(core_hooks_path) + } else { +- // No core.hookspath, use default .git/hooks location +- Cow::Owned(repo.common_dir().join("hooks")) +- }; ++ // The hooks path is relative to the root of the working tree otherwise ++ let work_dir = repo.workdir().expect("non-bare repo must have work dir"); ++ work_dir.join(core_hooks_path) ++ } ++ } else { ++ // No core.hookspath, use default .git/hooks location ++ repo.common_dir().join("hooks") ++ }; + let hook_path = hooks_path.join(hook_name); + + let hook_meta = match std::fs::metadata(&hook_path) { +--- a/src/patch/edit/interactive.rs ++++ b/src/patch/edit/interactive.rs +@@ -135,15 +135,13 @@ fn get_editor(config: &gix::config::Snap + let editor = if let Some(editor) = std::env::var_os("GIT_EDITOR") { + editor + } else if let Some(editor) = config +- .trusted_path("stgit.editor") +- .transpose()? +- .map(|p| p.as_os_str().to_os_string()) ++ .trusted_path("stgit.editor")? ++ .map(|p| p.into_os_string()) + { + editor + } else if let Some(editor) = config +- .trusted_path("core.editor") +- .transpose()? +- .map(|p| p.as_os_str().to_os_string()) ++ .trusted_path("core.editor")? ++ .map(|p| p.into_os_string()) + { + editor + } else if let Some(editor) = std::env::var_os("VISUAL") { +--- a/src/stack/stack.rs ++++ b/src/stack/stack.rs +@@ -238,12 +238,7 @@ impl<'repo> Stack<'repo> { + /// Check whether the stack is marked as protected in the config. + pub(crate) fn is_protected(&self, config: &gix::config::Snapshot) -> bool { + config +- .boolean_by( +- "branch", +- Some(format!("{}.stgit", self.branch_name).as_str().into()), +- "protect", +- ) +- .unwrap_or(Ok(false)) ++ .boolean(format!("branch.{}.stgit.protect", self.branch_name).as_str()) + .unwrap_or(false) + } + +@@ -271,7 +266,7 @@ impl<'repo> Stack<'repo> { + if let Ok(section) = local_config_file + .section_by_key(format!("{section}.{subsection}").as_bytes().as_bstr()) + { +- if section.num_values() == 0 { ++ if section.body().num_values() == 0 { + local_config_file.remove_section_by_id(section.id()); + } + } +--- a/src/stack/upgrade.rs ++++ b/src/stack/upgrade.rs +@@ -325,7 +325,7 @@ fn rm_stackformatversion(repo: &gix::Rep + if let Ok(section) = + local_config_file.section_by_key(format!("{section}.{subsection}").as_bytes().as_bstr()) + { +- if section.num_values() == 0 { ++ if section.body().num_values() == 0 { + local_config_file.remove_section_by_id(section.id()); + } + } diff -Nru stgit-2.6.1/debian/patches/series stgit-2.6.1/debian/patches/series --- stgit-2.6.1/debian/patches/series 2026-07-20 12:53:23.000000000 -0500 +++ stgit-2.6.1/debian/patches/series 2026-08-20 11:57:19.000000000 -0500 @@ -2,4 +2,4 @@ disable_interactive_test use_bzip2_crate use_winnow_0_7 -use_gix_0_83 +gix-0.86.patch diff -Nru stgit-2.6.1/debian/patches/use_gix_0_83 stgit-2.6.1/debian/patches/use_gix_0_83 --- stgit-2.6.1/debian/patches/use_gix_0_83 2026-07-20 12:53:23.000000000 -0500 +++ stgit-2.6.1/debian/patches/use_gix_0_83 1969-12-31 18:00:00.000000000 -0600 @@ -1,11 +0,0 @@ ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -43,7 +43,7 @@ - ctrlc = "3.4" - encoding_rs = "0.8" - flate2 = "1" --gix = { version = "0.84", default-features = false, features = [ -+gix = { version = "0.83", default-features = false, features = [ - "command", - "revision", - "sha1",
OpenPGP_signature.asc
Description: OpenPGP digital signature

