diff --git a/modules/bit/src/cmd/bit/for_each_ref.mbt b/modules/bit/src/cmd/bit/for_each_ref.mbt index 5059a907..16be3161 100644 --- a/modules/bit/src/cmd/bit/for_each_ref.mbt +++ b/modules/bit/src/cmd/bit/for_each_ref.mbt @@ -1009,24 +1009,40 @@ async fn for_each_ref_validate_atom(atom : String) -> Unit { @sys.exit(1) } } - // Validate upstream/push arguments + // Validate upstream/push arguments. The argument may be a comma-separated + // list of tokens (e.g. "track,nobracket"); each token is a simple option or + // a ref-stripping modifier (lstrip=/strip=/rstrip=), mirroring git. if atom.has_prefix("upstream:") { let arg = String::unsafe_substring(atom, start=9, end=atom.length()) - match arg { - "short" | "track" | "trackshort" | "remotename" | "remoteref" => () - _ => { - eprint_line("fatal: unrecognized %(upstream) argument: " + arg) - @sys.exit(1) + for tok_view in arg.split(",") { + let tok = tok_view.to_owned() + match tok { + "short" | "track" | "trackshort" | "nobracket" | "remotename" + | "remoteref" => () + _ if tok.has_prefix("lstrip=") || + tok.has_prefix("strip=") || + tok.has_prefix("rstrip=") => () + _ => { + eprint_line("fatal: unrecognized %(upstream) argument: " + arg) + @sys.exit(1) + } } } } if atom.has_prefix("push:") { let arg = String::unsafe_substring(atom, start=5, end=atom.length()) - match arg { - "short" | "track" | "trackshort" | "remotename" | "remoteref" => () - _ => { - eprint_line("fatal: unrecognized %(push) argument: " + arg) - @sys.exit(1) + for tok_view in arg.split(",") { + let tok = tok_view.to_owned() + match tok { + "short" | "track" | "trackshort" | "nobracket" | "remotename" + | "remoteref" => () + _ if tok.has_prefix("lstrip=") || + tok.has_prefix("strip=") || + tok.has_prefix("rstrip=") => () + _ => { + eprint_line("fatal: unrecognized %(push) argument: " + arg) + @sys.exit(1) + } } } } @@ -4081,6 +4097,17 @@ async fn for_each_ref_commit_atom( } else { "" } + // Message with the signature block removed (lines before sig_start). Trailer + // parsing must ignore the signature, matching git which strips it first. + let no_sig_parts : Array[String] = [] + for i = 0; i < sig_start; i = i + 1 { + no_sig_parts.push(message_lines[i]) + } + let message_no_sig = if no_sig_parts.length() > 0 { + no_sig_parts.join("\n") + } else { + "" + } // Determine which ident to use for creator* atoms let creator = if tagger.length() > 0 { tagger @@ -4328,17 +4355,17 @@ async fn for_each_ref_commit_atom( lines.join("\n") } } - "trailers" => for_each_ref_format_trailers_atom(atom, raw_message) + "trailers" => for_each_ref_format_trailers_atom(atom, message_no_sig) _ if atom.has_prefix("trailers:") => - for_each_ref_format_trailers_atom(atom, raw_message) + for_each_ref_format_trailers_atom(atom, message_no_sig) "contents:trailers" => { let trailer_atom = "trailers" - for_each_ref_format_trailers_atom(trailer_atom, raw_message) + for_each_ref_format_trailers_atom(trailer_atom, message_no_sig) } _ if atom.has_prefix("contents:trailers:") => { let trailer_atom = "trailers" + String::unsafe_substring(atom, start=17, end=atom.length()) - for_each_ref_format_trailers_atom(trailer_atom, raw_message) + for_each_ref_format_trailers_atom(trailer_atom, message_no_sig) } _ if atom.has_prefix("contents:") => { let arg = String::unsafe_substring(atom, start=9, end=atom.length()) diff --git a/modules/bit_io/src/native/upload_pack_process.mbt b/modules/bit_io/src/native/upload_pack_process.mbt index bd5676ce..c54693c6 100644 --- a/modules/bit_io/src/native/upload_pack_process.mbt +++ b/modules/bit_io/src/native/upload_pack_process.mbt @@ -1325,19 +1325,19 @@ fn write_partial_clone_metadata( let filter_value = filter.to_string() let config_path = @bit.join_path(git_dir, "config") let config = - #|[core] - #| repositoryformatversion = 1 - #| filemode = true - #| bare = false - #| logallrefupdates = true - #|[extensions] - #| partialclone = origin + $|[core] + $| repositoryformatversion = 1 + $| filemode = true + $| bare = false + $| logallrefupdates = true + $|[extensions] + $| partialclone = origin $|[remote "origin"] $| url = \{remote} - #| fetch = +refs/heads/*:refs/remotes/origin/* - #| promisor = true + $| fetch = +refs/heads/*:refs/remotes/origin/* + $| promisor = true $| partialclonefilter = \{filter_value} - #| + $| fs.write_string(config_path, config) let packed_refs_path = @bit.join_path(git_dir, "packed-refs") fs.write_string(packed_refs_path, "# pack-refs with: peeled fully-peeled\n") diff --git a/modules/bit_pack/src/pack_index_write_test.mbt b/modules/bit_pack/src/pack_index_write_test.mbt index 4f634b32..b4e5781f 100644 --- a/modules/bit_pack/src/pack_index_write_test.mbt +++ b/modules/bit_pack/src/pack_index_write_test.mbt @@ -1,8 +1,28 @@ ///| Pack index fixture tests (git index-pack output) +///| +/// Resolve a repo-root-relative fixture path independent of the test's working +/// directory. `moon test` does not guarantee the native test binary runs from +/// the repo root (this changed in moon 0.1.20260618, which broke the plain +/// "fixtures/..." reads), so walk up parent directories until the path exists. +fn resolve_fixture(path : String) -> String { + let mut prefix = "" + let mut i = 0 + while i < 32 { + let candidate = prefix + path + if @fs.path_exists(candidate) { + return candidate + } + prefix = prefix + "../" + i = i + 1 + } + path +} + ///| fn read_fixture_bytes(path : String) -> Bytes raise { - @fs.read_file_to_bytes(path) catch { + let resolved = resolve_fixture(path) + @fs.read_file_to_bytes(resolved) catch { e => fail("failed to read fixture: \{path} (\{e})") } }