Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user to select remote and branch when creating a PR #1889

Merged

Conversation

moha-gh
Copy link
Contributor

@moha-gh moha-gh commented Apr 22, 2022

When creating a PR against a selected branch (via O = "create pull request
options"), the user will first be asked to select a remote (if there is more
than one). After that, the suggestion area is populated with all remote branches
at that origin - instead of all local ones. After all, creating a PR against a
branch that doesn't exist on the remote won't work.

Please note that for the "PR is not filed against 'origin' remote" use case
(e.g. when contributing via a fork that is 'origin' to a GitHub project that is
'upstream'), the opened URL will not be correct. This is not a regression and
will be fixed in an upcoming PR.

Fixes #1826.

Copy link
Contributor Author

@moha-gh moha-gh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jesseduffield: Would be great if you could have a look, I need a few pointers to continue here :)

pkg/gui/controllers/helpers/suggestions_helper.go Outdated Show resolved Hide resolved
pkg/gui/controllers/helpers/suggestions_helper.go Outdated Show resolved Hide resolved
@@ -375,7 +375,7 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
OnPress: func() error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that when using the "against selected branch" option for a GitHub fork, GitHub won't automatically open the PR against the upstream. But that has nothing to do with my change (same behaviour on current master). Might be worth an additional look.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm not sure how best to address that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had another look at this: Apparently, to create a PR against a different remote (mainly the upstream I'd guess) the URL would need to look different.

Instead of something like

https://github.com/moha-gh/lazygit/compare/master...mh%2Fpr-suggest-remote-branches-only?expand=1

one would need to use

https://github.com/jesseduffield/lazygit/compare/master...moha-gh:lazygit:mh/pr-suggest-remote-branches-only?expand=1

That means the "repo URL" of the target remote (https://github.com/jesseduffield/lazygit/ instead of https://github.com/moha-gh/lazygit) is used and the full name of the source repo is prepended to the remote branch branch (with / replaced by :).

To handle this correctly, the createPullRequest() would need to be extended I think - so one can pass target and source remote as well, allowing the function to build the URL correctly.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me. I'm happy for that to be handled as a separate pull request (given that it's currently broken on master). As you say, it'll require updating HostHelper.GetPullRequestURL to take extra arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, then let's fix this separately 👍

Copy link
Owner

@jesseduffield jesseduffield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, left some feedback.

One thing I wonder is, would it make more sense to first choose a remote and then choose the branch, rather than select from branches across all remotes?

