diff options
author | Juan Sanchez Montalvo <jsmontalvo@osx-l-07779.youview.local> | 2022-06-24 22:10:13 +0100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2022-07-05 19:33:44 +1000 |
commit | 11d766053e8fad837d598c9f4d4a0c7af62d0a92 (patch) | |
tree | 3b26df22c69c0913693f443775f762d3c41bdb2f /pkg | |
parent | 41071c37035a5944f77b4f0da5f07ec3b52fef0e (diff) |
Allow adding a file to the .git/info/exclude file
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/git_commands/working_tree.go | 5 | ||||
-rw-r--r-- | pkg/config/user_config.go | 4 | ||||
-rw-r--r-- | pkg/gui/controllers/files_controller.go | 130 | ||||
-rw-r--r-- | pkg/i18n/chinese.go | 2 | ||||
-rw-r--r-- | pkg/i18n/english.go | 18 | ||||
-rw-r--r-- | pkg/i18n/japanese.go | 2 | ||||
-rw-r--r-- | pkg/i18n/korean.go | 2 |
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: "푸시", |