summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-09-30 09:06:11 +1000
committerJesse Duffield <jessedduffield@gmail.com>2020-10-02 08:09:42 +1000
commitea307c8d94623bd0279297db2cf3990492998ab4 (patch)
tree8053c95e8a710656150b3eabd2e8d2cc658655cf
parent7b4a0f20b26d884cb756f09bc7514e57941709d4 (diff)
add more submodule commands
-rw-r--r--pkg/commands/submodules.go28
-rw-r--r--pkg/gui/discard_changes_menu_panel.go17
-rw-r--r--pkg/gui/keybindings.go15
-rw-r--r--pkg/gui/submodules_panel.go114
-rw-r--r--pkg/i18n/english.go12
5 files changed, 130 insertions, 56 deletions
diff --git a/pkg/commands/submodules.go b/pkg/commands/submodules.go
index fb72d090d..5c369ab8e 100644
--- a/pkg/commands/submodules.go
+++ b/pkg/commands/submodules.go
@@ -3,6 +3,7 @@ package commands
import (
"bufio"
"os"
+ "path/filepath"
"regexp"
"github.com/jesseduffield/lazygit/pkg/commands/models"
@@ -59,21 +60,36 @@ func (c *GitCommand) GetSubmoduleConfigs() ([]*models.SubmoduleConfig, error) {
return configs, nil
}
-func (c *GitCommand) SubmoduleStash(config *models.SubmoduleConfig) error {
+func (c *GitCommand) SubmoduleStash(submodule *models.SubmoduleConfig) error {
// if the path does not exist then it hasn't yet been initialized so we'll swallow the error
// because the intention here is to have no dirty worktree state
- if _, err := os.Stat(config.Path); os.IsNotExist(err) {
- c.Log.Infof("submodule path %s does not exist, returning", config.Path)
+ if _, err := os.Stat(submodule.Path); os.IsNotExist(err) {
+ c.Log.Infof("submodule path %s does not exist, returning", submodule.Path)
return nil
}
- return c.OSCommand.RunCommand("git -C %s stash --include-untracked", config.Path)
+ return c.OSCommand.RunCommand("git -C %s stash --include-untracked", submodule.Path)
}
-func (c *GitCommand) SubmoduleReset(config *models.SubmoduleConfig) error {
- return c.OSCommand.RunCommand("git submodule update --force %s", config.Name)
+func (c *GitCommand) SubmoduleReset(submodule *models.SubmoduleConfig) error {
+ return c.OSCommand.RunCommand("git submodule update --init --force %s", submodule.Name)
}
func (c *GitCommand) SubmoduleUpdateAll() error {
+ // not doing an --init here because the user probably doesn't want that
return c.OSCommand.RunCommand("git submodule update --force")
}
+
+func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
+ // based on https://gist.github.com/myusuf3/7f645819ded92bda6677
+
+ if err := c.OSCommand.RunCommand("git submodule deinit %s", submodule.Name); err != nil {
+ return err
+ }
+
+ if err := c.OSCommand.RunCommand("git rm %s", submodule.Path); err != nil {
+ return err
+ }
+
+ return os.RemoveAll(filepath.Join(c.DotGitDir, "modules", submodule.Name))
+}
diff --git a/pkg/gui/discard_changes_menu_panel.go b/pkg/gui/discard_changes_menu_panel.go
index 6805187c4..9d79a70fa 100644
--- a/pkg/gui/discard_changes_menu_panel.go
+++ b/pkg/gui/discard_changes_menu_panel.go
@@ -23,24 +23,15 @@ func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
var menuItems []*menuItem
- submoduleConfigs := gui.State.Submodules
- if file.IsSubmodule(submoduleConfigs) {
- submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
+ submodules := gui.State.Submodules
+ if file.IsSubmodule(submodules) {
+ submodule := file.SubmoduleConfig(submodules)
menuItems = []*menuItem{
{
displayString: gui.Tr.SLocalize("submoduleStashAndReset"),
onPress: func() error {
- if err := gui.GitCommand.UnStageFile(file.Name, file.Tracked); err != nil {
- return gui.surfaceError(err)
- }
- if err := gui.GitCommand.SubmoduleStash(submoduleConfig); err != nil {
- return gui.surfaceError(err)
- }
- if err := gui.GitCommand.SubmoduleReset(submoduleConfig); err != nil {
- return gui.surfaceError(err)
- }
- return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES}})
+ return gui.resetSubmodule(submodule)
},
},
}
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index b08f3df92..fcdbbb2c1 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -1586,6 +1586,21 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.wrappedHandler(gui.handleCopySelectedSideContextItemToClipboard),
Description: gui.Tr.SLocalize("copySubmoduleNameToClipboard"),
},
+ {
+ ViewName: "files",
+ Contexts: []string{SUBMODULES_CONTEXT_KEY},
+ Key: gui.getKey("universal.remove"),
+
+ Handler: gui.wrappedHandler(gui.handleRemoveSubmodule),
+ Description: gui.Tr.SLocalize("removeSubmodule"),
+ },
+ {
+ ViewName: "files",
+ Contexts: []string{SUBMODULES_CONTEXT_KEY},
+ Key: gui.getKey("u"),
+ Handler: gui.wrappedHandler(gui.handleResetSubmodule),
+ Description: gui.Tr.SLocalize("submoduleStashAndReset"),
+ },
}
for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} {
diff --git a/pkg/gui/submodules_panel.go b/pkg/gui/submodules_panel.go
index e956a30f4..7089a9015 100644
--- a/pkg/gui/submodules_panel.go
+++ b/pkg/gui/submodules_panel.go
@@ -25,6 +25,7 @@ func (gui *Gui) handleSubmoduleSelect() error {
task = gui.createRenderStringTask("No submodules")
} else {
// TODO: we want to display the path, name, url, and a diff. We really need to be able to pipe commands together. We can always pipe commands together and just not do it asynchronously, but what if it's an expensive diff to obtain? I think that makes the most sense now though.
+
task = gui.createRenderStringTask(
fmt.Sprintf(
"Name: %s\nPath: %s\nUrl: %s\n",
@@ -62,74 +63,113 @@ func (gui *Gui) enterSubmodule(submodule *models.SubmoduleConfig) error {
return gui.dispatchSwitchToRepo(submodule.Path)
}
-// func (gui *Gui) handleAddRemote(g *gocui.Gui, v *gocui.View) error {
-// return gui.prompt(gui.Tr.SLocalize("newRemoteName"), "", func(remoteName string) error {
-// return gui.prompt(gui.Tr.SLocalize("newRemoteUrl"), "", func(remoteUrl string) error {
-// if err := gui.GitCommand.AddRemote(remoteName, remoteUrl); err != nil {
-// return err
-// }
-// return gui.refreshSidePanels(refreshOptions{scope: []int{REMOTES}})
-// })
-// })
-// }
+func (gui *Gui) handleRemoveSubmodule() error {
+ submodule := gui.getSelectedSubmodule()
+ if submodule == nil {
+ return nil
+ }
-// func (gui *Gui) handleRemoveRemote(g *gocui.Gui, v *gocui.View) error {
-// remote := gui.getSelectedSubmodule()
-// if remote == nil {
-// return nil
-// }
+ return gui.ask(askOpts{
+ title: gui.Tr.SLocalize("RemoveSubmodule"),
+ prompt: gui.Tr.SLocalize("RemoveSubmodulePrompt") + " '" + submodule.Name + "'?",
+ handleConfirm: func() error {
+ if err := gui.GitCommand.SubmoduleDelete(submodule); err != nil {
+ return err
+ }
+
+ return gui.refreshSidePanels(refreshOptions{scope: []int{SUBMODULES, FILES}})
+ },
+ })
+}
+
+func (gui *Gui) handleResetSubmodule() error {
+ return gui.WithWaitingStatus(gui.Tr.SLocalize("resettingSubmoduleStatus"), func() error {
+ submodule := gui.getSelectedSubmodule()
+ if submodule == nil {
+ return nil
+ }
-// return gui.ask(askOpts{
-// title: gui.Tr.SLocalize("removeRemote"),
-// prompt: gui.Tr.SLocalize("removeRemotePrompt") + " '" + remote.Name + "'?",
-// handleConfirm: func() error {
-// if err := gui.GitCommand.RemoveRemote(remote.Name); err != nil {
+ return gui.resetSubmodule(submodule)
+ })
+}
+
+func (gui *Gui) fileForSubmodule(submodule *models.SubmoduleConfig) *models.File {
+ for _, file := range gui.State.Files {
+ if file.IsSubmodule([]*models.SubmoduleConfig{submodule}) {
+ return file
+ }
+ }
+
+ return nil
+}
+
+func (gui *Gui) resetSubmodule(submodule *models.SubmoduleConfig) error {
+ file := gui.fileForSubmodule(submodule)
+ if file != nil {
+ if err := gui.GitCommand.UnStageFile(file.Name, file.Tracked); err != nil {
+ return gui.surfaceError(err)
+ }
+ }
+
+ if err := gui.GitCommand.SubmoduleStash(submodule); err != nil {
+ return gui.surfaceError(err)
+ }
+ if err := gui.GitCommand.SubmoduleReset(submodule); err != nil {
+ return gui.surfaceError(err)
+ }
+
+ return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{FILES, SUBMODULES}})
+}
+
+// func (gui *Gui) handleAddsubmodule(g *gocui.Gui, v *gocui.View) error {
+// return gui.prompt(gui.Tr.SLocalize("newsubmoduleName"), "", func(submoduleName string) error {
+// return gui.prompt(gui.Tr.SLocalize("newsubmoduleUrl"), "", func(submoduleUrl string) error {
+// if err := gui.GitCommand.Addsubmodule(submoduleName, submoduleUrl); err != nil {
// return err
// }
-
-// return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
-// },
+// return gui.refreshSidePanels(refreshOptions{scope: []int{submoduleS}})
+// })
// })
// }
-// func (gui *Gui) handleEditRemote(g *gocui.Gui, v *gocui.View) error {
-// remote := gui.getSelectedSubmodule()
-// if remote == nil {
+// func (gui *Gui) handleEditsubmodule(g *gocui.Gui, v *gocui.View) error {
+// submodule := gui.getSelectedSubmodule()
+// if submodule == nil {
// return nil
// }
// editNameMessage := gui.Tr.TemplateLocalize(
-// "editRemoteName",
+// "editsubmoduleName",
// Teml{
-// "remoteName": remote.Name,
+// "submoduleName": submodule.Name,
// },
// )
-// return gui.prompt(editNameMessage, remote.Name, func(updatedRemoteName string) error {
-// if updatedRemoteName != remote.Name {
-// if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil {
+// return gui.prompt(editNameMessage, submodule.Name, func(updatedsubmoduleName string) error {
+// if updatedsubmoduleName != submodule.Name {
+// if err := gui.GitCommand.Renamesubmodule(submodule.Name, updatedsubmoduleName); err != nil {
// return gui.surfaceError(err)
// }
// }
// editUrlMessage := gui.Tr.TemplateLocalize(
-// "editRemoteUrl",
+// "editsubmoduleUrl",
// Teml{
-// "remoteName": updatedRemoteName,
+// "submoduleName": updatedsubmoduleName,
// },
// )
-// urls := remote.Urls
+// urls := submodule.Urls
// url := ""
// if len(urls) > 0 {
// url = urls[0]
// }
-// return gui.prompt(editUrlMessage, url, func(updatedRemoteUrl string) error {
-// if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil {
+// return gui.prompt(editUrlMessage, url, func(updatedsubmoduleUrl string) error {
+// if err := gui.GitCommand.UpdatesubmoduleUrl(updatedsubmoduleName, updatedsubmoduleUrl); err != nil {
// return gui.surfaceError(err)
// }
-// return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
+// return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, submoduleS}})
// })
// })
// }
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 45a13647f..b2282d5ca 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -1203,6 +1203,18 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "copySubmoduleNameToClipboard",
Other: "copy submodule name to clipboard",
+ }, &i18n.Message{
+ ID: "RemoveSubmodule",
+ Other: "Remove submodule",
+ }, &i18n.Message{
+ ID: "removeSubmodule",
+ Other: "remove submodule",
+ }, &i18n.Message{
+ ID: "RemoveSubmodulePrompt",
+ Other: "Are you sure you want to remove submodule",
+ }, &i18n.Message{
+ ID: "resettingSubmoduleStatus",
+ Other: "resetting submodule",
},
)
}