summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJuan Sanchez Montalvo <jsmontalvo@osx-l-07779.youview.local>2022-06-24 22:10:13 +0100
committerJesse Duffield <jessedduffield@gmail.com>2022-07-05 19:33:44 +1000
commit11d766053e8fad837d598c9f4d4a0c7af62d0a92 (patch)
tree3b26df22c69c0913693f443775f762d3c41bdb2f /pkg
parent41071c37035a5944f77b4f0da5f07ec3b52fef0e (diff)
Allow adding a file to the .git/info/exclude file
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/git_commands/working_tree.go5
-rw-r--r--pkg/config/user_config.go4
-rw-r--r--pkg/gui/controllers/files_controller.go130
-rw-r--r--pkg/i18n/chinese.go2
-rw-r--r--pkg/i18n/english.go18
-rw-r--r--pkg/i18n/japanese.go2
-rw-r--r--pkg/i18n/korean.go2
7 files changed, 120 insertions, 43 deletions
diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go
index 5986392a8..8fd1fb177 100644
--- a/pkg/commands/git_commands/working_tree.go
+++ b/pkg/commands/git_commands/working_tree.go
@@ -218,6 +218,11 @@ func (self *WorkingTreeCommands) Ignore(filename string) error {
return self.os.AppendLineToFile(".gitignore", filename)
}
+// Exclude adds a file to the .git/info/exclude for the repo
+func (self *WorkingTreeCommands) Exclude(filename string) error {
+ return self.os.AppendLineToFile(".git/info/exclude", filename)
+}
+
// WorktreeFileDiff returns the diff of a file
func (self *WorkingTreeCommands) WorktreeFileDiff(file *models.File, plain bool, cached bool, ignoreWhitespace bool) string {
// for now we assume an error means the file was deleted
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go
index 0b3a91bf6..22c9c81dd 100644
--- a/pkg/config/user_config.go
+++ b/pkg/config/user_config.go
@@ -210,7 +210,7 @@ type KeybindingFilesConfig struct {
CommitChangesWithoutHook string `yaml:"commitChangesWithoutHook"`
AmendLastCommit string `yaml:"amendLastCommit"`
CommitChangesWithEditor string `yaml:"commitChangesWithEditor"`
- IgnoreFile string `yaml:"ignoreFile"`
+ IgnoreOrExcludeFile string `yaml:"IgnoreOrExcludeFile"`
RefreshFiles string `yaml:"refreshFiles"`
StashAllChanges string `yaml:"stashAllChanges"`
ViewStashOptions string `yaml:"viewStashOptions"`
@@ -487,7 +487,7 @@ func GetDefaultConfig() *UserConfig {
CommitChangesWithoutHook: "w",
AmendLastCommit: "A",
CommitChangesWithEditor: "C",
- IgnoreFile: "i",
+ IgnoreOrExcludeFile: "i",
RefreshFiles: "r",
StashAllChanges: "s",
ViewStashOptions: "S",
diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go
index b413f6f5f..4aed5cf0a 100644
--- a/pkg/gui/controllers/files_controller.go
+++ b/pkg/gui/controllers/files_controller.go
@@ -86,9 +86,9 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
Description: self.c.Tr.LcOpenFile,
},
{
- Key: opts.GetKey(opts.Config.Files.IgnoreFile),
- Handler: self.checkSelectedFileNode(self.ignore),
- Description: self.c.Tr.LcIgnoreFile,
+ Key: opts.GetKey(opts.Config.Files.IgnoreOrExcludeFile),
+ Handler: self.checkSelectedFileNode(self.ignoreOrExcludeMenu),
+ Description: self.c.Tr.Actions.IgnoreExcludeFile,
},
{
Key: opts.GetKey(opts.Config.Files.RefreshFiles),
@@ -302,57 +302,113 @@ func (self *FilesController) stageAll() error {
return self.contexts.Files.HandleFocus()
}
-func (self *FilesController) ignore(node *filetree.FileNode) error {
- if node.GetPath() == ".gitignore" {
- return self.c.ErrorMsg("Cannot ignore .gitignore")
+func (self *FilesController) unstageFiles(node *filetree.FileNode) error {
+ return node.ForEachFile(func(file *models.File) error {
+ if file.HasStagedChanges {
+ if err := self.git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
+}
+
+func (self *FilesController) ignoreOrExcludeTracked(node *filetree.FileNode, trAction string, f func(string) error) error {
+ self.c.LogAction(trAction)
+ // not 100% sure if this is necessary but I'll assume it is
+ if err := self.unstageFiles(node); err != nil {
+ return err
}
- unstageFiles := func() error {
- return node.ForEachFile(func(file *models.File) error {
- if file.HasStagedChanges {
- if err := self.git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
- return err
- }
- }
+ if err := self.git.WorkingTree.RemoveTrackedFiles(node.GetPath()); err != nil {
+ return err
+ }
- return nil
- })
+ if err := f(node.GetPath()); err != nil {
+ return err
+ }
+
+ return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
+}
+
+func (self *FilesController) ignoreOrExcludeUntracked(node *filetree.FileNode, trAction string, f func(string) error) error {
+ self.c.LogAction(trAction)
+
+ if err := f(node.GetPath()); err != nil {
+ return err
}
+ return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
+}
+
+func (self *FilesController) ignoreOrExcludeFile(node *filetree.FileNode, trText string, trPrompt string, trAction string, f func(string) error) error {
if node.GetIsTracked() {
return self.c.Confirm(types.ConfirmOpts{
- Title: self.c.Tr.IgnoreTracked,
- Prompt: self.c.Tr.IgnoreTrackedPrompt,
+ Title: trText,
+ Prompt: trPrompt,
HandleConfirm: func() error {
- self.c.LogAction(self.c.Tr.Actions.IgnoreFile)
- // not 100% sure if this is necessary but I'll assume it is
- if err := unstageFiles(); err != nil {
- return err
- }
-
- if err := self.git.WorkingTree.RemoveTrackedFiles(node.GetPath()); err != nil {
- return err
- }
-
- if err := self.git.WorkingTree.Ignore(node.GetPath()); err != nil {
- return err
- }
- return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
+ return self.ignoreOrExcludeTracked(node, trAction, f)
},
})
}
+ return self.ignoreOrExcludeUntracked(node, trAction, f)
+}
- self.c.LogAction(self.c.Tr.Actions.IgnoreFile)
-
- if err := unstageFiles(); err != nil {
+func (self *FilesController) ignore(node *filetree.FileNode) error {
+ if node.GetPath() == ".gitignore" {
+ return self.c.ErrorMsg(self.c.Tr.Actions.IgnoreFileErr)
+ }
+ err := self.ignoreOrExcludeFile(node, self.c.Tr.IgnoreTracked, self.c.Tr.IgnoreTrackedPrompt, self.c.Tr.Actions.IgnoreExcludeFile, self.git.WorkingTree.Ignore)
+ if err != nil {
return err
}
- if err := self.git.WorkingTree.Ignore(node.GetPath()); err != nil {
- return self.c.Error(err)
+ return nil
+}
+
+func (self *FilesController) exclude(node *filetree.FileNode) error {
+ if node.GetPath() == ".git/info/exclude" {
+ return self.c.ErrorMsg(self.c.Tr.Actions.ExcludeFileErr)
}
- return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
+ if node.GetPath() == ".gitignore" {
+ return self.c.ErrorMsg(self.c.Tr.Actions.ExcludeGitIgnoreErr)
+ }
+
+ err := self.ignoreOrExcludeFile(node, self.c.Tr.ExcludeTracked, self.c.Tr.ExcludeTrackedPrompt, self.c.Tr.Actions.ExcludeFile, self.git.WorkingTree.Exclude)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (self *FilesController) ignoreOrExcludeMenu(node *filetree.FileNode) error {
+ return self.c.Menu(types.CreateMenuOptions{
+ Title: self.c.Tr.Actions.IgnoreExcludeFile,
+ Items: []*types.MenuItem{
+ {
+ LabelColumns: []string{self.c.Tr.LcIgnoreFile},
+ OnPress: func() error {
+ if err := self.ignore(node); err != nil {
+ return self.c.Error(err)
+ }
+ return nil
+ },
+ Key: 'i',
+ },
+ {
+ LabelColumns: []string{self.c.Tr.LcExcludeFile},
+ OnPress: func() error {
+ if err := self.exclude(node); err != nil {
+ return self.c.Error(err)
+ }
+ return nil
+ },
+ Key: 'e',
+ },
+ },
+ })
}
func (self *FilesController) HandleWIPCommitPress() error {
diff --git a/pkg/i18n/chinese.go b/pkg/i18n/chinese.go
index 21097f7c4..f39728659 100644
--- a/pkg/i18n/chinese.go
+++ b/pkg/i18n/chinese.go
@@ -507,7 +507,7 @@ func chineseTranslationSet() TranslationSet {
UnstageFile: "取消暂存文件",
UnstageAllFiles: "取消暂存所有文件",
StageAllFiles: "暂存所有文件",
- IgnoreFile: "忽略文件",
+ IgnoreExcludeFile: "忽略文件",
Commit: "提交 (Commit)",
EditFile: "编辑文件",
Push: "推送 (Push)",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 975cc9285..138277ab6 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -155,6 +155,7 @@ type TranslationSet struct {
LcEditFile string
LcOpenFile string
LcIgnoreFile string
+ LcExcludeFile string
LcRefreshFiles string
LcMergeIntoCurrentBranch string
ConfirmQuit string
@@ -345,7 +346,9 @@ type TranslationSet struct {
NotAGitFlowBranch string
NewBranchNamePrompt string
IgnoreTracked string
+ ExcludeTracked string
IgnoreTrackedPrompt string
+ ExcludeTrackedPrompt string
LcViewResetToUpstreamOptions string
LcNextScreenMode string
LcPrevScreenMode string
@@ -560,7 +563,12 @@ type Actions struct {
UnstageFile string
UnstageAllFiles string
StageAllFiles string
+ IgnoreExcludeFile string
IgnoreFile string
+ IgnoreFileErr string
+ ExcludeFile string
+ ExcludeFileErr string
+ ExcludeGitIgnoreErr string
Commit string
EditFile string
Push string
@@ -780,6 +788,7 @@ func EnglishTranslationSet() TranslationSet {
LcEditFile: `edit file`,
LcOpenFile: `open file`,
LcIgnoreFile: `add to .gitignore`,
+ LcExcludeFile: `add to .git/info/exclude`,
LcRefreshFiles: `refresh files`,
LcMergeIntoCurrentBranch: `merge into currently checked out branch`,
ConfirmQuit: `Are you sure you want to quit?`,
@@ -972,6 +981,8 @@ func EnglishTranslationSet() TranslationSet {
NewGitFlowBranchPrompt: "new {{.branchType}} name:",
IgnoreTracked: "Ignore tracked file",
IgnoreTrackedPrompt: "Are you sure you want to ignore a tracked file?",
+ ExcludeTracked: "Exclude tracked file",
+ ExcludeTrackedPrompt: "Are you sure you want to exclude a tracked file?",
LcViewResetToUpstreamOptions: "view upstream reset options",
LcNextScreenMode: "next screen mode (normal/half/fullscreen)",
LcPrevScreenMode: "prev screen mode",
@@ -1169,7 +1180,12 @@ func EnglishTranslationSet() TranslationSet {
UnstageFile: "Unstage file",
UnstageAllFiles: "Unstage all files",
StageAllFiles: "Stage all files",
- IgnoreFile: "Ignore file",
+ IgnoreExcludeFile: "Ignore or Exclude file",
+ IgnoreFile: "Ignore or Exclude file",
+ IgnoreFileErr: "Cannot ignore .gitignore",
+ ExcludeFile: "Exclude file",
+ ExcludeFileErr: "Cannot exclude .git/info/exclude",
+ ExcludeGitIgnoreErr: "Cannot exclude .gitignore",
Commit: "Commit",
EditFile: "Edit file",
Push: "Push",
diff --git a/pkg/i18n/japanese.go b/pkg/i18n/japanese.go
index 64cf5adc1..34b5adae1 100644
--- a/pkg/i18n/japanese.go
+++ b/pkg/i18n/japanese.go
@@ -533,7 +533,7 @@ func japaneseTranslationSet() TranslationSet {
UnstageFile: "ファイルをアンステージ",
UnstageAllFiles: "すべてのファイルをアンステージ",
StageAllFiles: "すべてのファイルをステージ",
- IgnoreFile: "ファイルをignore",
+ IgnoreExcludeFile: "ファイルをignore",
Commit: "コミット",
EditFile: "ファイルを編集",
Push: "Push",
diff --git a/pkg/i18n/korean.go b/pkg/i18n/korean.go
index f1b1759bd..20000fd2f 100644
--- a/pkg/i18n/korean.go
+++ b/pkg/i18n/korean.go
@@ -536,7 +536,7 @@ func koreanTranslationSet() TranslationSet {
UnstageFile: "Unstage file",
UnstageAllFiles: "Unstage all files",
StageAllFiles: "Stage all files",
- IgnoreFile: "Ignore file",
+ IgnoreExcludeFile: "Ignore file",
Commit: "커밋",
EditFile: "파일 수정",
Push: "푸시",