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

Aborting a rebase started by `git sync --merge` then `git undo -i` deletes the main branch

Open mlcui-corp opened this issue 2 years ago • 1 comments

Description of the bug

See command log below:

Command log
$ git init sync-abort

$ cd sync-abort

$ git commit --allow-empty -m "Initial commit"
[main (root-commit) 6dfb64b] Initial commit
git branchless init
Created config file at ~/git/branchless-testing/sync-abort/.git/branchless/config
Auto-detected your main branch as: main
If this is incorrect, run: git branchless init --main-branch <branch>
Installing hooks: post-commit, post-merge, post-rewrite, post-checkout, pre-auto-gc, reference-transaction
Successfully installed git-branchless.
To uninstall, run: git branchless init --uninstall

$ git switch --detach
branchless: processing 1 update: ref HEAD
HEAD is now at 6dfb64b Initial commit
branchless: processing checkout

$ echo "Hello, world!" > a.txt && git add a.txt && git commit -m "a: Hello, world!"
branchless: processing 1 update: ref HEAD
branchless: processed commit: e2880de a: Hello, world!
[detached HEAD e2880de] a: Hello, world!
 1 file changed, 1 insertion(+)
 create mode 100644 a.txt

$ echo "Hello, world!" > b.txt && git add b.txt && git commit -m "b: Hello, world!"
branchless: processing 1 update: ref HEAD
branchless: processed commit: 5d269df b: Hello, world!
[detached HEAD 5d269df] b: Hello, world!
 1 file changed, 1 insertion(+)
 create mode 100644 b.txt

$ git switch main
Previous HEAD position was 5d269df b: Hello, world!
Switched to branch 'main'
branchless: processing checkout

$ echo "Hello world" | tee a.txt b.txt
Hello world

$ git add a.txt b.txt && git commit -m "a, b: Hello world"
branchless: processing 2 updates: branch main, ref HEAD
branchless: processed commit: f9f3612 a, b: Hello world
[main f9f3612] a, b: Hello world
 2 files changed, 2 insertions(+)
 create mode 100644 a.txt
 create mode 100644 b.txt

$ git sl
◇ 6dfb64b 9m Initial commit
┣━┓
┃ ◯ e2880de 2m a: Hello, world!
┃ ┃
┃ ◯ 5d269df 2m b: Hello, world!
┃
◆ f9f3612 10s (ᐅ main) a, b: Hello world

$ git sync --merge
Attempting rebase in-memory...
There was a merge conflict, which currently can't be resolved when rebasing in-memory.
The conflicting commit was: e2880de a: Hello, world!
Trying again on-disk...
branchless: running command: git diff --quiet
Calling Git for on-disk rebase...
branchless: running command: git rebase --continue
branchless: processing 1 update: ref HEAD
Auto-merging a.txt
CONFLICT (add/add): Merge conflict in a.txt
error: could not apply e2880de... a: Hello, world!
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply e2880de... 

# ... resolve merge conflict for this commit...
$ git rebase --continue
branchless: processing 1 update: ref HEAD
branchless: processed commit: ac04bfe a: Hello, world!
[detached HEAD ac04bfe] a: Hello, world!
 1 file changed, 1 insertion(+), 1 deletion(-)
Executing: git branchless hook-detect-empty-commit e2880de6c8c5f980ecf15b604150b1e824537572
Auto-merging b.txt
CONFLICT (add/add): Merge conflict in b.txt
error: could not apply 5d269df... b: Hello, world!
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 5d269df... 

$ git sl
◇ 6dfb64b 11m Initial commit
┣━┓
┃ ◯ e2880de 5m a: Hello, world!
┃ ┃
┃ ◯ 5d269df 4m b: Hello, world!
┃
◇ f9f3612 2m (main) a, b: Hello world
┃
● ac04bfe 18s a: Hello, world!

$ git rebase --abort
branchless: processing 1 update: branch main

$ git sl
◇ 6dfb64b 11m Initial commit
┣━┓
┃ ◯ e2880de 5m a: Hello, world!
┃ ┃
┃ ◯ 5d269df 4m b: Hello, world!
┃
◆ f9f3612 2m (ᐅ main) a, b: Hello world
┃
◯ ac04bfe 29s a: Hello, world!

# issue: undoing from here results in the main branch being deleted
$ git undo -i
# choose the smartlog without ac04bfe
Will apply these actions:
1. Delete branch main at f9f3612 a, b: Hello world
   
2. Hide commit ac04bfe a: Hello, world!
   
3. Check out from ac04bfe a: Hello, world!
               to f9f3612 a, b: Hello world
Confirm? [yN] y
branchless: creating working copy snapshot
The application panicked (crashed).
Message:  A fatal error occurred: 
   0: Updating to previous HEAD location
   1: Could not find repository main branch

Location:
   git-branchless-lib/src/core/repo_ext.rs:74

Suggestion: 
The main branch "main" could not be found in your repository
at path: "/usr/local/google/home/mlcui/git/branchless-testing/sync-abort/.git/".
These branches exist: []
Either create it, or update the main branch setting by running:

    git branchless init --main-branch <branch>

Note that remote main branches are no longer supported as of v0.6.0. See
https://github.com/arxanas/git-branchless/discussions/595 for more details.

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
Location: git-branchless/src/commands/mod.rs:468

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

$ git switch -c main
branchless: processing 1 update: branch main
Switched to a new branch 'main'
branchless: processing checkout

$ git branchless bug-report
(attached)

$ git sl
◇ 6dfb64b 20m Initial commit
┣━┓
┃ ◯ e2880de 14m a: Hello, world!
┃ ┃
┃ ◯ 5d269df 13m b: Hello, world!
┃
◆ f9f3612 11m (ᐅ main) a, b: Hello world

