Skip to content

Commit

Permalink
branch rename: Support <old> <new> form (#139)
Browse files Browse the repository at this point in the history
With this, 'branch rename' supports the following three forms:

    branch rename <old> <new>
    branch rename <new> # old = current
    branch rename       # old = current, new = prompt
  • Loading branch information
abhinav authored Jun 1, 2024
1 parent 9e7becf commit 3cb0a73
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .changes/unreleased/Added-20240601-122230.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Added
body: 'branch rename: Support renaming another branch by name with the `branch rename <old> <new>` form of the command.'
time: 2024-06-01T12:22:30.93713-07:00
44 changes: 32 additions & 12 deletions branch_rename.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,31 @@ import (

"github.com/charmbracelet/log"
"go.abhg.dev/gs/internal/git"
"go.abhg.dev/gs/internal/must"
"go.abhg.dev/gs/internal/spice"
"go.abhg.dev/gs/internal/text"
"go.abhg.dev/gs/internal/ui"
)

type branchRenameCmd struct {
// TODO: optional old name

Name string `arg:"" optional:"" help:"New name of the branch"`
OldName string `arg:"" optional:"" help:"Old name of the branch"`
NewName string `arg:"" optional:"" help:"New name of the branch"`
}

func (*branchRenameCmd) Help() string {
return text.Dedent(`
Renames a tracked branch, updating internal references to it.
The following modes are supported:
# Rename <old> to <new>
gs branch rename <old> <new>
# Rename current branch to <new>
gs branch rename <new>
If you renamed a branch without using this command,
# Rename current branch interactively
gs branch rename
If you renamed a branch without this command,
track the new branch name with 'gs branch track',
and untrack the old name with 'gs branch untrack'.
`)
Expand All @@ -36,15 +45,23 @@ func (cmd *branchRenameCmd) Run(ctx context.Context, log *log.Logger, opts *glob
return fmt.Errorf("open repository: %w", err)
}

// TODO: support: rename [old] new
oldName, err := repo.CurrentBranch(ctx)
if err != nil {
return fmt.Errorf("get current branch: %w", err)
oldName, newName := cmd.OldName, cmd.NewName
// For "gs branch rename <new>",
// we'll actually get oldName = <new> and newName = "".
if oldName != "" && newName == "" {
oldName, newName = "", oldName
}

if cmd.Name == "" {
if oldName == "" {
oldName, err = repo.CurrentBranch(ctx)
if err != nil {
return fmt.Errorf("get current branch: %w", err)
}
}

if newName == "" {
prompt := ui.NewInput().
WithValue(&cmd.Name).
WithValue(&newName).
WithTitle("New branch name").
WithDescription(fmt.Sprintf("Renaming branch: %v", oldName)).
WithValidate(func(s string) error {
Expand All @@ -59,13 +76,16 @@ func (cmd *branchRenameCmd) Run(ctx context.Context, log *log.Logger, opts *glob
}
}

must.NotBeBlankf(oldName, "old branch name must be set")
must.NotBeBlankf(newName, "new branch name must be set")

store, err := ensureStore(ctx, repo, log, opts)
if err != nil {
return err
}

svc := spice.NewService(repo, store, log)
if err := svc.RenameBranch(ctx, oldName, cmd.Name); err != nil {
if err := svc.RenameBranch(ctx, oldName, newName); err != nil {
return fmt.Errorf("rename branch: %w", err)
}

Expand Down
18 changes: 14 additions & 4 deletions doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,20 +413,30 @@ will be restacked.
## gs branch rename

```
gs branch (b) rename (rn,mv) [<name>]
gs branch (b) rename (rn,mv) [<old-name> [<new-name>]]
```

Rename a branch

Renames a tracked branch, updating internal references to it.
The following modes are supported:

If you renamed a branch without using this command,
# Rename <old> to <new>
gs branch rename <old> <new>

# Rename current branch to <new>
gs branch rename <new>

# Rename current branch interactively
gs branch rename

If you renamed a branch without this command,
track the new branch name with 'gs branch track',
and untrack the old name with 'gs branch untrack'.

**Arguments**

* `name`: New name of the branch
* `old-name`: Old name of the branch
* `new-name`: New name of the branch

## gs branch restack

Expand Down
26 changes: 26 additions & 0 deletions testdata/script/branch_rename_old_new.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Renaming a branch by name.

as 'Test <[email protected]>'
at '2024-06-01T12:15:12Z'

mkdir repo
cd repo
git init
git commit --allow-empty -m 'Initial commit'
gs repo init

git add foo.txt
gs branch create oldname -m 'Do things'
gs trunk

gs branch rename oldname newname
git graph --branches
cmp stdout $WORK/golden/graph.txt


-- repo/foo.txt --
whatever

-- golden/graph.txt --
* 1f8dc81 (newname) Do things
* 0cfef96 (HEAD -> main) Initial commit

0 comments on commit 3cb0a73

Please sign in to comment.