pkg/gui/controllers/helpers/suggestions_helper.go Outdated Show resolved Hide resolved
pkg/gui/controllers/helpers/suggestions_helper.go Outdated Show resolved Hide resolved
@@ -375,7 +375,7 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
OnPress: func() error {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm not sure how best to address that

@@ -375,7 +375,7 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
OnPress: func() error {
return self.c.Prompt(types.PromptOpts{
Title: branch.Name + " →",
FindSuggestionsFunc: self.helpers.Suggestions.GetBranchNameSuggestionsFunc(),
FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteBranchesWithoutRemotePrefixSuggestionsFunc(),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got no problem with long names

@moha-gh
Copy link
Contributor Author

moha-gh commented May 25, 2022

One thing I wonder is, would it make more sense to first choose a remote and then choose the branch, rather than select from branches across all remotes?

Definitely. I'm pretty busy right now, but hope to find some time in the next one or two weeks to incorporate the feedback and update the PR :)

@moha-gh moha-gh force-pushed the mh/pr-suggest-remote-branches-only branch from 8e00faa to 5310d37 Compare June 18, 2022 14:53
FindSuggestionsFunc: self.helpers.Suggestions.GetBranchNameSuggestionsFunc(),
HandleConfirm: func(targetBranchName string) error {
return self.createPullRequest(branch.Name, targetBranchName)
Title: "Select Target Remote",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make this translatable when finalizing the PR.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you do, be sure to use Sentence case

Comment on lines 158 to 167
for _, remote := range self.model.Remotes {
if remote.Name == remoteName {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an easier/nicer way to find the matching remote?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moha-gh you could use lo.Find (I think that's what it's called). Can't recall if it's actually less verbose all things considered

@moha-gh
Copy link
Contributor Author

moha-gh commented Jun 18, 2022

One thing I wonder is, would it make more sense to first choose a remote and then choose the branch, rather than select from branches across all remotes?

Definitely. I'm pretty busy right now, but hope to find some time in the next one or two weeks to incorporate the feedback and update the PR :)

@jesseduffield - That took a bit longer than expected :( I've changed the implementation to match the discussed approach (Select origin first, branch from that origin second). If there is only a single remote, the first step is skipped automatically. Could you have another look at the changes to see whether that's going in the right direction? If so, I'd clean up the PR for a final review.

@jesseduffield
Copy link
Owner

Sorry for the late re-review @moha-gh , I'm happy with the direction you've taken. Let me know when it's ready for another pass

@moha-gh
Copy link
Contributor Author

moha-gh commented Sep 27, 2022

@jesseduffield : Thanks, no worries. I'll try to get the PR rebased and cleaned up soon'ish :)

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2023

Uffizzi Ephemeral Environment deployment-19547

☁️ https://app.uffizzi.com/github.com/jesseduffield/lazygit/pull/1889

📄 View Application Logs etc.

What is Uffizzi? Learn more!

@jesseduffield
Copy link
Owner

@moha-gh this is still a draft PR. Did you intend to return to this?

@moha-gh
Copy link
Contributor Author

moha-gh commented Nov 11, 2024

@jesseduffield : The issue has been bugging me again lately, so yes, I'd like to give this another try. I'll see whether I come round to it in the next two weeks.

@moha-gh moha-gh force-pushed the mh/pr-suggest-remote-branches-only branch from c6f4f80 to dede117 Compare November 15, 2024 10:13
@moha-gh
Copy link
Contributor Author

moha-gh commented Nov 15, 2024

@jesseduffield : I've rebased the PR and tried to adapt it to the various changes that happened since the last update. Could you have another look, especially re. the error handling (not sure whether I modified that correctly, now that some functions don't return errors anymore).

What still remains is the issue that (at least for GitHub) creating a PR from a fork against a upstream repo still doesn't work correctly. I left a comment in the discussion here in the PR. I'd be nice to get this fixed as well - since that was one of the main motivations for starting to work on this PR :)

Copy link
Owner

@jesseduffield jesseduffield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

Comment on lines 158 to 167
for _, remote := range self.model.Remotes {
if remote.Name == remoteName {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@moha-gh you could use lo.Find (I think that's what it's called). Can't recall if it's actually less verbose all things considered

@@ -162,10 +162,38 @@ func (self *SuggestionsHelper) getRemoteBranchNames(separator string) []string {
})
}

func (self *SuggestionsHelper) getRemoteBranchNamesForRemote(remoteName string) []string {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the functions here that are not being called from anywhere.

@@ -764,6 +777,19 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
return self.c.Menu(types.CreateMenuOptions{Title: fmt.Sprint(self.c.Tr.CreatePullRequestOptions), Items: menuItems})
}

func (self *BranchesController) promptForTargetBranchNameAndCreatePullRequest(fromBranch *models.Branch, toRemote string) error {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an error can't be returned from this function then let's just remove the error return from the function signature

FindSuggestionsFunc: self.helpers.Suggestions.GetBranchNameSuggestionsFunc(),
HandleConfirm: func(targetBranchName string) error {
return self.createPullRequest(branch.Name, targetBranchName)
Title: "Select Target Remote",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you do, be sure to use Sentence case

@@ -375,7 +375,7 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
OnPress: func() error {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense to me. I'm happy for that to be handled as a separate pull request (given that it's currently broken on master). As you say, it'll require updating HostHelper.GetPullRequestURL to take extra arguments.

@@ -728,13 +728,26 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
},
},
{
// TODO: Replace with "Select remote and branch"?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the current label is fine

@moha-gh moha-gh force-pushed the mh/pr-suggest-remote-branches-only branch 3 times, most recently from c6096cc to d758517 Compare November 19, 2024 10:32
@moha-gh
Copy link
Contributor Author

moha-gh commented Nov 19, 2024

@jesseduffield : Updated the PR to (hopefully) take all review comments into account. Also added error handling for the "user enters an invalid remote name" case. Previously, that would have resulted in an empty selection box for the branch name.

Copy link
Owner

@jesseduffield jesseduffield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, just one thing on syntax.

It would be good to have an integration test as well. Giving a rough sketch, it would look something like this:

var OpenPullRequestNoUpstream = NewIntegrationTest(NewIntegrationTestArgs{
	Description:  "Open up a pull request, specifying an origin",
	ExtraCmdArgs: []string{},
	Skip:         false,
	SetupConfig: func(config *config.AppConfig) {
		config.GetUserConfig().OS.OpenLink = "echo {{link}} > /tmp/openlink"
	},
	SetupRepo: func(shell *Shell) {
		shell.NewBranch("branch-1")
		shell.NewBranch("branch-2")

		// Create a couple remotes
		shell.CloneIntoRemote("origin")
		shell.CloneIntoRemote("upstream")

		shell.RunCommand([]string{"git", "remote", "set-url", "origin", "https://github.com/jesseduffield/lazygit"})
		shell.RunCommand([]string{"git", "remote", "set-url", "upstream", "https://github.com/jesseduffield/other_repo"})
	},
	Run: func(t *TestDriver, keys config.KeybindingConfig) {
		// Open a PR for the current branch
		// Verify that we're prompted to enter the remote
		// Select a remote and ensure that the expected URL is used (by checking the openlink file)
	},
})

Let me know if you need any pointers

@@ -764,6 +776,28 @@ func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Bra
return self.c.Menu(types.CreateMenuOptions{Title: fmt.Sprint(self.c.Tr.CreatePullRequestOptions), Items: menuItems})
}

func (self *BranchesController) promptForTargetBranchNameAndCreatePullRequest(fromBranch *models.Branch, toRemote string) error {
_, ok := lo.Find(self.c.Model().Remotes, func(remote *models.Remote) bool {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to use lo.NoneBy here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, thanks for the hint.

@moha-gh moha-gh force-pushed the mh/pr-suggest-remote-branches-only branch 2 times, most recently from 85f674c to e0934db Compare November 20, 2024 08:19
@moha-gh
Copy link
Contributor Author

moha-gh commented Nov 20, 2024

@jesseduffield : Thanks for the test template. Used it to create one test where the entered name of the remote is invalid (and thus, an error should be shown). The other one mimics the successful creation of a PR. One thing I'm not sure about is how to properly validate the link. Opening the file in Go (and not via shell commands) and checking it's contents? Do you have an idea there?

@jesseduffield
Copy link
Owner

@moha-gh you could just navigate to the newly created file in the files view and assert the contents of the main view upon doing so. Alternatively you could add a method to the shell struct called AssertFileContents(path, expectedContents) that fails if the contents aren't as expected.

@stefanhaller
Copy link
Collaborator

Alternatively you could add a method to the shell struct called AssertFileContents(path, expectedContents) that fails if the contents aren't as expected.

We already have the FileContent function that we use exactly for this purpose, e.g. here.

@moha-gh moha-gh force-pushed the mh/pr-suggest-remote-branches-only branch from e0934db to fee001e Compare November 21, 2024 14:03
@moha-gh moha-gh changed the title [WIP] pkg/gui: Only suggest remote branches when creating a PR against a selected branch pkg/gui: Allow user to select remote and branch when creating a PR Nov 21, 2024
@moha-gh moha-gh marked this pull request as ready for review November 21, 2024 14:38
@moha-gh
Copy link
Contributor Author

moha-gh commented Nov 21, 2024

@stefanhaller , @jesseduffield : Great, thanks for the pointers! I've finalized the test case and marked the PR as ready :)

When creating a PR against a selected branch (via O = "create pull request
options"), the user will first be asked to select a remote (if there is more
than one). After that, the suggestion area is populated with all remote branches
at that origin - instead of all local ones. After all, creating a PR against a
branch that doesn't exist on the remote won't work.

Please note that for the "PR is not filed against 'origin' remote" use case
(e.g. when contributing via a fork that is 'origin' to a GitHub project that is
'upstream'), the opened URL will not be correct. This is not a regression and
will be fixed in an upcoming PR.

Fixes jesseduffield#1826.
@jesseduffield jesseduffield added the enhancement New feature or request label Nov 23, 2024
@jesseduffield jesseduffield changed the title pkg/gui: Allow user to select remote and branch when creating a PR Allow user to select remote and branch when creating a PR Nov 23, 2024
@jesseduffield jesseduffield force-pushed the mh/pr-suggest-remote-branches-only branch from fee001e to 949e131 Compare November 23, 2024 00:53
Copy link
Owner

@jesseduffield jesseduffield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, great work. I'll merge once these tests pass

@jesseduffield jesseduffield merged commit c3cf48c into jesseduffield:master Nov 23, 2024
16 checks passed
@moha-gh moha-gh deleted the mh/pr-suggest-remote-branches-only branch November 25, 2024 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Only remote branches should be suggested when creating a PR against selected branch
4 participants