Skip to content

Conversation

bchadwic
Copy link
Contributor

@bchadwic bchadwic commented Dec 6, 2021

I got tired of modifying my git config -e to switch my base repo, so I made a command for personal use.

After looking to see if others had similar problems, I found a lot of issues revolving the base repo and its obscurities.

I'm opening this to hopefully help all the future and current users who:

  1. might be new and don't understand what the base repo does (the help section explains the base repo)
    Secret created in Upstream Repo instead of Current Repo #4688
    Unclear message about base repository when creating a PR #2090
  2. might accidentally pick the wrong base repo initially (like I did 🤦‍♂️)
    How to change base repo for gh pr? #2300
  3. might want a short hand to quickly swap what remote gh points to for commands (especially combined with aliases)
    Allow configured Git remotes to be used for the '-R' argument #1481 Sorta related
    gh "base repository" not worktree specific #1837
    Document which remote is used for :owner, :repo placeholders #2657 (comment) Good start to this functionality

I think with the amount of requests and the void in documentation about the base repo, something like this should be included in the tool.

It needs work and tests, but this is what it looks like in action:

$ gh config base --help
The base repository is used to determine which repository gh
should automatically query for the commands:
        issue, pr, browse, run, repo rename, secret, workflow


USAGE
  gh config base <git remote name> [flags]

FLAGS
  -v, --view   View the current configured default repository

...

$ gh config base -v
base repo has not been specified yet

$ gh config base
? Which should be the base repository (used for e.g. querying issues) for this directory? cli/cli

$ gh config base -v
upstream

$ gh config base origin

$ gh config base -v
origin

$ gh config base foo
could not find local remote name foo

@bchadwic bchadwic requested a review from a team as a code owner December 6, 2021 09:40
@bchadwic bchadwic requested review from samcoe and removed request for a team December 6, 2021 09:40
@cliAutomation cliAutomation added the external pull request originating outside of the CLI core team label Dec 6, 2021
@samcoe samcoe added the discuss Feature changes that require discussion primarily among the GitHub CLI team label Dec 10, 2021
@darcyclarke darcyclarke removed the discuss Feature changes that require discussion primarily among the GitHub CLI team label Jan 12, 2022
@samcoe
Copy link
Contributor

samcoe commented Jan 13, 2022

@bchadwic The team discussed this feature offline and we all agreed that it is a great idea. We came up with a proposed UX design for this as well. Let us know what you think.

// No argument interactive
gh repo default 
// This would display current default repo and prompt user if they would like to change it

// No argument non-interactive 
gh repo default
// This would just display current default repo

// Argument provided for both interactive and non-interactive
gh repo default some-repo
// This would set the default repo to some-repo
// If there is no matching git remote for some-repo then return error

// Run from outside of a git repo
gh repo default
// This would return an error

While the code refers to this feature as "base" repo we want to use "default" when displaying to the user as it has more meaning.

Additionally we thought it would be nice to have a --reset-default-repo flag for all commands that utilize the default repo functionality, i.e. any command that uses the SmartBaseRepoFunc. This flag would reset the default repo and then prompt the user to select a new default. This functionality is a bit more complex to add. To start I would suggest just working on adding the gh repo default command and we can go from there. How does that sound?

@bchadwic
Copy link
Contributor Author

bchadwic commented Jan 14, 2022

@samcoe Sounds great, I agree that gh repo default is much more sensible than gh config base.

Since dailying the command, I find I use gh config base -v (aliased as gh b -v) much like git branch. It's exclusively a quick way for me to see what I'm pointing to. Having gh repo default display then always prompt might become an annoyance for interactive users. Especially those who switch around a lot that just need a quick reminder where they're pointing (i.e. instead of always typing n + Enter).

After some thought, I'm ok with leaving out an exclusive view option if my concerns don't seem to be an issue. I only want to voice my experience with using this command before it gets officially implemented 👍

Let me know if that's the final design the team would like to go with, I'd be happy to do some work on this.

Also I like the idea of --reset-default-repo!

@bchadwic
Copy link
Contributor Author

bchadwic commented Jan 14, 2022

Also a view option could serve as a list of available remotes

Merely a suggestion...

// No argument interactive
gh repo default 
// This would prompt the user to select a remote

// No argument non-interactive 
gh repo default
remote name is required when not running interactively, use `--view` to see available remotes

// No argument interactive and non-interactive --view (similar to git branch except * = default)
gh repo default --view
  origin
* upstream

vvvvvvvvvvvvvvvvv
same as team's design

@samcoe
Copy link
Contributor

samcoe commented Jan 18, 2022

@bchadwic I like the idea of a dedicated flag that will skip the prompt and just display the current default since I can imagine many users just forgetting their default and wanting to see what it is. I am not sure --view is the right name for that flag but we can discuss that more once the implementation is done since it is just a name change.

