arxanas / git-branchless

High-velocity, monorepo-scale workflow for Git
Apache License 2.0
3.48k stars 89 forks source link

Panic on executing `git prev` with custom `status` configuration: unknown status line prefix ASCII character: 35 #1404

Closed TrueDoctor closed 2 weeks ago

TrueDoctor commented 2 months ago

Description of the bug

When executing git prev I get this error:

Graphite on  master [$?] ➜ git prev
branchless: creating working copy snapshot
The application panicked (crashed).
Message:  A fatal error occurred:
   0: unknown status line prefix ASCII character: 35

Location:
   git-branchless-lib/src/core/check_out.rs:221

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   0: branchless::core::check_out::check_out_commit with effects=<Output fancy=true> git_run_info=<GitRunInfo path_to_git="git" working_directory="/home/dennis/Projects/rust/Graphite" env=not shown> repo=<Git repository at: "/home/dennis/Projects/rust/Graphite/.git/"> event_log_db=<EventLogDb> event_tx_id=EventTransactionId(1264) target=Some(Oid(NonZeroOid(ef007736f5400602348436c978963baa7c51e232))) options=CheckOutCommitOptions { additional_args: [], reset: false, render_smartlog: true }
      at git-branchless-lib/src/core/check_out.rs:107
   1: git_branchless_navigation::traverse_commits with effects=<Output fancy=true> git_run_info=<GitRunInfo path_to_git="git" working_directory="/home/dennis/Projects/rust/Graphite" env=not shown> command=Prev options=TraverseCommitsOptions { num_commits: None, all_the_way: false, move_by_branches: false, oldest: false, newest: false, interactive: false, merge: false, force: false }
      at git-branchless-navigation/src/lib.rs:309

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                                ⋮ 3 frames hidden ⋮
   4: branchless::core::check_out::create_snapshot::ha2ce3d73aeffbb12
      at <unknown source file>:<unknown line>
   5: branchless::core::check_out::check_out_commit::h333d15830b408054
      at <unknown source file>:<unknown line>
   6: git_branchless_navigation::traverse_commits::hc20dc93f7e901dd9
      at <unknown source file>:<unknown line>
   7: git_branchless::commands::command_main::ha8d2c10599fa2da4
      at <unknown source file>:<unknown line>
   8: git_branchless_invoke::do_main_and_drop_locals::h492362cb5928ac89
      at <unknown source file>:<unknown line>
   9: git_branchless::commands::main::h655ebb1410b39ed3
      at <unknown source file>:<unknown line>
  10: std::sys_common::backtrace::__rust_begin_short_backtrace::h7995c1697ab0ab37
      at <unknown source file>:<unknown line>
  11: std::rt::lang_start::{{closure}}::hc53d5a782d6d5d7b
      at <unknown source file>:<unknown line>
  12: std::panicking::try::ha86251cf5daa9bea
      at <unknown source file>:<unknown line>
  13: std::rt::lang_start_internal::ha6a51778162f8d22
      at <unknown source file>:<unknown line>
  14: main<unknown>
      at <unknown source file>:<unknown line>
  15: __libc_start_call_main<unknown>
      at <unknown source file>:<unknown line>
  16: __libc_start_main@@GLIBC_2.34<unknown>
      at <unknown source file>:<unknown line>
  17: _start<unknown>
      at <unknown source file>:<unknown line>

Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering.
Run with RUST_BACKTRACE=full to include source snippets.
Location: git-branchless/src/commands/mod.rs:235

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                                ⋮ 8 frames hidden ⋮
   9: core::result::Result<T,E>::expect::hf0e172a7fee0d4b9
      at <unknown source file>:<unknown line>
  10: git_branchless::commands::main::h655ebb1410b39ed3
      at <unknown source file>:<unknown line>
  11: std::sys_common::backtrace::__rust_begin_short_backtrace::h7995c1697ab0ab37
      at <unknown source file>:<unknown line>
  12: std::rt::lang_start::{{closure}}::hc53d5a782d6d5d7b
      at <unknown source file>:<unknown line>
  13: std::panicking::try::ha86251cf5daa9bea
      at <unknown source file>:<unknown line>
  14: std::rt::lang_start_internal::ha6a51778162f8d22
      at <unknown source file>:<unknown line>
  15: main<unknown>
      at <unknown source file>:<unknown line>
  16: __libc_start_call_main<unknown>
      at <unknown source file>:<unknown line>
  17: __libc_start_main@@GLIBC_2.34<unknown>
      at <unknown source file>:<unknown line>
  18: _start<unknown>
      at <unknown source file>:<unknown line>

Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering.
Run with RUST_BACKTRACE=full to include source snippets.

This happens when using the version of git branchless get on nixos. This is the repo for which it fails: https://github.com/GraphiteEditor/Graphite

Expected behavior

No response

Actual behavior

No response

Version of rustc

No response

Automated bug report

Software version

git-branchless 0.8.0

Operating system

Linux 6.10.3

