Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions pkg/gui/controllers/tags_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,59 @@ func (self *TagsController) remoteDelete(tag *models.Tag) error {
return nil
}

func (self *TagsController) localAndRemoteDelete(tag *models.Tag) error {
title := utils.ResolvePlaceholderString(
self.c.Tr.SelectRemoteTagUpstream,
map[string]string{
"tagName": tag.Name,
},
)

self.c.Prompt(types.PromptOpts{
Title: title,
InitialContent: "origin",
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRemoteSuggestionsFunc(),
HandleConfirm: func(upstream string) error {
confirmTitle := utils.ResolvePlaceholderString(
self.c.Tr.DeleteTagTitle,
map[string]string{
"tagName": tag.Name,
},
)
confirmPrompt := utils.ResolvePlaceholderString(
self.c.Tr.DeleteLocalAndRemoteTagPrompt,
map[string]string{
"tagName": tag.Name,
"upstream": upstream,
},
)

self.c.Confirm(types.ConfirmOpts{
Title: confirmTitle,
Prompt: confirmPrompt,
HandleConfirm: func() error {
return self.c.WithInlineStatus(tag, types.ItemOperationDeleting, context.TAGS_CONTEXT_KEY, func(task gocui.Task) error {
self.c.LogAction(self.c.Tr.Actions.DeleteRemoteTag)
if err := self.c.Git().Remote.DeleteRemoteTag(task, upstream, tag.Name); err != nil {
return err
}

self.c.LogAction(self.c.Tr.Actions.DeleteLocalTag)
if err := self.c.Git().Tag.LocalDelete(tag.Name); err != nil {
return err
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS, types.TAGS}})
})
},
})

return nil
},
})

return nil
}

func (self *TagsController) delete(tag *models.Tag) error {
menuTitle := utils.ResolvePlaceholderString(
self.c.Tr.DeleteTagTitle,
Expand All @@ -201,6 +254,14 @@ func (self *TagsController) delete(tag *models.Tag) error {
return self.remoteDelete(tag)
},
},
{
Label: self.c.Tr.DeleteLocalAndRemoteTag,
Key: 'b',
OpensMenu: true,
OnPress: func() error {
return self.localAndRemoteDelete(tag)
},
},
}

return self.c.Menu(types.CreateMenuOptions{
Expand Down
4 changes: 4 additions & 0 deletions pkg/i18n/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,10 @@ type TranslationSet struct {
DeleteTagTitle string
DeleteLocalTag string
DeleteRemoteTag string
DeleteLocalAndRemoteTag string
SelectRemoteTagUpstream string
DeleteRemoteTagPrompt string
DeleteLocalAndRemoteTagPrompt string
RemoteTagDeletedMessage string
PushTagTitle string
PushTag string
Expand Down Expand Up @@ -1539,9 +1541,11 @@ func EnglishTranslationSet() *TranslationSet {
DeleteTagTitle: "Delete tag '{{.tagName}}'?",
DeleteLocalTag: "Delete local tag",
DeleteRemoteTag: "Delete remote tag",
DeleteLocalAndRemoteTag: "Delete local and remote tag",
RemoteTagDeletedMessage: "Remote tag deleted",
SelectRemoteTagUpstream: "Remote from which to remove tag '{{.tagName}}':",
DeleteRemoteTagPrompt: "Are you sure you want to delete the remote tag '{{.tagName}}' from '{{.upstream}}'?",
DeleteLocalAndRemoteTagPrompt: "Are you sure you want to delete '{{.tagName}}' from both your machine and from '{{.upstream}}'?",
PushTagTitle: "Remote to push tag '{{.tagName}}' to:",
// Using 'push tag' rather than just 'push' to disambiguate from a global push
PushTag: "Push tag",
Expand Down
4 changes: 4 additions & 0 deletions pkg/integration/components/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ func (self *Shell) Revert(ref string) *Shell {
return self.RunCommand([]string{"git", "revert", ref})
}

func (self *Shell) AssertRemoteTagNotFound(upstream, name string) *Shell {
return self.RunCommandExpectError([]string{"git", "ls-remote", "--exit-code", upstream, fmt.Sprintf("refs/tags/%s", name)})
}

func (self *Shell) CreateLightweightTag(name string, ref string) *Shell {
return self.RunCommand([]string{"git", "tag", name, ref})
}
Expand Down
75 changes: 75 additions & 0 deletions pkg/integration/tests/tag/delete_local_and_remote.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package tag

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)

var DeleteLocalAndRemote = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Create and delete both local and remote annotated tag",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("initial commit")
shell.CloneIntoRemote("origin")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Tags().
Focus().
IsEmpty().
Press(keys.Universal.New).
Tap(func() {
t.ExpectPopup().CommitMessagePanel().
Title(Equals("Tag name")).
Type("new-tag").
SwitchToDescription().
Title(Equals("Tag description")).
Type("message").
SwitchToSummary().
Confirm()
}).
Lines(
MatchesRegexp(`new-tag.*message`).IsSelected(),
).
Press(keys.Universal.Push).
Tap(func() {
t.ExpectPopup().Prompt().
Title(Equals("Remote to push tag 'new-tag' to:")).
InitialText(Equals("origin")).
SuggestionLines(
Contains("origin"),
).
Confirm()
}).
Press(keys.Universal.Remove).
Tap(func() {
t.ExpectPopup().
Menu().
Title(Equals("Delete tag 'new-tag'?")).
Select(Contains("Delete local and remote tag")).
Confirm()
}).
Tap(func() {
t.ExpectPopup().Prompt().
Title(Equals("Remote from which to remove tag 'new-tag':")).
InitialText(Equals("origin")).
SuggestionLines(
Contains("origin"),
).
Confirm()
}).
Tap(func() {
t.ExpectPopup().
Confirmation().
Title(Equals("Delete tag 'new-tag'?")).
Content(Equals("Are you sure you want to delete 'new-tag' from both your machine and from 'origin'?")).
Confirm()
}).
IsEmpty().
Press(keys.Universal.New).
Tap(func() {
t.Shell().AssertRemoteTagNotFound("origin", "new-tag")
})
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ var tests = []*components.IntegrationTest{
tag.CreateWhileCommitting,
tag.CrudAnnotated,
tag.CrudLightweight,
tag.DeleteLocalAndRemote,
tag.ForceTagAnnotated,
tag.ForceTagLightweight,
tag.Reset,
Expand Down