git-branchless icon indicating copy to clipboard operation
git-branchless copied to clipboard

Unhelpful behavior when `git-branchless init` not performed.

Open greg7mdp opened this issue 2 years ago • 9 comments

Description of the bug

As I tried a macos build of my software, I forgot to run git-branchless init on the repo, and I was mistified for a moment as to why git-branchless was not working. Even got a crash:

❯ git-branchless smartlog
The application panicked (crashed).
Message:  A fatal error occurred: 
   0: Could not find repository main branch

Location:
   /Users/gpopovitch/.cargo/registry/src/github.com-1ecc6299db9ec823/git-branchless-lib-0.3.12/src/git/repo.rs:404

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

   0: branchless::git::repo::get_main_branch_oid with self=<Git repository at: "/Users/gpopovitch/github/rippled/.git/">
      at /Users/gpopovitch/.cargo/registry/src/github.com-1ecc6299db9ec823/git-branchless-lib-0.3.12/src/git/repo.rs:412
   1: git_branchless::commands::smartlog::smartlog with effects=<Output fancy=true> git_run_info=<GitRunInfo path_to_git="git" working_directory="/Users/gpopovitch/github/rippled" env=not shown> options=SmartlogOptions { show_hidden_commits: false, only_show_branches: false }
      at /Users/gpopovitch/.cargo/registry/src/github.com-1ecc6299db9ec823/git-branchless-0.3.12/src/commands/smartlog.rs:533

Suggestion: 
The main branch "master" could not be found in your repository

After doing a git-branchless init, all issues went away.

BTW I love git-branchless. This is what git should be :-).

Expected behavior

A friendly message, like Looks like you forgot to run "git-branchless init"

Actual behavior

~/github/rippled @22fa1f23 ?5 ❯ git-branchless sl       
error: Found argument 'sl' which wasn't expected, or isn't valid in this context

USAGE:
    git-branchless [OPTIONS] <SUBCOMMAND>

For more information try --help
~/github/rippled @22fa1f23 ?5 ❯ git-branchless smartlog
The application panicked (crashed).
Message:  A fatal error occurred: 
   0: Could not find repository main branch

Version of rustc

rustc 1.62.1 (e092d0b6b 2022-07-16)

Automated bug report

No response

Version of git-branchless

git-branchless 0.3.12

Version of git

git version 2.35.1

greg7mdp avatar Aug 09 '22 22:08 greg7mdp

Hi @greg7mdp, thanks for reporting. This situation should definitely be improved. It's worth noting that some git-branchless commands should work even without having run git branchless init if it can infer your main branch, like git move.

arxanas avatar Aug 17 '22 02:08 arxanas

When raising this error, we can check to see if init has been run, and, if not, include something in the error message suggesting to run it. We can infer that init has been run by checking to see if the config value branchless.core.mainBranch has a value or not. There might be a small amount of refactoring in config.rs to make that query.

arxanas avatar Jan 13 '23 09:01 arxanas

This probably deserves its own issue if it's doable/well-received, but a possibly related feature that I'd love to see is a configuration option to lazily/automatically init the first time it's needed. Perhaps a branchless.core.autoInit or something of the sort. I'd set this globally in a heartbeat and it would save me from quite a number of errors related to not having run init yet!

zachallaun avatar Jan 23 '23 13:01 zachallaun

@zachallaun feel free to open a separate issue. I don't personally plan to work on that in the near future, but I'd accept a PR implementing it.

arxanas avatar Jan 25 '23 01:01 arxanas

I'm just starting to use git branchless, it seems excellent.

Could I ask — why the need to run git branchless init in each repo for commands like git sync? Assuming that refs/remotes/origin/HEAD is set, don't we already know the default branch?

max-sixty avatar Oct 21 '23 19:10 max-sixty

Could I ask — why the need to run git branchless init in each repo for commands like git sync?

@max-sixty There are a lot of implicit dependencies in the rest of the code. For example:

  • We have to guess the main branch name at some point, as it may not be main/master locally, and we might need to explicitly prompt the user/save the result.
  • To merely know the structure of the commit graph, we have to run the DAG initialization procedure.
  • Generally speaking, we want to track the history of branch moves and commit rewrites so that they can be undone, which requires initializing the event log database and installing hooks.
  • If we fall back to on-disk rebases (rather than an in-memory rebase), then it requires that we have installed the post-rewrite hook for correctness reasons.

It's possible that certain commands under certain circumstances can run without explicit initialization, but it would be difficult to write the existing code in a way that can run without assuming that git branchless init has been run.

Assuming that refs/remotes/origin/HEAD is set, don't we already know the default branch?

There might be some metadata I'm not familiar with; how does refs/remotes/origin/HEAD tell us the local main branch? (Also, it assumes that origin is the remote that we want to sync from — for example, in a two-remote GitHub setup, one often has origin and upstream remotes, where upstream is the pull-remote and origin is the push-remote — although it wouldn't be unreasonable to assume that origin is the default remote in many cases).

arxanas avatar Oct 22 '23 00:10 arxanas

It's possible that certain commands under certain circumstances can run without explicit initialization, but it would be difficult to write the existing code in a way that can run without assuming that git branchless init has been run.

Yes, this makes sense.

Plausibly the main thing I came here for is actually quite a small feature — update all my local branches based on any remote updates — such that the full operation does require the setup...

There might be some metadata I'm not familiar with; how does refs/remotes/origin/HEAD tell us the local main branch?

IIUC, refs/remotes/origin/HEAD is the default branch (i.e. HEAD) of the default remote (i.e. origin). Running git remote set-head origin -a will update it.

max-sixty avatar Oct 22 '23 01:10 max-sixty