Command-line

git-branchless bug-report 

Environment variables

SHELL=/run/current-system/sw/bin/bash
EDITOR=hx

Git version

> git version 
git version 2.44.1

Hooks

Show 7 hooks ##### Hook `post-applypatch` ``` #!/bin/sh ## START BRANCHLESS CONFIG git branchless hook post-applypatch "$@" ## END BRANCHLESS CONFIG ``` ##### Hook `post-checkout` ``` #!/bin/sh ## START BRANCHLESS CONFIG git branchless hook post-checkout "$@" ## END BRANCHLESS CONFIG ``` ##### Hook `post-commit` ``` #!/bin/sh ## START BRANCHLESS CONFIG git branchless hook post-commit "$@" ## END BRANCHLESS CONFIG ``` ##### Hook `post-merge` ``` #!/bin/sh ## START BRANCHLESS CONFIG git branchless hook post-merge "$@" ## END BRANCHLESS CONFIG ``` ##### Hook `post-rewrite` ``` #!/bin/sh ## START BRANCHLESS CONFIG git branchless hook post-rewrite "$@" ## END BRANCHLESS CONFIG ``` ##### Hook `pre-auto-gc` ``` #!/bin/sh ## START BRANCHLESS CONFIG git branchless hook pre-auto-gc "$@" ## END BRANCHLESS CONFIG ``` ##### Hook `reference-transaction` ``` #!/bin/sh ## START BRANCHLESS CONFIG # Avoid canceling the reference transaction in the case that `branchless` fails # for whatever reason. git branchless hook reference-transaction "$@" || ( echo 'branchless: Failed to process reference transaction!' echo 'branchless: Some events (e.g. branch updates) may have been lost.' echo 'branchless: This is a bug. Please report it.' ) ## END BRANCHLESS CONFIG ```

Events

Show 5 events ##### Event ID: 489, transaction ID: 1262 (message: hook-post-checkout) 1. `RefUpdateEvent { timestamp: 1726830626.292588, event_tx_id: EventTransactionId(1262), ref_name: ReferenceName("HEAD"), old_oid: 02c31d94ac82864e78247814f7c32a0be798e5b7, new_oid: ca0d1022961569b73b2f7514126f9ef53f8b2c65, message: None }` ``` : O 8fa46ba 231d xxxx xx xxxxxx xxxxx xxx xxxxxxxxxxxxxx xxxxxxxxxxxxx xxxxxxxxxx xxxxxxx |\ | o cab8c49 229d (redacted-ref-0) xxx xxxxxxxxxxxxx xxxx xxx xxxxx xxxxx xxxxxx xx xxxxx xxxxxxx | O 349ec5d 229d (redacted-ref-1) xxx xxxxxxxxxxxxx xxxx xxx xxxxx xxxxx xxxxxx xx xxxxx xxxxxxx : -- truncated because the comment was too long for github ```

Version of git-branchless

git-branchless-opts 0.8.0

Version of git

git version 2.44.1

arxanas commented 2 months ago

Thanks for reporting. This is happening during working copy snapshotting, where we run

git status --porcelain=v2 --untracked-files=no -z

ASCII character 35 = #. This is a valid beginning of a status line when you ask for metadata, like with --branch. However, git-branchless doesn't intend to ask for such metadata, so it fails to parse this. @TrueDoctor if you run the above git status command, what does it print? Does it include any lines with # in the output?

TrueDoctor commented 1 month ago

@arxanas This is the output:

# stash 3
arxanas commented 1 month ago

@TrueDoctor That output should only appear if --show-stash is passed: https://git-scm.com/docs/git-status#_stash_information

Do you have any configuration or aliases that might cause it to appear without passing that flag?

As a fix, we could probably just ignore # lines for now. I had a more robust git status parser somewhere which might also handle this case.

TrueDoctor commented 1 month ago

I've found this in my git config:

[status]
    branch = true
    showStash = true

Clearing the stash fixes it (will try to test disabling the option as well) Thanks!

arxanas commented 1 month ago

Thanks for confirming. The best fix is probably to update git-branchless to support #. IIRC it should be pretty simple if you want to give it a try; I think there's already a match statement where we match on the first character and handle 1/2/u?

I do wonder if this should be considered a bug in Git. It seems to me like porcelain output should ignore the user configuration for these settings, precisely so that scripts can be written against it without worrying about these kinds of environment differences.

TrueDoctor commented 1 month ago

Can you give me a rough location where I should look for the fix?

arxanas commented 1 month ago

@TrueDoctor I believe here:

https://github.com/arxanas/git-branchless/blob/aa23e70515d77b2ff2884fdf2ffbba35483ae0be/git-branchless-lib/src/git/repo.rs#L1014

TrueDoctor commented 2 weeks ago

Sorry just came back from a trip but should now have some time to work on this. It looks like # is valid per spec: https://git-scm.com/docs/git-status#_porcelain_format_version_2 and denotes header lines and can be ignored by parsers