From 3cb0a735f6c5a2c39a9214aa8798966e2761d4dc Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Sat, 1 Jun 2024 12:29:59 -0700 Subject: [PATCH] branch rename: Support form (#139) With this, 'branch rename' supports the following three forms: branch rename branch rename # old = current branch rename # old = current, new = prompt --- .../unreleased/Added-20240601-122230.yaml | 3 ++ branch_rename.go | 44 ++++++++++++++----- doc/reference.md | 18 ++++++-- testdata/script/branch_rename_old_new.txt | 26 +++++++++++ 4 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 .changes/unreleased/Added-20240601-122230.yaml create mode 100644 testdata/script/branch_rename_old_new.txt diff --git a/.changes/unreleased/Added-20240601-122230.yaml b/.changes/unreleased/Added-20240601-122230.yaml new file mode 100644 index 00000000..15f09548 --- /dev/null +++ b/.changes/unreleased/Added-20240601-122230.yaml @@ -0,0 +1,3 @@ +kind: Added +body: 'branch rename: Support renaming another branch by name with the `branch rename ` form of the command.' +time: 2024-06-01T12:22:30.93713-07:00 diff --git a/branch_rename.go b/branch_rename.go index 0e746579..3578e7c9 100644 --- a/branch_rename.go +++ b/branch_rename.go @@ -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 to + gs branch rename + + # Rename current branch to + gs branch rename - 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'. `) @@ -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 ", + // we'll actually get oldName = 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 { @@ -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) } diff --git a/doc/reference.md b/doc/reference.md index c1c54747..5374e1d4 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -413,20 +413,30 @@ will be restacked. ## gs branch rename ``` -gs branch (b) rename (rn,mv) [] +gs branch (b) rename (rn,mv) [ []] ``` 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 to + gs branch rename + + # Rename current branch to + gs branch rename + + # 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 diff --git a/testdata/script/branch_rename_old_new.txt b/testdata/script/branch_rename_old_new.txt new file mode 100644 index 00000000..b301efbe --- /dev/null +++ b/testdata/script/branch_rename_old_new.txt @@ -0,0 +1,26 @@ +# Renaming a branch by name. + +as 'Test ' +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