Repository: jesseduffield/lazygit
File: pkg/gui/controllers/helpers/refs_helper.go (Go)

Code before:
			// note, this will only work for english-language git commands. If we force git to use english, and the error isn't this one, then the user will receive an english command they may not understand. I'm not sure what the best solution to this is. Running the command once in english and a second time in the native language is one option

			if options.OnRefNotFound != nil && strings.Contains(err.Error(), "did not match any file(s) known to git") {
				return options.OnRefNotFound(ref)
			}

			if IsSwitchBranchUncommitedChangesError(err) {
				// offer to autostash changes
				self.c.OnUIThread(func() error {
					// (Before showing the prompt, render again to remove the inline status)
					_ = self.c.Contexts().Branches.HandleRender()
					return self.c.Confirm(types.ConfirmOpts{
						Title:  self.c.Tr.AutoStashTitle,
						Prompt: self.c.Tr.AutoStashPrompt,
						HandleConfirm: func() error {
							return withCheckoutStatus(func(gocui.Task) error {
								if err := self.c.Git().Stash.Push(self.c.Tr.StashPrefix + ref); err != nil {
									return err
								}
								if err := self.c.Git().Branch.Checkout(ref, cmdOptions); err != nil {
									return err
								}
								popErr := self.c.Git().Stash.Pop(0)
								// Branch switch successful so re-render the UI even if the pop operation failed (e.g. conflict).
								if err := renderBranchSwitched(); err != nil {
									return err
								}
								return popErr
							})
						},
					})
				})
				return nil
			}

			return err
		}

		return renderBranchSwitched()
	})
}

// Shows a prompt to choose between creating a new branch or checking out a detached head
func (self *RefsHelper) CheckoutRemoteBranch(fullBranchName string, localBranchName string) error {
	checkout := func(branchName string) error {
		// Switch to the branches context _before_ starting to check out the
		// branch, so that we see the inline status
		if self.c.Context().Current() != self.c.Contexts().Branches {
			if err := self.c.Context().Push(self.c.Contexts().Branches); err != nil {
				return err
			}

Review comment (bug):
If both the pop and the refresh fail, then you are returning the error from refresh. I think it would be better to return the error from pop instead. One way to do that (with a pattern that I have used elsewhere) is
```
		popErr := self.c.Git().Stash.Pop(0)
		// Branch switch successful so refresh the UI even if the pop operation failed (e.g. conflict).
		refreshError := renderBranchSwitched()
		if popErr != nil {
			// An error from pop is the more important one to report to the user
			return popErr
		}
		return refreshError
```

Alternatively, we could have renderBranchSwitched not return an error, and swallow the return value of the refresh call inside, knowing that a refresh with `BLOCK_UI` [will always return nil](https://github.com/jesseduffield/lazygit/blob/05ae0800c3ff3fd7160a5705a8fbac7f50745624/pkg/gui/controllers/helpers/refresh_helper.go#L203). Thinking about this, I guess I would prefer that as it results in simpler code.

Code after:
			// note, this will only work for english-language git commands. If we force git to use english, and the error isn't this one, then the user will receive an english command they may not understand. I'm not sure what the best solution to this is. Running the command once in english and a second time in the native language is one option

			if options.OnRefNotFound != nil && strings.Contains(err.Error(), "did not match any file(s) known to git") {
				return options.OnRefNotFound(ref)
			}

			if IsSwitchBranchUncommitedChangesError(err) {
				// offer to autostash changes
				self.c.OnUIThread(func() error {
					// (Before showing the prompt, render again to remove the inline status)
					_ = self.c.Contexts().Branches.HandleRender()
					return self.c.Confirm(types.ConfirmOpts{
						Title:  self.c.Tr.AutoStashTitle,
						Prompt: self.c.Tr.AutoStashPrompt,
						HandleConfirm: func() error {
							return withCheckoutStatus(func(gocui.Task) error {
								if err := self.c.Git().Stash.Push(self.c.Tr.StashPrefix + ref); err != nil {
									return err
								}
								if err := self.c.Git().Branch.Checkout(ref, cmdOptions); err != nil {
									return err
								}
								err := self.c.Git().Stash.Pop(0)
								// Branch switch successful so re-render the UI even if the pop operation failed (e.g. conflict).
								refresh()
								return err
							})
						},
					})
				})
				return nil
			}

			return err
		}

		refresh()
		return nil
	})
}

// Shows a prompt to choose between creating a new branch or checking out a detached head
func (self *RefsHelper) CheckoutRemoteBranch(fullBranchName string, localBranchName string) error {
	checkout := func(branchName string) error {
		// Switch to the branches context _before_ starting to check out the
		// branch, so that we see the inline status
		if self.c.Context().Current() != self.c.Contexts().Branches {
			if err := self.c.Context().Push(self.c.Contexts().Branches); err != nil {
				return err
			}
		}