mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-03 13:21:56 +02:00
allow user to discard old file changes for a given commit
This commit is contained in:
parent
0e008cc15f
commit
4f7f6a073c
14
pkg/commands/errors.go
Normal file
14
pkg/commands/errors.go
Normal file
@ -0,0 +1,14 @@
|
||||
package commands
|
||||
|
||||
import "github.com/go-errors/errors"
|
||||
|
||||
// WrapError wraps an error for the sake of showing a stack trace at the top level
|
||||
// the go-errors package, for some reason, does not return nil when you try to wrap
|
||||
// a non-error, so we're just doing it here
|
||||
func WrapError(err error) error {
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errors.Wrap(err, 0)
|
||||
}
|
@ -32,11 +32,11 @@ func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir f
|
||||
}
|
||||
|
||||
if !os.IsNotExist(err) {
|
||||
return errors.Wrap(err, 0)
|
||||
return WrapError(err)
|
||||
}
|
||||
|
||||
if err = chdir(".."); err != nil {
|
||||
return errors.Wrap(err, 0)
|
||||
return WrapError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -797,10 +797,25 @@ func (c *GitCommand) CherryPickCommits(commits []*Commit) error {
|
||||
return c.OSCommand.RunPreparedCommand(cmd)
|
||||
}
|
||||
|
||||
// CommitFiles get the specified commit files
|
||||
func (c *GitCommand) CommitFiles(commitID string) (string, error) {
|
||||
// GetCommitFiles get the specified commit files
|
||||
func (c *GitCommand) GetCommitFiles(commitID string) ([]*CommitFile, error) {
|
||||
cmd := fmt.Sprintf("git show --pretty= --name-only %s", commitID)
|
||||
return c.OSCommand.RunCommandWithOutput(cmd)
|
||||
files, err := c.OSCommand.RunCommandWithOutput(cmd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commitFiles := make([]*CommitFile, 0)
|
||||
|
||||
for _, file := range strings.Split(strings.TrimRight(files, "\n"), "\n") {
|
||||
commitFiles = append(commitFiles, &CommitFile{
|
||||
Sha: commitID,
|
||||
Name: file,
|
||||
DisplayString: file,
|
||||
})
|
||||
}
|
||||
|
||||
return commitFiles, nil
|
||||
}
|
||||
|
||||
// ShowCommitFile get the diff of specified commit file
|
||||
@ -814,3 +829,55 @@ func (c *GitCommand) CheckoutFile(commitSha, fileName string) error {
|
||||
cmd := fmt.Sprintf("git checkout %s %s", commitSha, fileName)
|
||||
return c.OSCommand.RunCommand(cmd)
|
||||
}
|
||||
|
||||
// DiscardOldFileChanges discards changes to a file from an old commit
|
||||
func (c *GitCommand) DiscardOldFileChanges(commits []*Commit, commitIndex int, fileName string) error {
|
||||
// we can make this GPG thing possible it just means we need to do this in two parts:
|
||||
// one where we handle the possibility of a credential request, and the other
|
||||
// where we continue the rebase
|
||||
if c.usingGpg() {
|
||||
errors.New("feature not available for users using GPG")
|
||||
}
|
||||
|
||||
commitSha := commits[commitIndex].Sha
|
||||
|
||||
todo, err := c.GenerateGenericRebaseTodo(commits, commitIndex, "edit")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd, err := c.PrepareInteractiveRebaseCommand(commitSha+"^", todo, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.OSCommand.RunPreparedCommand(cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check if file exists in previous commit (this command returns an error if the file doesn't exist)
|
||||
if err := c.OSCommand.RunCommand(fmt.Sprintf("git cat-file -e HEAD^:%s", fileName)); err != nil {
|
||||
if err := c.OSCommand.RemoveFile(fileName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.StageFile(fileName); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := c.CheckoutFile("HEAD^", fileName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// amend the commit
|
||||
cmd, err = c.AmendHead()
|
||||
if cmd != nil {
|
||||
errors.New("received unexpected pointer to cmd")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// continue
|
||||
return c.GenericMerge("rebase", "continue")
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||
// errors like 'exit status 1' are not very useful so we'll create an error
|
||||
// from the combined output
|
||||
if outputString == "" {
|
||||
return "", errors.Wrap(err, 0)
|
||||
return "", WrapError(err)
|
||||
}
|
||||
return outputString, errors.New(outputString)
|
||||
}
|
||||
@ -224,13 +224,13 @@ func (c *OSCommand) Unquote(message string) string {
|
||||
func (c *OSCommand) AppendLineToFile(filename, line string) error {
|
||||
f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, 0)
|
||||
return WrapError(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString("\n" + line)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, 0)
|
||||
return WrapError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -240,16 +240,16 @@ func (c *OSCommand) CreateTempFile(filename, content string) (string, error) {
|
||||
tmpfile, err := ioutil.TempFile("", filename)
|
||||
if err != nil {
|
||||
c.Log.Error(err)
|
||||
return "", errors.Wrap(err, 0)
|
||||
return "", WrapError(err)
|
||||
}
|
||||
|
||||
if _, err := tmpfile.WriteString(content); err != nil {
|
||||
c.Log.Error(err)
|
||||
return "", errors.Wrap(err, 0)
|
||||
return "", WrapError(err)
|
||||
}
|
||||
if err := tmpfile.Close(); err != nil {
|
||||
c.Log.Error(err)
|
||||
return "", errors.Wrap(err, 0)
|
||||
return "", WrapError(err)
|
||||
}
|
||||
|
||||
return tmpfile.Name(), nil
|
||||
@ -258,7 +258,7 @@ func (c *OSCommand) CreateTempFile(filename, content string) (string, error) {
|
||||
// RemoveFile removes a file at the specified path
|
||||
func (c *OSCommand) RemoveFile(filename string) error {
|
||||
err := os.Remove(filename)
|
||||
return errors.Wrap(err, 0)
|
||||
return WrapError(err)
|
||||
}
|
||||
|
||||
// FileExists checks whether a file exists at the specified path
|
||||
|
@ -53,12 +53,49 @@ func (gui *Gui) handleSwitchToCommitsPanel(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleCheckoutCommitFile(g *gocui.Gui, v *gocui.View) error {
|
||||
commitSha := gui.State.Commits[gui.State.Panels.Commits.SelectedLine].Sha
|
||||
fileName := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name
|
||||
file := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine]
|
||||
|
||||
if err := gui.GitCommand.CheckoutFile(commitSha, fileName); err != nil {
|
||||
if err := gui.GitCommand.CheckoutFile(file.Sha, file.Name); err != nil {
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
|
||||
return gui.refreshFiles()
|
||||
}
|
||||
|
||||
func (gui *Gui) handleDiscardOldFileChange(g *gocui.Gui, v *gocui.View) error {
|
||||
fileName := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name
|
||||
|
||||
return gui.createConfirmationPanel(gui.g, v, gui.Tr.SLocalize("DiscardFileChangesTitle"), gui.Tr.SLocalize("DiscardFileChangesPrompt"), func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.WithWaitingStatus(gui.Tr.SLocalize("RebasingStatus"), func() error {
|
||||
if err := gui.GitCommand.DiscardOldFileChanges(gui.State.Commits, gui.State.Panels.Commits.SelectedLine, fileName); err != nil {
|
||||
if err := gui.handleGenericMergeCommandResult(err); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return gui.refreshSidePanels(gui.g)
|
||||
})
|
||||
}, nil)
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshCommitFilesView() error {
|
||||
commit := gui.getSelectedCommit(gui.g)
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
files, err := gui.GitCommand.GetCommitFiles(commit.Sha)
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
}
|
||||
|
||||
gui.State.CommitFiles = files
|
||||
|
||||
gui.refreshSelectedLine(&gui.State.Panels.CommitFiles.SelectedLine, len(gui.State.CommitFiles))
|
||||
|
||||
if err := gui.renderListPanel(gui.getCommitFilesView(), gui.State.CommitFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.handleCommitFileSelect(gui.g, gui.getCommitFilesView())
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package gui
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
|
||||
@ -72,9 +71,12 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error {
|
||||
fmt.Fprint(v, list)
|
||||
|
||||
gui.refreshStatus(g)
|
||||
if v == g.CurrentView() {
|
||||
if g.CurrentView() == v {
|
||||
gui.handleCommitSelect(g, v)
|
||||
}
|
||||
if g.CurrentView() == gui.getCommitFilesView() {
|
||||
gui.refreshCommitFilesView()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
@ -440,36 +442,9 @@ func (gui *Gui) HandlePasteCommits(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSwitchToCommitFilesPanel(g *gocui.Gui, v *gocui.View) error {
|
||||
commit := gui.getSelectedCommit(g)
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
commitfileView, err := g.View("commitFiles")
|
||||
if err != nil {
|
||||
if err := gui.refreshCommitFilesView(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
files, err := gui.GitCommand.CommitFiles(commit.Sha)
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(g, err.Error())
|
||||
}
|
||||
|
||||
gui.State.Panels.CommitFiles = &commitFilesPanelState{SelectedLine: 0}
|
||||
gui.State.CommitFiles = make([]*commands.CommitFile, 0)
|
||||
|
||||
if files == "" {
|
||||
gui.State.Panels.CommitFiles.SelectedLine = -1
|
||||
}
|
||||
|
||||
for _, file := range strings.Split(strings.TrimRight(files, "\n"), "\n") {
|
||||
gui.State.CommitFiles = append(gui.State.CommitFiles, &commands.CommitFile{
|
||||
Sha: commit.Sha,
|
||||
Name: file,
|
||||
DisplayString: file,
|
||||
})
|
||||
}
|
||||
|
||||
gui.renderListPanel(gui.getCommitFilesView(), gui.State.CommitFiles)
|
||||
return gui.switchFocus(g, v, commitfileView)
|
||||
return gui.switchFocus(g, v, gui.getCommitFilesView())
|
||||
}
|
||||
|
@ -155,11 +155,12 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
|
||||
StashEntries: make([]*commands.StashEntry, 0),
|
||||
Platform: *oSCommand.Platform,
|
||||
Panels: &panelStates{
|
||||
Files: &filePanelState{SelectedLine: -1},
|
||||
Branches: &branchPanelState{SelectedLine: 0},
|
||||
Commits: &commitPanelState{SelectedLine: -1},
|
||||
Stash: &stashPanelState{SelectedLine: -1},
|
||||
Menu: &menuPanelState{SelectedLine: 0},
|
||||
Files: &filePanelState{SelectedLine: -1},
|
||||
Branches: &branchPanelState{SelectedLine: 0},
|
||||
Commits: &commitPanelState{SelectedLine: -1},
|
||||
CommitFiles: &commitFilesPanelState{SelectedLine: -1},
|
||||
Stash: &stashPanelState{SelectedLine: -1},
|
||||
Menu: &menuPanelState{SelectedLine: 0},
|
||||
Merging: &mergingPanelState{
|
||||
ConflictIndex: 0,
|
||||
ConflictTop: true,
|
||||
@ -219,20 +220,21 @@ func max(a, b int) int {
|
||||
|
||||
// getFocusLayout returns a manager function for when view gain and lose focus
|
||||
func (gui *Gui) getFocusLayout() func(g *gocui.Gui) error {
|
||||
var focusedView *gocui.View
|
||||
var previousView *gocui.View
|
||||
return func(g *gocui.Gui) error {
|
||||
v := gui.g.CurrentView()
|
||||
if v != focusedView {
|
||||
if err := gui.onFocusChange(); err != nil {
|
||||
newView := gui.g.CurrentView()
|
||||
if err := gui.onFocusChange(); err != nil {
|
||||
return err
|
||||
}
|
||||
// for now we don't consider losing focus to a popup panel as actually losing focus
|
||||
if newView != previousView && !gui.isPopupPanel(newView.Name()) {
|
||||
if err := gui.onFocusLost(previousView, newView); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gui.onFocusLost(focusedView); err != nil {
|
||||
if err := gui.onFocus(newView); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gui.onFocus(v); err != nil {
|
||||
return err
|
||||
}
|
||||
focusedView = v
|
||||
previousView = newView
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -246,31 +248,23 @@ func (gui *Gui) onFocusChange() error {
|
||||
return gui.setMainTitle()
|
||||
}
|
||||
|
||||
func (gui *Gui) onFocusLost(v *gocui.View) error {
|
||||
func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
if v.Name() == "branches" {
|
||||
// This stops the branches panel from showing the upstream/downstream changes to the selected branch, when it loses focus
|
||||
// inside renderListPanel it checks to see if the panel has focus
|
||||
if err := gui.renderListPanel(gui.getBranchesView(), gui.State.Branches); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if v.Name() == "main" {
|
||||
// if we have lost focus to a popup panel, that's okay
|
||||
if gui.popupPanelFocused() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if we have lost focus to a first-class panel, we need to do some cleanup
|
||||
if err := gui.changeContext("main", "normal"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else if v.Name() == "commitFiles" {
|
||||
// if we have lost focus to a popup panel, that's okay
|
||||
if gui.popupPanelFocused() {
|
||||
return nil
|
||||
}
|
||||
|
||||
gui.g.SetViewOnBottom(v.Name())
|
||||
}
|
||||
gui.Log.Info(v.Name() + " focus lost")
|
||||
|
@ -459,10 +459,16 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||
Modifier: gocui.ModNone,
|
||||
Handler: gui.handleCheckoutCommitFile,
|
||||
Description: gui.Tr.SLocalize("checkoutCommitFile"),
|
||||
}, {
|
||||
ViewName: "commitFiles",
|
||||
Key: 'd',
|
||||
Modifier: gocui.ModNone,
|
||||
Handler: gui.handleDiscardOldFileChange,
|
||||
Description: gui.Tr.SLocalize("discardOldFileChange"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, viewName := range []string{"status", "branches", "files", "commits", "stash", "menu"} {
|
||||
for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} {
|
||||
bindings = append(bindings, []*Binding{
|
||||
{ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView},
|
||||
|
@ -22,6 +22,11 @@ func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
|
||||
if err := gui.refreshCommits(g); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gui.refreshCommitFilesView(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.refreshStashEntries(g)
|
||||
}
|
||||
|
||||
@ -30,8 +35,13 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
||||
if v == nil || v.Name() == cyclableViews[len(cyclableViews)-1] {
|
||||
focusedViewName = cyclableViews[0]
|
||||
} else {
|
||||
// if we're in the commitFiles view we'll act like we're in the commits view
|
||||
viewName := v.Name()
|
||||
if viewName == "commitFiles" {
|
||||
viewName = "commits"
|
||||
}
|
||||
for i := range cyclableViews {
|
||||
if v.Name() == cyclableViews[i] {
|
||||
if viewName == cyclableViews[i] {
|
||||
focusedViewName = cyclableViews[i+1]
|
||||
break
|
||||
}
|
||||
@ -39,7 +49,7 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
||||
message := gui.Tr.TemplateLocalize(
|
||||
"IssntListOfViews",
|
||||
Teml{
|
||||
"name": v.Name(),
|
||||
"name": viewName,
|
||||
},
|
||||
)
|
||||
gui.Log.Info(message)
|
||||
@ -59,8 +69,13 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||
if v == nil || v.Name() == cyclableViews[0] {
|
||||
focusedViewName = cyclableViews[len(cyclableViews)-1]
|
||||
} else {
|
||||
// if we're in the commitFiles view we'll act like we're in the commits view
|
||||
viewName := v.Name()
|
||||
if viewName == "commitFiles" {
|
||||
viewName = "commits"
|
||||
}
|
||||
for i := range cyclableViews {
|
||||
if v.Name() == cyclableViews[i] {
|
||||
if viewName == cyclableViews[i] {
|
||||
focusedViewName = cyclableViews[i-1] // TODO: make this work properly
|
||||
break
|
||||
}
|
||||
@ -68,7 +83,7 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||
message := gui.Tr.TemplateLocalize(
|
||||
"IssntListOfViews",
|
||||
Teml{
|
||||
"name": v.Name(),
|
||||
"name": viewName,
|
||||
},
|
||||
)
|
||||
gui.Log.Info(message)
|
||||
@ -131,15 +146,10 @@ func (gui *Gui) returnFocus(g *gocui.Gui, v *gocui.View) error {
|
||||
// pass in oldView = nil if you don't want to be able to return to your old view
|
||||
// TODO: move some of this logic into our onFocusLost and onFocus hooks
|
||||
func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error {
|
||||
// we assume we'll never want to return focus to a confirmation panel i.e.
|
||||
// we should never stack confirmation panels
|
||||
if oldView != nil && oldView.Name() != "confirmation" {
|
||||
// second class panels should never have focus restored to them because
|
||||
// once they lose focus they are effectively 'destroyed'
|
||||
secondClassPanels := []string{"confirmation", "menu"}
|
||||
if !utils.IncludesString(secondClassPanels, oldView.Name()) {
|
||||
gui.State.PreviousView = oldView.Name()
|
||||
}
|
||||
// we assume we'll never want to return focus to a popup panel i.e.
|
||||
// we should never stack popup panels
|
||||
if oldView != nil && !gui.isPopupPanel(oldView.Name()) {
|
||||
gui.State.PreviousView = oldView.Name()
|
||||
}
|
||||
|
||||
gui.Log.Info("setting highlight to true for view" + newView.Name())
|
||||
@ -301,7 +311,7 @@ func (gui *Gui) currentViewName() string {
|
||||
|
||||
func (gui *Gui) resizeCurrentPopupPanel(g *gocui.Gui) error {
|
||||
v := g.CurrentView()
|
||||
if v.Name() == "commitMessage" || v.Name() == "credentials" || v.Name() == "confirmation" {
|
||||
if gui.isPopupPanel(v.Name()) {
|
||||
return gui.resizePopupPanel(g, v)
|
||||
}
|
||||
return nil
|
||||
@ -393,14 +403,10 @@ func (gui *Gui) handleFocusView(g *gocui.Gui, v *gocui.View) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (gui *Gui) popupPanelFocused() bool {
|
||||
viewNames := []string{"commitMessage",
|
||||
"credentials",
|
||||
"menu"}
|
||||
for _, viewName := range viewNames {
|
||||
if gui.currentViewName() == viewName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
func (gui *Gui) isPopupPanel(viewName string) bool {
|
||||
return viewName == "commitMessage" || viewName == "credentials" || viewName == "confirmation" || viewName == "menu"
|
||||
}
|
||||
|
||||
func (gui *Gui) popupPanelFocused() bool {
|
||||
return gui.isPopupPanel(gui.currentViewName())
|
||||
}
|
||||
|
@ -658,6 +658,15 @@ func addDutch(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "checkoutCommitFile",
|
||||
Other: "checkout file",
|
||||
}, &i18n.Message{
|
||||
ID: "discardOldFileChange",
|
||||
Other: "discard this commit's changes to this file",
|
||||
}, &i18n.Message{
|
||||
ID: "DiscardFileChangesTitle",
|
||||
Other: "Discard file changes",
|
||||
}, &i18n.Message{
|
||||
ID: "DiscardFileChangesPrompt",
|
||||
Other: "Are you sure you want to discard this commit's changes to this file? If this file was created in this commit, it will be deleted",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -681,6 +681,15 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "checkoutCommitFile",
|
||||
Other: "checkout file",
|
||||
}, &i18n.Message{
|
||||
ID: "discardOldFileChange",
|
||||
Other: "discard this commit's changes to this file",
|
||||
}, &i18n.Message{
|
||||
ID: "DiscardFileChangesTitle",
|
||||
Other: "Discard file changes",
|
||||
}, &i18n.Message{
|
||||
ID: "DiscardFileChangesPrompt",
|
||||
Other: "Are you sure you want to discard this commit's changes to this file? If this file was created in this commit, it will be deleted",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -641,6 +641,15 @@ func addPolish(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "checkoutCommitFile",
|
||||
Other: "checkout file",
|
||||
}, &i18n.Message{
|
||||
ID: "discardOldFileChange",
|
||||
Other: "discard this commit's changes to this file",
|
||||
}, &i18n.Message{
|
||||
ID: "DiscardFileChangesTitle",
|
||||
Other: "Discard file changes",
|
||||
}, &i18n.Message{
|
||||
ID: "DiscardFileChangesPrompt",
|
||||
Other: "Are you sure you want to discard this commit's changes to this file? If this file was created in this commit, it will be deleted",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user