-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(branch): add gs branch squash
#564
Merged
Merged
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
cc3710f
feat(branch): add `gs branch squash`
jonboiser 7b3a819
git/commit: learn about -t/--template
abhinav b317a28
squash: Use -t/--template to generate initial commit message
abhinav d16f2e1
squash: detach and restore with defer
abhinav 8e1fdf1
doc: explain why we're doing a soft reset
abhinav a31fa26
update-ref: ensure that the branch hasn't moved
abhinav a118e3c
test: update test cases
abhinav 34338db
add --no-verify flag
abhinav 1a2a8cd
doc: adjust the help text
abhinav 337f359
test: verify branch is restored after aborting commit
abhinav File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
kind: Added | ||
body: 'branch squash: Squashses all commits in the current branch into a single commit and restacks the upstack branches.' | ||
time: 2025-02-02T19:27:29.806629-08:00 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/charmbracelet/log" | ||
"go.abhg.dev/gs/internal/git" | ||
"go.abhg.dev/gs/internal/spice" | ||
"go.abhg.dev/gs/internal/spice/state" | ||
"go.abhg.dev/gs/internal/text" | ||
"go.abhg.dev/gs/internal/ui" | ||
) | ||
|
||
type branchSquashCmd struct { | ||
Message string `short:"m" placeholder:"MSG" help:"Use the given message as the commit message."` | ||
} | ||
|
||
func (*branchSquashCmd) Help() string { | ||
return text.Dedent(` | ||
Squash all commits in the current branch into a single commit | ||
and restack upstack branches. | ||
`) | ||
} | ||
|
||
func (cmd *branchSquashCmd) Run( | ||
ctx context.Context, | ||
log *log.Logger, | ||
view ui.View, | ||
repo *git.Repository, | ||
store *state.Store, | ||
svc *spice.Service, | ||
) error { | ||
branchName, err := repo.CurrentBranch(ctx) | ||
if err != nil { | ||
return fmt.Errorf("get current branch: %w", err) | ||
} | ||
|
||
branch, err := svc.LookupBranch(ctx, branchName) | ||
if err != nil { | ||
return fmt.Errorf("lookup branch %q: %w", branchName, err) | ||
} | ||
|
||
if err := svc.VerifyRestacked(ctx, branchName); err != nil { | ||
var restackErr *spice.BranchNeedsRestackError | ||
if errors.As(err, &restackErr) { | ||
return fmt.Errorf("branch %v needs to be restacked before it can be squashed", branchName) | ||
} | ||
return fmt.Errorf("verify restacked: %w", err) | ||
} | ||
|
||
commitMsg := cmd.Message | ||
|
||
if commitMsg == "" { | ||
commitMessages, err := repo.CommitMessageRange(ctx, branch.Head.String(), branch.BaseHash.String()) | ||
if err != nil { | ||
return fmt.Errorf("get commit messages: %w", err) | ||
} | ||
commitMsg = commitMessages[len(commitMessages)-1].String() | ||
} | ||
|
||
// Checkout the branch in detached mode | ||
if err := (&branchCheckoutCmd{ | ||
Branch: branchName, | ||
checkoutOptions: checkoutOptions{ | ||
Detach: true, | ||
}, | ||
}).Run(ctx, log, view, repo, store, svc); err != nil { | ||
return err | ||
} | ||
|
||
// Reset the detached branch to the base commit | ||
if err := repo.Reset(ctx, branch.BaseHash.String(), git.ResetOptions{Mode: git.ResetSoft}); err != nil { | ||
return err | ||
} | ||
|
||
// Commit the changes | ||
if err := repo.Commit(ctx, git.CommitRequest{Message: commitMsg}); err != nil { | ||
return err | ||
} | ||
|
||
// Replace the HEAD ref of `branchName` with the new commit | ||
headHash, err := repo.Head(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err := repo.SetRef(ctx, git.SetRefRequest{ | ||
Ref: "refs/heads/" + branchName, | ||
Hash: headHash, | ||
}); err != nil { | ||
return err | ||
} | ||
|
||
// Check out the original branch | ||
if err := repo.Checkout(ctx, branchName); err != nil { | ||
return err | ||
} | ||
|
||
return (&upstackRestackCmd{}).Run(ctx, log, repo, store, svc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Squashing a branch into one commit with 'squash' | ||
|
||
as 'Test <[email protected]>' | ||
at '2024-03-30T14:59:32Z' | ||
|
||
cd repo | ||
git init | ||
git commit --allow-empty -m 'Initial commit' | ||
gs repo i | ||
|
||
# Create a branch with two commits | ||
git add feature1.txt | ||
gs branch create feature-1 -m 'First message in squashed branch' | ||
git add feature2.txt | ||
git commit -m 'Second message in squashed branch' | ||
|
||
# Create another branch | ||
git add feature3.txt | ||
gs branch create feature2 -m 'First message in rebased branch' | ||
|
||
git graph --branches | ||
cmp stdout $WORK/golden/graph-before.txt | ||
|
||
# Go back to branch that will be squashed | ||
gs down | ||
gs branch squash | ||
|
||
git graph --branches | ||
cmp stdout $WORK/golden/graph.txt | ||
|
||
-- repo/dirty.txt -- | ||
Dirty | ||
-- repo/feature1.txt -- | ||
Feature 1 | ||
-- repo/feature2.txt -- | ||
Feature 2 | ||
-- repo/feature3.txt -- | ||
Feature 3 | ||
-- golden/graph-before.txt -- | ||
* d805cb2 (HEAD -> feature2) First message in rebased branch | ||
* 0239007 (feature-1) Second message in squashed branch | ||
* 7ebfd80 First message in squashed branch | ||
* 9bad92b (main) Initial commit | ||
-- golden/graph.txt -- | ||
* cbeb99e (feature2) First message in rebased branch | ||
* 6ca0ea8 (HEAD -> feature-1) First message in squashed branch | ||
* 9bad92b (main) Initial commit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Squashing a branch into one commit with 'squash' | ||
|
||
as 'Test <[email protected]>' | ||
at '2024-03-30T14:59:32Z' | ||
|
||
cd repo | ||
git init | ||
git commit --allow-empty -m 'Initial commit' | ||
gs repo i | ||
|
||
# Create a branch with two commits | ||
git add feature1.txt | ||
gs branch create feature-1 -m 'First message in squashed branch' | ||
git add feature2.txt | ||
git commit -m 'Second message in squashed branch' | ||
|
||
# Create another branch | ||
git add feature3.txt | ||
gs branch create feature2 -m 'First message in rebased branch' | ||
|
||
git graph --branches | ||
cmp stdout $WORK/golden/graph-before.txt | ||
|
||
# Go back to branch that will be squashed | ||
gs down | ||
gs branch squash -m 'squash feature-1 into one commit' | ||
|
||
git graph --branches | ||
cmp stdout $WORK/golden/graph.txt | ||
|
||
-- repo/dirty.txt -- | ||
Dirty | ||
-- repo/feature1.txt -- | ||
Feature 1 | ||
-- repo/feature2.txt -- | ||
Feature 2 | ||
-- repo/feature3.txt -- | ||
Feature 3 | ||
-- golden/graph-before.txt -- | ||
* d805cb2 (HEAD -> feature2) First message in rebased branch | ||
* 0239007 (feature-1) Second message in squashed branch | ||
* 7ebfd80 First message in squashed branch | ||
* 9bad92b (main) Initial commit | ||
-- golden/graph.txt -- | ||
* 8323247 (feature2) First message in rebased branch | ||
* 3267250 (HEAD -> feature-1) squash feature-1 into one commit | ||
* 9bad92b (main) Initial commit |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😅 thanks!