I saw that commits created during a reverted rebase remain in the smartlog. This is very minor - users can git hide them, although they aren't marked as successors of the rewritten commits so users will need to resolve the same merge conflict again. This is more of a feature request than a bug report, but can these be marked as a rewrite of the previous commit - so users can continue the sync / restack at a later time?

Expected behavior

Aborting a rebase started by git sync --merge, then doing git undo -i, undos correctly.

Actual behavior

Aborting a rebase started by git sync --merge, then doing git undo -i, deletes the main branch.

Version of rustc

No response

Automated bug report

Software version

git-branchless 0.7.0-pre.1 (v0.3.6-nixos.0-655-gf698e09)

Operating system

Linux 5.19.11-1rodete1-amd64

Command-line

~/.cargo/bin/git-branchless bug-report 

Environment variables

SHELL=/bin/zsh
EDITOR=nvim

Git version

> git version 
git version 2.39.0.rc1.256.g54fd8350bd-goog

Hooks

Show 6 hooks
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 post-checkout
#!/bin/sh
## START BRANCHLESS CONFIG

git branchless hook-post-checkout "$@"

## 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: 18, transaction ID: 25 (message: hook-post-checkout)
  1. RefUpdateEvent { timestamp: 1670821239.7127469, event_tx_id: EventTransactionId(25), ref_name: ReferenceName("HEAD"), old_oid: f9f3612960af426ced33ab2eeb2d70124cbceaff, new_oid: f9f3612960af426ced33ab2eeb2d70124cbceaff, message: None }
O 6dfb64b 17m xxxxxxx xxxxxx
|\
| o e2880de 11m xx xxxxxx xxxxxx
| |
| o 5d269df 10m xx xxxxxx xxxxxx
|
@ f9f3612 8m (> main) xx xx xxxxx xxxxx
Event ID: 17, transaction ID: 24 (message: reference-transaction)
  1. RefUpdateEvent { timestamp: 1670821239.6613429, event_tx_id: EventTransactionId(24), ref_name: ReferenceName("refs/heads/main"), old_oid: 0000000000000000000000000000000000000000, new_oid: f9f3612960af426ced33ab2eeb2d70124cbceaff, message: None }
O 6dfb64b 17m xxxxxxx xxxxxx
|\
| o e2880de 11m xx xxxxxx xxxxxx
| |
| o 5d269df 10m xx xxxxxx xxxxxx
|
@ f9f3612 8m (> main) xx xx xxxxx xxxxx
Event ID: 15, transaction ID: 23 (message: undo)
  1. ObsoleteEvent { timestamp: 1670821189.692501, event_tx_id: EventTransactionId(23), commit_oid: NonZeroOid(ac04bfeed238699fa257406f0d91ecf35186e0f5) }
  2. WorkingCopySnapshot { timestamp: 1670821196.9232357, event_tx_id: EventTransactionId(23), head_oid: f9f3612960af426ced33ab2eeb2d70124cbceaff, commit_oid: NonZeroOid(2f7257f1b9370abf7ee2857fc5b2138fdee14fb7), ref_name: None }
O 6dfb64b 17m xxxxxxx xxxxxx
|\
| o e2880de 11m xx xxxxxx xxxxxx
| |
| o 5d269df 10m xx xxxxxx xxxxxx
|
@ f9f3612 8m (> main) xx xx xxxxx xxxxx
Event ID: 14, transaction ID: 21 (message: reference-transaction)
  1. RefUpdateEvent { timestamp: 1670821073.873817, event_tx_id: EventTransactionId(21), ref_name: ReferenceName("refs/heads/main"), old_oid: 0000000000000000000000000000000000000000, new_oid: f9f3612960af426ced33ab2eeb2d70124cbceaff, message: None }
O 6dfb64b 17m xxxxxxx xxxxxx
|\
| o e2880de 11m xx xxxxxx xxxxxx
| |
| o 5d269df 10m xx xxxxxx xxxxxx
|
@ f9f3612 8m (> main) xx xx xxxxx xxxxx
Event ID: 13, transaction ID: 15 (message: post-commit)
  1. CommitEvent { timestamp: 1670821047.0, event_tx_id: EventTransactionId(15), commit_oid: NonZeroOid(ac04bfeed238699fa257406f0d91ecf35186e0f5) }
O 6dfb64b 17m xxxxxxx xxxxxx
|\
| o e2880de 11m xx xxxxxx xxxxxx
| |
| o 5d269df 10m xx xxxxxx xxxxxx
|
@ f9f3612 8m (> main) xx xx xxxxx xxxxx

Version of git-branchless

5c13964

Version of git

No response

mlcui-corp avatar Dec 12 '22 05:12 mlcui-corp

Oof, it looks like it might be hard to fix this one. I don't really understand why git undo thought it was appropriate to delete the main branch in this case.

I saw that commits created during a reverted rebase remain in the smartlog. This is very minor - users can git hide them, although they aren't marked as successors of the rewritten commits so users will need to resolve the same merge conflict again. This is more of a feature request than a bug report, but can these be marked as a rewrite of the previous commit - so users can continue the sync / restack at a later time?

Re this point, the issue is similar to https://github.com/arxanas/git-branchless/issues/316. There's no post-abort hook, so it would be hard to run any action when a git rebase is aborted, and we don't know what commits have been rewritten into until the end of the rebase when it calls the post-rewrite hook. It would probably be better if we could at least abort the transaction/not register the newly created commits unless the git rebase completes, which would at least ensure that there's only one copy of the same commit in the smartlog as a result.

arxanas avatar Dec 13 '22 22:12 arxanas