bchadwic added a commit to bchadwic/gh-cli that referenced this pull request Jan 19, 2022
… is a working example of the teams design combined with cli#4859 (comment)
@mislav
Copy link
Contributor

mislav commented Jan 19, 2022

I have a suggestion for keeping this simpler. Literally the only design goals for this command right now are that it:

  1. Allows you to reset your previously chosen default;
  2. (nice-to-have) Shows the current result of the base repo resolution.

I would avoid adding much more functionality to this command; especially the kind that does different things in interactive and non-interactive modes. Primarily, I would avoid adding any kind of prompting behavior to the command, which would also alleviate the need for adding flags to disable the prompting behavior.

Here's how I imagine the command would work:

$ gh repo default
#=> "cli/cli"

$ gh repo default --reset

$ gh issue list
# (prompts you to select the new default)

@samcoe What do you think?

@bchadwic
Copy link
Contributor Author

bchadwic commented Jan 19, 2022

Would you still be able to pass in a remote name to set the default?

$ gh repo default origin

@samcoe
Copy link
Contributor

samcoe commented Jan 20, 2022

@mislav I can understand the desire to keep this simple, the reason I thought that this command should allow setting the default repo was to remove the responsibility of setting a default from other commands. In the example you listed the issue list command has a prompt for setting a new default, if we allow this command to set a default then issue list can simply error out and instruct the user to run gh repo default.

Having this one command be able to reset/set/list/etc is a lot of functionality which is why I proposed, offline in slack, introducing a new top level object of a remote, then we could have a set of commands to provide this functionality instead of just one nested under the repo object.

Overall, I don't have strong opinions here but I do anticipate users asking for the feature of being able to set the default through this command.

@mislav
Copy link
Contributor

mislav commented Jan 20, 2022

Would you still be able to pass in a remote name to set the default?

@bchadwic I personally can't see how that interface would add any value over the existing prompt that asks you to select the base repo.

Here's what currently happens if I clone bchadwic/cli and run gh issue list:

/tmp/bchadwic-cli [trunk] $ gh issue list
? Which should be the base repository (used for e.g. querying issues) for this directory?
> cli/cli
  bchadwic/cli

Note that there was only a single git remote "origin" pointing to bchadwic/cli, but the interactive prompt also includes its parent repository as an option, even if it isn't present as a git remote. How would I make the same choice using gh repo default <remote>?

Furthermore, it should be much more clear to the user when choosing from a prompt that lists repositories as owner/repo rather than having an interface that lets you choose between git remote names. Seeing gh repo default origin by itself contains little information unless you know exactly where "origin" points to.

@mislav
Copy link
Contributor

mislav commented Jan 20, 2022

In the example you listed the issue list command has a prompt for setting a new default, if we allow this command to set a default then issue list can simply error out and instruct the user to run gh repo default.

@samcoe Aah, gotcha! If the goal is that other commands will error out when there is ambiguity, then I agree that we should add more functionality to the new dedicated command. Then instead of --reset, I propose something like:

gh repo default --select
? Which should be the base repository (used for e.g. querying issues) for this directory?
> cli/cli
  bchadwic/cli

which is why I proposed, offline in slack, introducing a new top level object of a remote, then we could have a set of commands to provide this functionality instead of just one nested under the repo object.

That's a worthwhile consideration! I agree it would make slightly more sense if these commands were nested under remote rather than repo, since they're mostly about choosing a remote.

@bchadwic
Copy link
Contributor Author

bchadwic commented Jan 25, 2022

Ah I didn't do my due diligence; I thought that gh looked at the git config to resolve the base repo, my apologies @mislav

Given that this will be referred to by various commands, I think it now makes more sense for the new command to prompt the default without a flag. I say this to keep things intuitive for new users and to keep directions uniform given that this command will be similar to auth now.

For example, when you run gh pr create without an authentication you get a very intuitive:

To authenticate, please run 'gh auth login'.

Likewise when you run gh pr create without a repo specified you should get something uniform to auth like:

To select a default repo, please run 'gh repo default'.

Simple, and similar to what already exists:

// always prompts a new default
$ gh repo default
? Which should be the base repository (used for e.g. querying issues) for this directory?
> cli/cli
  bchadwic/cli

$ gh repo default --view
#=> "cli/cli"
or
#=> a repo has not been specified yet, run 'gh repo default' to select a default

I'm not attached to --view this was just a suggestion based off other command flags.

Also I'm unsure of what the message would be for non-interactive users.

@samcoe
Copy link
Contributor

samcoe commented Jan 26, 2022

@bchadwic I agree with the approach of interactive by default, it is the norm with other commands.

@bchadwic
Copy link
Contributor Author

bchadwic commented Feb 2, 2022

