History

Merge pull request #1752 from GitoxideLabs/git-shell

git login shell

Sebastian Thiel committed 1 year ago

Commit 1ca480a2 parents 8d84818 3aff1e530 files · +141 −114Browse files

Unified · Split

30 files
  1. .github/workflows/ci.yml +1 −1
  2. Cargo.toml +1 −0
  3. gitoxide-core/src/repository/attributes/query.rs +1 −1
  4. gitoxide-core/src/repository/clean.rs +2 −2
  5. gitoxide-core/src/repository/config.rs +5 −4
  6. gitoxide-core/src/repository/exclude.rs +1 −1
  7. gitoxide-core/src/repository/fetch.rs +1 −1
  8. gitoxide-core/src/repository/index/entries.rs +1 −1
  9. gitoxide-core/src/repository/remote.rs +1 −1
  10. gitoxide-core/src/repository/revision/list.rs +1 −1
  11. gix-dir/src/walk/classify.rs +1 −1
  12. gix-filter/examples/arrow.rs +1 −1
  13. gix-filter/src/driver/process/mod.rs +1 −1
  14. gix-pack/src/multi_index/chunk.rs +2 −2
  15. gix-packetline-blocking/src/line/async_io.rs +4 −4
  16. gix-packetline/src/line/async_io.rs +4 −4
  17. gix-path/src/env/mod.rs +17 −0
  18. gix-path/tests/path.rs +0 −80
  19. gix-path/tests/path/convert/mod.rs +0 −0
  20. gix-path/tests/path/convert/normalize.rs +0 −0
  21. gix-path/tests/path/env.rs +71 −0
  22. gix-path/tests/path/main.rs +18 −0
  23. gix-path/tests/path/realpath.rs +0 −0
  24. gix-path/tests/path/util.rs +0 −0
  25. gix-ref/src/store/file/transaction/commit.rs +1 −1
  26. gix-submodule/src/lib.rs +1 −3
  27. gix-validate/src/path.rs +1 −1
  28. gix/src/config/tree/sections/mod.rs +1 −0
  29. gix/src/remote/url/scheme_permission.rs +1 −1
  30. tests/tools/src/lib.rs +2 −2
.github/workflows/ci.yml+1−1
@@ -318,7 +318,7 @@ jobs: · 317 unmodified lines
318 318
319 strategy:319 strategy:
320 matrix:320 matrix:
321 target: [ wasm32-unknown-unknown, wasm32-wasi ]321 target: [ wasm32-unknown-unknown, wasm32-wasip1 ]
322 322
323 env:323 env:
324 TARGET: ${{ matrix.target }}324 TARGET: ${{ matrix.target }}
Cargo.toml+1−0
@@ -394,3 +394,4 @@ stable_sort_primitive = "allow" # x1 · 393 unmodified lines
394no_effect_underscore_binding = "allow" # x1394no_effect_underscore_binding = "allow" # x1
395empty_docs = "allow"395empty_docs = "allow"
396too_long_first_doc_paragraph = "allow"396too_long_first_doc_paragraph = "allow"
397large_stack_arrays = "allow"
gitoxide-core/src/repository/attributes/query.rs+1−1
@@ -89,7 +89,7 @@ pub(crate) mod function { · 88 unmodified lines
89 let entry = cache.at_entry(89 let entry = cache.at_entry(
90 path,90 path,
91 Some(is_dir_to_mode(91 Some(is_dir_to_mode(
92 workdir.map_or(false, |wd| wd.join(gix::path::from_bstr(path)).is_dir())92 workdir.is_some_and(|wd| wd.join(gix::path::from_bstr(path)).is_dir())
93 || pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),93 || pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),
94 )),94 )),
95 )?;95 )?;
gitoxide-core/src/repository/clean.rs+2−2
@@ -128,10 +128,10 @@ pub(crate) mod function { · 127 unmodified lines
128 let pathspec_includes_entry = match pathspec.as_mut() {128 let pathspec_includes_entry = match pathspec.as_mut() {
129 None => entry129 None => entry
130 .pathspec_match130 .pathspec_match
131 .map_or(false, |m| m != gix::dir::entry::PathspecMatch::Excluded),131 .is_some_and(|m| m != gix::dir::entry::PathspecMatch::Excluded),
132 Some(pathspec) => pathspec132 Some(pathspec) => pathspec
133 .pattern_matching_relative_path(entry.rela_path.as_bstr(), entry.disk_kind.map(|k| k.is_dir()))133 .pattern_matching_relative_path(entry.rela_path.as_bstr(), entry.disk_kind.map(|k| k.is_dir()))
134 .map_or(false, |m| !m.is_excluded()),134 .is_some_and(|m| !m.is_excluded()),
135 };135 };
136 pruned_entries += usize::from(!pathspec_includes_entry);136 pruned_entries += usize::from(!pathspec_includes_entry);
137 if !pathspec_includes_entry && debug {137 if !pathspec_includes_entry && debug {
gitoxide-core/src/repository/config.rs+5−4
@@ -32,7 +32,7 @@ pub fn list( · 31 unmodified lines
32 }32 }
33 33
34 let meta = section.meta();34 let meta = section.meta();
35 if last_meta.map_or(true, |last| last != meta) {35 if last_meta != Some(meta) {
36 write_meta(meta, &mut out)?;36 write_meta(meta, &mut out)?;
37 }37 }
38 last_meta = Some(meta);38 last_meta = Some(meta);
@@ -41,9 +41,10 @@ pub fn list( · 2 unmodified lines
41 for event in matter {41 for event in matter {
42 event.write_to(&mut out)?;42 event.write_to(&mut out)?;
43 }43 }
44 if it.peek().map_or(false, |(next_section, _)| {44 if it
45 next_section.header().name() != section.header().name()45 .peek()
46 }) {46 .is_some_and(|(next_section, _)| next_section.header().name() != section.header().name())
47 {
47 writeln!(&mut out)?;48 writeln!(&mut out)?;
48 }49 }
49 }50 }
gitoxide-core/src/repository/exclude.rs+1−1
@@ -93,7 +93,7 @@ pub fn query( · 92 unmodified lines
93 let entry = cache.at_entry(93 let entry = cache.at_entry(
94 path,94 path,
95 Some(is_dir_to_mode(95 Some(is_dir_to_mode(
96 workdir.map_or(false, |wd| wd.join(gix::path::from_bstr(path)).is_dir())96 workdir.is_some_and(|wd| wd.join(gix::path::from_bstr(path)).is_dir())
97 || pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),97 || pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),
98 )),98 )),
99 )?;99 )?;
gitoxide-core/src/repository/fetch.rs+1−1
@@ -305,7 +305,7 @@ pub(crate) mod function { · 304 unmodified lines
305 for fix in &map.fixes {305 for fix in &map.fixes {
306 match fix {306 match fix {
307 Fix::MappingWithPartialDestinationRemoved { name, spec } => {307 Fix::MappingWithPartialDestinationRemoved { name, spec } => {
308 if prev_spec.map_or(true, |prev_spec| prev_spec != spec) {308 if prev_spec.is_some_and(|prev_spec| prev_spec != spec) {
309 prev_spec = spec.into();309 prev_spec = spec.into();
310 spec.to_ref().write_to(&mut err)?;310 spec.to_ref().write_to(&mut err)?;
311 writeln!(err)?;311 writeln!(err)?;
gitoxide-core/src/repository/index/entries.rs+1−1
@@ -198,7 +198,7 @@ pub(crate) mod function { · 197 unmodified lines
198 sms_by_path198 sms_by_path
199 .iter()199 .iter()
200 .find_map(|(path, sm)| (path == entry_path).then_some(sm))200 .find_map(|(path, sm)| (path == entry_path).then_some(sm))
201 .filter(|sm| sm.git_dir_try_old_form().map_or(false, |dot_git| dot_git.exists()))201 .filter(|sm| sm.git_dir_try_old_form().is_ok_and(|dot_git| dot_git.exists()))
202 })202 })
203 {203 {
204 let sm_path = gix::path::to_unix_separators_on_windows(sm.path()?);204 let sm_path = gix::path::to_unix_separators_on_windows(sm.path()?);
gitoxide-core/src/repository/remote.rs+1−1
@@ -190,7 +190,7 @@ mod refs_impl { · 189 unmodified lines
190 for fix in &map.fixes {190 for fix in &map.fixes {
191 match fix {191 match fix {
192 Fix::MappingWithPartialDestinationRemoved { name, spec } => {192 Fix::MappingWithPartialDestinationRemoved { name, spec } => {
193 if prev_spec.map_or(true, |prev_spec| prev_spec != spec) {193 if prev_spec.is_some_and(|prev_spec| prev_spec != spec) {
194 prev_spec = spec.into();194 prev_spec = spec.into();
195 spec.to_ref().write_to(&mut err)?;195 spec.to_ref().write_to(&mut err)?;
196 writeln!(err)?;196 writeln!(err)?;
gitoxide-core/src/repository/revision/list.rs+1−1
@@ -108,7 +108,7 @@ pub(crate) mod function { · 107 unmodified lines
108 }108 }
109 }109 }
110 progress.inc();110 progress.inc();
111 if limit.map_or(false, |limit| limit == progress.step()) {111 if limit.is_some_and(|limit| limit == progress.step()) {
112 break;112 break;
113 }113 }
114 }114 }
gix-dir/src/walk/classify.rs+1−1
@@ -215,7 +215,7 @@ pub fn path( · 214 unmodified lines
215 215
216 let is_dir = if symlinks_to_directories_are_ignored_like_directories216 let is_dir = if symlinks_to_directories_are_ignored_like_directories
217 && ctx.excludes.is_some()217 && ctx.excludes.is_some()
218 && kind.map_or(false, |ft| ft == entry::Kind::Symlink)218 && kind == Some(entry::Kind::Symlink)
219 {219 {
220 path.metadata().ok().map(|md| is_dir_to_mode(md.is_dir()))220 path.metadata().ok().map(|md| is_dir_to_mode(md.is_dir()))
221 } else {221 } else {
gix-filter/examples/arrow.rs+1−1
@@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { · 18 unmodified lines
19 19
20 match sub_command.as_str() {20 match sub_command.as_str() {
21 "process" => {21 "process" => {
22 let disallow_delay = next_arg.as_deref().map_or(false, |arg| arg == "disallow-delay");22 let disallow_delay = next_arg.as_deref() == Some("disallow-delay");
23 let mut srv = gix_filter::driver::process::Server::handshake(23 let mut srv = gix_filter::driver::process::Server::handshake(
24 stdin(),24 stdin(),
25 stdout(),25 stdout(),
gix-filter/src/driver/process/mod.rs+1−1
@@ -83,7 +83,7 @@ impl Status { · 82 unmodified lines
83 83
84 /// Returns true if this is an `abort` status.84 /// Returns true if this is an `abort` status.
85 pub fn is_abort(&self) -> bool {85 pub fn is_abort(&self) -> bool {
86 self.message().map_or(false, |m| m == "abort")86 self.message() == Some("abort")
87 }87 }
88 88
89 /// Return true if the status is explicitly set to indicated delayed output processing89 /// Return true if the status is explicitly set to indicated delayed output processing
gix-pack/src/multi_index/chunk.rs+2−2
@@ -69,7 +69,7 @@ pub mod index_names { · 68 unmodified lines
69 ascii_path.is_ascii(),69 ascii_path.is_ascii(),
70 "must use ascii bytes for correct size computation"70 "must use ascii bytes for correct size computation"
71 );71 );
72 count += (ascii_path.as_bytes().len() + 1/* null byte */) as u64;72 count += (ascii_path.len() + 1/* null byte */) as u64;
73 }73 }
74 74
75 let needed_alignment = CHUNK_ALIGNMENT - (count % CHUNK_ALIGNMENT);75 let needed_alignment = CHUNK_ALIGNMENT - (count % CHUNK_ALIGNMENT);
@@ -89,7 +89,7 @@ pub mod index_names { · 13 unmodified lines
89 let path = path.as_ref().to_str().expect("UTF-8 path");89 let path = path.as_ref().to_str().expect("UTF-8 path");
90 out.write_all(path.as_bytes())?;90 out.write_all(path.as_bytes())?;
91 out.write_all(&[0])?;91 out.write_all(&[0])?;
92 written_bytes += path.as_bytes().len() as u64 + 1;92 written_bytes += path.len() as u64 + 1;
93 }93 }
94 94
95 let needed_alignment = CHUNK_ALIGNMENT - (written_bytes % CHUNK_ALIGNMENT);95 let needed_alignment = CHUNK_ALIGNMENT - (written_bytes % CHUNK_ALIGNMENT);
gix-packetline-blocking/src/line/async_io.rs+4−4
@@ -6,7 +6,7 @@ use futures_io::AsyncWrite; · 5 unmodified lines
6 6
7use crate::{encode, BandRef, Channel, ErrorRef, PacketLineRef, TextRef};7use crate::{encode, BandRef, Channel, ErrorRef, PacketLineRef, TextRef};
8 8
9impl<'a> BandRef<'a> {9impl BandRef<'_> {
10 /// Serialize this instance to `out`, returning the amount of bytes written.10 /// Serialize this instance to `out`, returning the amount of bytes written.
11 ///11 ///
12 /// The data written to `out` can be decoded with [`Borrowed::decode_band()]`.12 /// The data written to `out` can be decoded with [`Borrowed::decode_band()]`.
@@ -20,14 +20,14 @@ impl<'a> BandRef<'a> { · 7 unmodified lines
20 }20 }
21}21}
22 22
23impl<'a> TextRef<'a> {23impl TextRef<'_> {
24 /// Serialize this instance to `out`, appending a newline if there is none, returning the amount of bytes written.24 /// Serialize this instance to `out`, appending a newline if there is none, returning the amount of bytes written.
25 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {25 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {
26 encode::text_to_write(self.0, out).await26 encode::text_to_write(self.0, out).await
27 }27 }
28}28}
29 29
30impl<'a> ErrorRef<'a> {30impl ErrorRef<'_> {
31 /// Serialize this line as error to `out`.31 /// Serialize this line as error to `out`.
32 ///32 ///
33 /// This includes a marker to allow decoding it outside of a side-band channel, returning the amount of bytes written.33 /// This includes a marker to allow decoding it outside of a side-band channel, returning the amount of bytes written.
@@ -36,7 +36,7 @@ impl<'a> ErrorRef<'a> { · 2 unmodified lines
36 }36 }
37}37}
38 38
39impl<'a> PacketLineRef<'a> {39impl PacketLineRef<'_> {
40 /// Serialize this instance to `out` in git `packetline` format, returning the amount of bytes written to `out`.40 /// Serialize this instance to `out` in git `packetline` format, returning the amount of bytes written to `out`.
41 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {41 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {
42 match self {42 match self {
gix-packetline/src/line/async_io.rs+4−4
@@ -4,7 +4,7 @@ use futures_io::AsyncWrite; · 3 unmodified lines
4 4
5use crate::{encode, BandRef, Channel, ErrorRef, PacketLineRef, TextRef};5use crate::{encode, BandRef, Channel, ErrorRef, PacketLineRef, TextRef};
6 6
7impl<'a> BandRef<'a> {7impl BandRef<'_> {
8 /// Serialize this instance to `out`, returning the amount of bytes written.8 /// Serialize this instance to `out`, returning the amount of bytes written.
9 ///9 ///
10 /// The data written to `out` can be decoded with [`Borrowed::decode_band()]`.10 /// The data written to `out` can be decoded with [`Borrowed::decode_band()]`.
@@ -18,14 +18,14 @@ impl<'a> BandRef<'a> { · 7 unmodified lines
18 }18 }
19}19}
20 20
21impl<'a> TextRef<'a> {21impl TextRef<'_> {
22 /// Serialize this instance to `out`, appending a newline if there is none, returning the amount of bytes written.22 /// Serialize this instance to `out`, appending a newline if there is none, returning the amount of bytes written.
23 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {23 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {
24 encode::text_to_write(self.0, out).await24 encode::text_to_write(self.0, out).await
25 }25 }
26}26}
27 27
28impl<'a> ErrorRef<'a> {28impl ErrorRef<'_> {
29 /// Serialize this line as error to `out`.29 /// Serialize this line as error to `out`.
30 ///30 ///
31 /// This includes a marker to allow decoding it outside of a side-band channel, returning the amount of bytes written.31 /// This includes a marker to allow decoding it outside of a side-band channel, returning the amount of bytes written.
@@ -34,7 +34,7 @@ impl<'a> ErrorRef<'a> { · 2 unmodified lines
34 }34 }
35}35}
36 36
37impl<'a> PacketLineRef<'a> {37impl PacketLineRef<'_> {
38 /// Serialize this instance to `out` in git `packetline` format, returning the amount of bytes written to `out`.38 /// Serialize this instance to `out` in git `packetline` format, returning the amount of bytes written to `out`.
39 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {39 pub async fn write_to(&self, out: impl AsyncWrite + Unpin) -> io::Result<usize> {
40 match self {40 match self {
gix-path/src/env/mod.rs+17−0
@@ -28,6 +28,23 @@ pub fn installation_config_prefix() -> Option<&'static Path> { · 27 unmodified lines
28 installation_config().map(git::config_to_base_path)28 installation_config().map(git::config_to_base_path)
29}29}
30 30
31/// Return the shell that Git would prefer as login shell, the shell to execute Git commands from.
32///
33/// On Windows, this is the `bash.exe` bundled with it, and on Unix it's the shell specified by `SHELL`,
34/// or `None` if it is truly unspecified.
35pub fn login_shell() -> Option<&'static Path> {
36 static PATH: Lazy<Option<PathBuf>> = Lazy::new(|| {
37 if cfg!(windows) {
38 installation_config_prefix()
39 .and_then(|p| p.parent())
40 .map(|p| p.join("usr").join("bin").join("bash.exe"))
41 } else {
42 std::env::var_os("SHELL").map(PathBuf::from)
43 }
44 });
45 PATH.as_deref()
46}
47
31/// Return the name of the Git executable to invoke it.48/// Return the name of the Git executable to invoke it.
32/// If it's in the `PATH`, it will always be a short name.49/// If it's in the `PATH`, it will always be a short name.
33///50///
gix-path/tests/path.rs+0−80
@@ -1,80 +0,0 @@
1pub type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>;
2
3mod convert;
4mod realpath;
5mod home_dir {
6 #[test]
7 fn returns_existing_directory() {
8 if let Some(home) = gix_path::env::home_dir() {
9 assert!(
10 home.is_dir(),
11 "the home directory would typically exist, even though on unix we don't test for that."
12 );
13 }
14 }
15}
16
17mod env {
18 #[test]
19 fn exe_invocation() {
20 let actual = gix_path::env::exe_invocation();
21 assert!(
22 !actual.as_os_str().is_empty(),
23 "it finds something as long as git is installed somewhere on the system (or a default location)"
24 );
25 }
26
27 #[test]
28 fn installation_config() {
29 assert_ne!(
30 gix_path::env::installation_config().map(|p| p.components().count()),
31 gix_path::env::installation_config_prefix().map(|p| p.components().count()),
32 "the prefix is a bit shorter than the installation config path itself"
33 );
34 }
35
36 #[test]
37 fn system_prefix() {
38 assert_ne!(
39 gix_path::env::system_prefix(),
40 None,
41 "git should be present when running tests"
42 );
43 }
44
45 #[test]
46 fn home_dir() {
47 assert_ne!(
48 gix_path::env::home_dir(),
49 None,
50 "we find a home on every system these tests execute"
51 );
52 }
53
54 mod xdg_config {
55 use std::ffi::OsStr;
56
57 #[test]
58 fn prefers_xdg_config_bases() {
59 let actual = gix_path::env::xdg_config("test", &mut |n| {
60 (n == OsStr::new("XDG_CONFIG_HOME")).then(|| "marker".into())
61 })
62 .expect("set");
63 #[cfg(unix)]
64 assert_eq!(actual.to_str(), Some("marker/git/test"));
65 #[cfg(windows)]
66 assert_eq!(actual.to_str(), Some("marker\\git\\test"));
67 }
68
69 #[test]
70 fn falls_back_to_home() {
71 let actual = gix_path::env::xdg_config("test", &mut |n| (n == OsStr::new("HOME")).then(|| "marker".into()))
72 .expect("set");
73 #[cfg(unix)]
74 assert_eq!(actual.to_str(), Some("marker/.config/git/test"));
75 #[cfg(windows)]
76 assert_eq!(actual.to_str(), Some("marker\\.config\\git\\test"));
77 }
78 }
79}
80mod util;
gix-path/tests/path/convert/mod.rsrenamed from gix-path/tests/convert/mod.rs+0−0

File renamed without changes.

gix-path/tests/path/convert/normalize.rsrenamed from gix-path/tests/convert/normalize.rs+0−0

File renamed without changes.

gix-path/tests/path/env.rs+71−0
@@ -0,0 +1,71 @@
1#[test]
2fn exe_invocation() {
3 let actual = gix_path::env::exe_invocation();
4 assert!(
5 !actual.as_os_str().is_empty(),
6 "it finds something as long as git is installed somewhere on the system (or a default location)"
7 );
8}
9
10#[test]
11fn login_shell() {
12 // On CI, the $SHELL variable isn't necessarily set. Maybe other ways to get the login shell should be used then.
13 if !gix_testtools::is_ci::cached() {
14 assert!(gix_path::env::login_shell()
15 .expect("There should always be the notion of a shell used by git")
16 .exists());
17 }
18}
19
20#[test]
21fn installation_config() {
22 assert_ne!(
23 gix_path::env::installation_config().map(|p| p.components().count()),
24 gix_path::env::installation_config_prefix().map(|p| p.components().count()),
25 "the prefix is a bit shorter than the installation config path itself"
26 );
27}
28
29#[test]
30fn system_prefix() {
31 assert_ne!(
32 gix_path::env::system_prefix(),
33 None,
34 "git should be present when running tests"
35 );
36}
37
38#[test]
39fn home_dir() {
40 assert_ne!(
41 gix_path::env::home_dir(),
42 None,
43 "we find a home on every system these tests execute"
44 );
45}
46
47mod xdg_config {
48 use std::ffi::OsStr;
49
50 #[test]
51 fn prefers_xdg_config_bases() {
52 let actual = gix_path::env::xdg_config("test", &mut |n| {
53 (n == OsStr::new("XDG_CONFIG_HOME")).then(|| "marker".into())
54 })
55 .expect("set");
56 #[cfg(unix)]
57 assert_eq!(actual.to_str(), Some("marker/git/test"));
58 #[cfg(windows)]
59 assert_eq!(actual.to_str(), Some("marker\\git\\test"));
60 }
61
62 #[test]
63 fn falls_back_to_home() {
64 let actual = gix_path::env::xdg_config("test", &mut |n| (n == OsStr::new("HOME")).then(|| "marker".into()))
65 .expect("set");
66 #[cfg(unix)]
67 assert_eq!(actual.to_str(), Some("marker/.config/git/test"));
68 #[cfg(windows)]
69 assert_eq!(actual.to_str(), Some("marker\\.config\\git\\test"));
70 }
71}
gix-path/tests/path/main.rs+18−0
@@ -0,0 +1,18 @@
1pub type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>;
2
3mod convert;
4mod realpath;
5mod home_dir {
6 #[test]
7 fn returns_existing_directory() {
8 if let Some(home) = gix_path::env::home_dir() {
9 assert!(
10 home.is_dir(),
11 "the home directory would typically exist, even though on unix we don't test for that."
12 );
13 }
14 }
15}
16
17mod env;
18mod util;
gix-path/tests/path/realpath.rsrenamed from gix-path/tests/realpath/mod.rs+0−0

File renamed without changes.

gix-path/tests/path/util.rsrenamed from gix-path/tests/util/mod.rs+0−0

File renamed without changes.

gix-ref/src/store/file/transaction/commit.rs+1−1
@@ -72,7 +72,7 @@ impl Transaction<'_, '_> { · 71 unmodified lines
72 }72 }
73 };73 };
74 if let Some((previous, new_oid)) = log_update {74 if let Some((previous, new_oid)) = log_update {
75 let do_update = previous.as_ref().map_or(true, |previous| previous != new_oid);75 let do_update = previous.as_ref() != Some(new_oid);
76 if do_update {76 if do_update {
77 self.store.reflog_create_or_append(77 self.store.reflog_create_or_append(
78 change.update.name.as_ref(),78 change.update.name.as_ref(),
gix-submodule/src/lib.rs+1−3
@@ -4,8 +4,6 @@ · 3 unmodified lines
4 4
5use std::{borrow::Cow, collections::BTreeMap};5use std::{borrow::Cow, collections::BTreeMap};
6 6
7use bstr::BStr;
8
9/// All relevant information about a git module, typically from `.gitmodules` files.7/// All relevant information about a git module, typically from `.gitmodules` files.
10///8///
11/// Note that overrides from other configuration might be relevant, which is why this type9/// Note that overrides from other configuration might be relevant, which is why this type
@@ -64,7 +62,7 @@ impl File { · 52 unmodified lines
64 let mut config_to_append = gix_config::File::new(config.meta_owned());62 let mut config_to_append = gix_config::File::new(config.meta_owned());
65 let mut prev_name = None;63 let mut prev_name = None;
66 for ((module_name, field), values) in values {64 for ((module_name, field), values) in values {
67 if prev_name.map_or(true, |pn: &BStr| pn != module_name) {65 if prev_name != Some(module_name) {
68 config_to_append66 config_to_append
69 .new_section("submodule", Some(Cow::Owned(module_name.to_owned())))67 .new_section("submodule", Some(Cow::Owned(module_name.to_owned())))
70 .expect("all names come from valid configuration, so remain valid");68 .expect("all names come from valid configuration, so remain valid");
gix-validate/src/path.rs+1−1
@@ -185,7 +185,7 @@ fn check_win_devices_and_illegal_characters(input: &BStr) -> Option<component::E · 184 unmodified lines
185}185}
186 186
187fn is_symlink(mode: Option<component::Mode>) -> bool {187fn is_symlink(mode: Option<component::Mode>) -> bool {
188 mode.map_or(false, |m| m == component::Mode::Symlink)188 mode == Some(component::Mode::Symlink)
189}189}
190 190
191fn is_dot_hfs(input: &BStr, search_case_insensitive: &str) -> bool {191fn is_dot_hfs(input: &BStr, search_case_insensitive: &str) -> bool {
gix/src/config/tree/sections/mod.rs+1−0
@@ -1,3 +1,4 @@
1#![allow(clippy::unnecessary_literal_bound)]
1#![allow(missing_docs)]2#![allow(missing_docs)]
2 3
3/// The `author` top-level section.4/// The `author` top-level section.
gix/src/remote/url/scheme_permission.rs+1−1
@@ -63,7 +63,7 @@ impl SchemePermission { · 62 unmodified lines
63 .map(|value| Protocol::ALLOW.try_into_allow(value, None))63 .map(|value| Protocol::ALLOW.try_into_allow(value, None))
64 .transpose()?;64 .transpose()?;
65 65
66 let mut saw_user = allow.map_or(false, |allow| allow == Allow::User);66 let mut saw_user = allow == Some(Allow::User);
67 let allow_per_scheme = match config.sections_by_name_and_filter("protocol", &mut filter) {67 let allow_per_scheme = match config.sections_by_name_and_filter("protocol", &mut filter) {
68 Some(it) => {68 Some(it) => {
69 let mut map = BTreeMap::default();69 let mut map = BTreeMap::default();
tests/tools/src/lib.rs+2−2
@@ -652,6 +652,7 @@ fn configure_command<'a, I: IntoIterator<Item = S>, S: AsRef<OsStr>>( · 651 unmodified lines
652}652}
653 653
654fn bash_program() -> &'static Path {654fn bash_program() -> &'static Path {
655 // TODO: use `gix_path::env::login_shell()` when available.
655 if cfg!(windows) {656 if cfg!(windows) {
656 static GIT_BASH: Lazy<Option<PathBuf>> = Lazy::new(|| {657 static GIT_BASH: Lazy<Option<PathBuf>> = Lazy::new(|| {
657 GIT_CORE_DIR658 GIT_CORE_DIR
@@ -685,8 +686,7 @@ fn is_lfs_pointer_file(path: &Path) -> bool { · 27 unmodified lines
685 std::fs::OpenOptions::new()686 std::fs::OpenOptions::new()
686 .read(true)687 .read(true)
687 .open(path)688 .open(path)
688 .and_then(|mut f| f.read_exact(&mut buf))689 .is_ok_and(|mut f| f.read_exact(&mut buf).is_ok_and(|_| buf.starts_with(PREFIX)))
689 .map_or(false, |_| buf.starts_with(PREFIX))
690}690}
691 691
692/// The `script_identity` will be baked into the soon to be created `archive` as it identifies the script692/// The `script_identity` will be baked into the soon to be created `archive` as it identifies the script