If the team likes the latest design mentioned then I can start revising my pr.

@samcoe if --view seems unintuitive, would --current be more appropriate diction to check the current default repo?

$ gh repo default --current
#=> "cli/cli"

@samcoe
Copy link
Contributor

samcoe commented Feb 2, 2022

@bchadwic The team is onboard with the direction you proposed. The main concerns we want to make sure are covered:

  • With the interactive by default option we must also provide a way to use the command non-interactively
  • In interactive mode if there is a default already chosen we want to indicate to the user which listed option it is, perhaps using Surveys default option mechanism
  • Lastly, if --view flag is used and a default is not set yet it should output to the user to run the command without the --view flag. We can start with --view flag name and reevaluate it at the end.

Let me know if you have any further questions about the direction!

@bchadwic
Copy link
Contributor Author

bchadwic commented Mar 2, 2022

@samcoe

Hey sorry for the delay, I'm picking this back up.

#1706

In non-interactive mode, the prompt is skipped and we default to the first git remote instead.

Does this still apply? Or is the remote strategy changing for non-interactive users with this new command?

@samcoe
Copy link
Contributor

samcoe commented Mar 2, 2022

@bchadwic Lets leave that behavior in place for now and address it in a follow up PR. In the future, in the scenario that there are two or more remotes and no default is selected we will want to error out and instruct the user to use this new command to set the default.

@bchadwic
Copy link
Contributor Author

bchadwic commented Apr 6, 2022

@samcoe , I finished what seems to be the functionality the team is after. I'm not sure if it's ready for a final review but if you have the time, a look over would be greatly appreciated 😃

A couple things to note:

  1. I haven't tested any of the additional functions in context.go because I'm not sure if extracting functions from context.BaseRepo() was the best solution. (Are there plans to make BaseRepo an interface? Like what Mislav is working on with git clients Extract concepts of local and remote git repos #4900)
  2. I also wasn't sure what to put in the help section other than what I might find helpful

Thank you!

samcoe pushed a commit to bchadwic/gh-cli that referenced this pull request Apr 20, 2022
@samcoe
Copy link
Contributor

samcoe commented Apr 20, 2022

@bchadwic We appreciate your hard work on this and patients on the follow through. In an effort to keep this from lingering on our side too long and wanting to see this shipped in the next release I went ahead and pushed a commit that does a couple things:

  1. Moves code you added to the context package into the default package so that it would be more self contained. The context package is a bit of a relic of the past and we refrain from adding to it whenever possible. Ideally, one day it will go away completely and its functionality will be replaced by a more appropriately named robust package.
  2. Adds tests for the default command. Although they are failing because I am using strings.Cut which was introduced in Go 1.18, I will fix that shortly.
  3. Added some polish and handling of edge cases that were not covered before. There is probably more to be done with the UX and documentation here so that usage of this command is clear.

@samcoe samcoe requested a review from mislav April 20, 2022 07:41
@bchadwic
Copy link
Contributor Author

Thank you @samcoe ! I think the hold up has been on my side so I appreciate you doing the heavy lifting. I'll look through the code later to see how I could improve for next time 👍

@vilmibm
Copy link
Contributor

vilmibm commented Aug 22, 2022

my TODO:

  • merge trunk
  • better name?
  • evaluate UX

@vilmibm
Copy link
Contributor

vilmibm commented Dec 13, 2022

@samcoe @mislav

I have updated this PR with some tweaked UX that could use a quick review.

When there is only one possibility for base repository's value:

cli> ghd repo default
Found only one known remote repo, cli/cli on github.com.
(hint: for gh to see more remote repositories, add them with `git remote`)

✓ Set cli/cli as the default repository for the current directory

When there are multiple possibilities:

cackle> ghd repo default
gh uses the default repository for things like:

 - viewing, creating, and setting the default base for  pull requests
 - viewing and creating issues
 - viewing and creating releases
 - working with Actions
 - adding secrets

(hint: for gh to see more remote repositories, add them with `git remote`)

? Which repository should be the default?  [Use arrows to move, type to filter]
  evilmibm/cackle

It's possible my mini-explainer should be in a help topic instead but I felt this was succint enough to leave in the command.

I've also opened up the follow-up issue, #6729 , which I'll do once this is merged.

Copy link
Contributor

@samcoe samcoe left a comment

Choose a reason for hiding this comment

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

Left two small comments, otherwise everything looks good to me pending the offline slack discussion around wording. We may still need to add a help topic for this feature in the future but I think that is something we can wait for user feedback on. Thanks for pushing this to the finish line! I am excited for this long standing PR to finally get merged!

Copy link
Contributor

@mislav mislav left a comment

Choose a reason for hiding this comment

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

This looks great; thank you for picking this back up.

I like the added help blurb!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external pull request originating outside of the CLI core team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants