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

Left panel - show inactive remotes #6015

Closed
RussKie opened this issue Dec 30, 2018 · 36 comments
Closed

Left panel - show inactive remotes #6015

RussKie opened this issue Dec 30, 2018 · 36 comments
Assignees
Milestone

Comments

@RussKie
Copy link
Member

RussKie commented Dec 30, 2018

Do you want to request a feature or report a bug?

feature

What is the current behavior?

The left panel displays the currently configured remotes.
GE has a feature that allows to disable a remote but keep the information available to the app.
image

What is the expected behavior?

Display disabled remotes in the tree, if any.
The node that contains the inactive remotes should be collapsed by default.

It could look like:

+ Branches
- Remotes (active)
  |- upstream
  |- fork
- Remotes (inactive)
  |- john
  |- jim
  |- jack

or

+ Branches
- Remotes
  |- active
  |  |- upstream
  |  |- fork
  |- inactive
  |  |- john
  |  |- jim
  |  |- jack

A context menu should allow to

  • enable an inactive remote,
  • disable an active remote
@RussKie RussKie added type: feature request area: user experience up-for-grabs Easy tasks for those looking to get involved. Refer to https://up-for-grabs.net/ 🤓 good first issue area: left-panel Issues related to the Left Panel labels Dec 30, 2018
@gerhardol
Copy link
Member

Useful for repo maintainers, but if this decreases the hurdle also for occasional developers to try out feature branches, much is gained.

An inactive remote can probably not list any branches. Should double click activate? Should double click of normal remotes deactivate then? If so should handling be as @amaiorano proposed for submodules?

The alternative to tabs is to be able to reorder in the left panel and keep the expansion state. For instance, I want submodules on the top.

Remotes should probably be on the same level as Branches (I would prefer to have inactive separate myself but have no good motivation).

@vbjay
Copy link
Contributor

vbjay commented Dec 30, 2018

I wouldn't want double click to alter the active/inactive state of my remote. That would drive me BONKERS. Instead, open remote dialog with that remote selected.

Instead of separate nodes, Use different icons and maybe a tooltip to say active/inactive.

@amaiorano
Copy link
Contributor

I didn't even know about this feature. Are disabled remotes a Git feature, or a GE feature?

In any case, given the current implementation, it would be easier to implement as:

- Remotes
  |- active
  |  |- upstream
  |  |- fork
  |- inactive
  |  |- john
  |  |- jim
  |  |- jack

Another option would be to not bother with "active", and have only the "inactive" parent node, so like:

- Remotes
  |- upstream
  |- fork
  |- inactive
  |  |- john
  |  |- jim
  |  |- jack

And as you said, in all cases, inactive would begin collapsed.

@amaiorano
Copy link
Contributor

I wouldn't want double click to alter the active/inactive state of my remote. That would drive me BONKERS. Instead, open remote dialog with that remote selected.

Yes, I recommend that double-click open a dialog that asks if you want to activate an inactive one. This would be the same behaviour as right-clicking and selecting "Activate", which should be the first context menu action. This would mimic the existing double-click behavior on other nodes; e.g. double-click a branch or right-click "checkout" both result in a check out branch dialog.

@gerhardol
Copy link
Member

I didn't even know about this feature. Are disabled remotes a Git feature, or a GE feature?

Really GE, inactive remotes are hidden in .git/config so Git do not care about them
So if I do not want to see your changes and deactivating them, I have a section like:

[-remote "amaiorano"]
        url = git://github.com/amaiorano/gitextensions.git
        fetch = +refs/heads/*:refs/remotes/amaiorano/*

Another option would be to not bother with "active", and have only the "inactive" parent node, so like:

Better

@vbjay
Copy link
Contributor

vbjay commented Dec 30, 2018

Yes, I recommend that double-click open a dialog that asks if you want to activate an inactive one

No Not asking the user if they want to change the state. Show the remote dialog.

image

If I double click on your remote I have ( following left panel ROT work) I would expect the dialog to show letting me manage the remote including disabling it. If i double clicked upstream, then upstream would be selected.

I highlighted the button that disables/enables a remote.

@RussKie
Copy link
Member Author

RussKie commented Dec 30, 2018

Useful for repo maintainers, but if this decreases the hurdle also for occasional developers to try out feature branches, much is gained.

I use this feature in many repos, as a team lead I need to check other devs' work.

I didn't even know about this feature. Are disabled remotes a Git feature, or a GE feature?

It is a GE-specific feature (#3615).

I wouldn't want double click to alter the active/inactive state of my remote. That would drive me BONKERS. Instead, open remote dialog with that remote selected.

Agree, I wouldn't like it either. Personally I would like to have the following options:

  • Manage remotes... (default, double click)
  • Activate the remote (if inactive)
  • Activate the remote and fetch (if inactive)
  • Deactivate the remote (if active)

@amaiorano
Copy link
Contributor

So I started looking into this, and trying out the disable/enable remotes feature, and the first thing I noticed is that removing a remote has the side effect of also removing all of its refs (.git/refs/remotes/<remote_name> is gone), but enabling it again does not fetch refs from the remote. As a result, after disable/enable, you cannot perform any actions on the remote until you've fetched from it (e.g. you can't check out a branch in the checkout pulldown, etc.).

Should I try to fix that? If we don't auto-fetch enabled remote refs, then after enabling a remote, you'd have to remember to fetch it for it to appear in the left panel.

@gerhardol
Copy link
Member

Should I try to fix that?

Leave it for now in this issue.
If you believe you have a solution, please discuss it.

@RussKie
Copy link
Member Author

RussKie commented Dec 31, 2018 via email

@amaiorano
Copy link
Contributor

Okay, I'll look into it some more. Having the left panel list remotes without branches isnt currently supported, so that's what needs to be added. Then we can provide the context actions you want, @RussKie. Also note that we'd want to show active remotes with no branches as well, and allow fetching on them. Should be doable.

@RussKie
Copy link
Member Author

RussKie commented Jan 1, 2019

Worth noting, that I often enable/disable remotes in batches (e.g. reviewing several PRs from different contributors), so in my case I need both "activate" and "activate+fetch" options.

@amaiorano
Copy link
Contributor

As I continue exploring, it looks like GitModule.GetRefs has a bug in it. If you pass in "tags: false, branches: true" to only retrieve branches, it will not return remote branches, only local ones. However, if you pass in "tags: true, branches: true", you'll get local and remote branches (and tags). It boils down to the fact that it uses different ways to get the refs:

        public IReadOnlyList<IGitRef> GetRefs(bool tags = true, bool branches = true)
        {
            var refList = GetRefList();

            return ParseRefs(refList);

            string GetRefList()
            {
                if (tags && branches)
                {
                    return _gitExecutable.GetOutput("show-ref --dereference");
                }

                if (tags)
                {
                    return _gitExecutable.GetOutput("show-ref --tags");
                }

                if (branches)
                {
                    return _gitExecutable.GetOutput(@"for-each-ref --sort=-committerdate refs/heads/ --format=""%(objectname) %(refname)""");
                }

                return "";
            }
        }

When only branches is wanted, the function uses for-each-ref but specifies only the "refs/heads/" path, so we don't get the refs from "refs/remotes/". This is surprising, and should be fixed, but there are a few calls to this function that pass in "tags: false, branches: true" that we need to make sure work as expected. Or perhaps we need to extent the API to accept another bool parameter "remotes".

@gerhardol
Copy link
Member

Check master for update GetRefs), changed just recently
But remotes: should be added too, it seems. (Maybe using a Mode as in #6002)

@RussKie
Copy link
Member Author

RussKie commented Jan 1, 2019

it looks like GitModule.GetRefs has a bug in it

Please open a new issue so we can track it separately.

@amaiorano amaiorano self-assigned this Jan 5, 2019
@amaiorano
Copy link
Contributor

amaiorano commented Jan 5, 2019

Screenshot time! Here's the current progress:

Enabled remotes without branches, as well as disabled remotes are now displayed:

Initially "Disabled" is collapsed:
image

If you expand it:
image

One thing to note, "fsharp" has no children. It is a remote with no fetched branches (yet). EDIT: Also note that it's not positioned alphabetically -- normally it would be in between "amaiorano" and "origin". I will fix that soon. Fixed.

Right-clicking an enabled remote:

image

Right-clicking a disabled remote:

image

I'm not sure what to do about icons. I can probably find something for Enable and Disable, but I'm not quite sure what to use for "Enable and fetch".

Performing "Enable", "Enable and fetch", and "Disable" all work as expected. Enable/Disable will refresh the UI. Enable and fetch shows the fetch dialog, and then the UI is refreshed. Works really well!

@amaiorano
Copy link
Contributor

If you want to try my changes, check out the branch on my fork:
https://github.com/amaiorano/gitextensions/tree/amaiorano/left-panel-remotes-improvements

@RussKie
Copy link
Member Author

RussKie commented Jan 5, 2019

Good stuff!

I suggest using the same terminology as we use in the Remotes dialog: "Activate" and "Deactivate" (or change the dialog to match the left panel).
Instead of "Disabled" - perhaps "Inactive"?
I also suggest use the same icons for the context menu as used in the dialog.
I don't particularly mind which way we chose to go as long as we are consistent.

As an observation - I think we need to rename "Manage remotes" to "Manage remotes..." to indicate this command opens a dialog

@RussKie RussKie removed 🤓 good first issue up-for-grabs Easy tasks for those looking to get involved. Refer to https://up-for-grabs.net/ labels Jan 5, 2019
@RussKie RussKie added this to the 3.1.0 milestone Jan 5, 2019
@RussKie
Copy link
Member Author

RussKie commented Jan 5, 2019

Looks pretty cool, though inactive remotes aren't sorted:
image

We could probably enhance the UX - when choosing to manage a remote, the dialog should pre-select the chosen remote

@amaiorano
Copy link
Contributor

amaiorano commented Jan 5, 2019

I suggest using the same terminology as we use in the Remotes dialog: "Activate" and "Deactivate" (or change the dialog to match the left panel). Instead of "Disabled" - perhaps "Inactive"?

Done. In code, it's "enable/disable", but for the UI, it's "active/inactive". Decided to just remain consistent.

I also suggest use the same icons for the context menu as used in the dialog. I don't particularly mind which way we chose to go as long as we are consistent.

Done, though I don't have a special icon for "Activate and fetch", so current using the eye open icon for both:

image

Would probably need an eye open icon with the blue down arrow that we use for fetch.

As an observation - I think we need to rename "Manage remotes" to "Manage remotes..." to indicate this command opens a dialog

Yep, had noticed that too. Fixed as well.

Branch has been updated if you want to try it now.

EDIT:

We could probably enhance the UX - when choosing to manage a remote, the dialog should pre-select the chosen remote

This is already how it works, it seems.

@RussKie
Copy link
Member Author

RussKie commented Jan 6, 2019

Tried it - very cool! Digging it.

I tried combining the eye and the arrow:
image

Not entirely happy with the result. Perhaps this item can remain icon-less...

@amaiorano
Copy link
Contributor

Can you tell me how to add icons in GE? I'll give it a shot as well.

@RussKie
Copy link
Member Author

RussKie commented Jan 6, 2019 via email

@RussKie
Copy link
Member Author

RussKie commented Jan 6, 2019

Please have a look at 4176d05 as an example, that's pretty much the extent of changes when adding or modifying an image

@RussKie
Copy link
Member Author

RussKie commented Jan 6, 2019

Found an annoyance: whenever deactivating or activating a remote the graph refreshes and the "Remotes/Inactive" node folds.
Is it difficult to retain the state across refreshes?

@amaiorano
Copy link
Contributor

Is it difficult to retain the state across refreshes?

I can easily special case it for the Inactive folder. Ideally, though, we'd remember the expanded state of the entire tree and attempt to reapply it. Need to think about the best way to do that. I want to wait, though, until my left panel pubsub change is merged, as it will affect how we approach this. But in the meantime, I'll special case this one.

@amaiorano
Copy link
Contributor

Please have a look at 4176d05 as an example, that's pretty much the extent of changes when adding or modifying an image

Thanks!

@amaiorano
Copy link
Contributor

amaiorano commented Jan 6, 2019

I pushed a couple of commits. First, I added an icon for RemoteEnableAndFetch:

image

The other commit somewhat addresses remembering the Inactive node expanded state. I'll explain what I mean. I didn't add any special code yet; instead, I rely on a side-effect of RepoObjectsTree.Nodes.FillTreeViewNode, a function that attempts to recycle existing TreeViewNode instances when rebuilding the structure after the "Node" structure has changed (Node is the base class for node types, and a TreeViewNode instance is created for each, with its "Tag" member set to the Node instance it matches). When this function recycles a TreeViewNode, the expanded state of that node is "remembered".

If you look at the FillTreeViewNode code, it's robust against insertion of new nodes, but if a node is removed, it won't recycle nodes properly. This can and should be fixed to at least improve node recycling, but I don't think we can rely on node recycling to always correctly remember expanded/collapsed state. I think this side effect was accidental, and wasn't really noticed because the Branches tree specifically expands to the currently active branch.

So right now, if you activate an inactive remote, it will "remember" the expanded state; but when you deactive a remote, it won't and the "Inactive" node will be collapsed. I'll think some more about this, and see what I can do.

@RussKie
Copy link
Member Author

RussKie commented Jan 6, 2019 via email

@amaiorano
Copy link
Contributor

Your icon looks way better than mine 👍

Thanks :) Have a little photoshopping experience thanks to my game dev background ;)

@amaiorano
Copy link
Contributor

amaiorano commented Jan 7, 2019

Okay, I just pushed a commit that adds the ability for the left panel to remember and re-apply the expanded state of nodes. This change is generic, and not really required for this specific change (show inactive remotes and remotes without branches). If you want, I can split this out into its own PR. Let me know. If you want to see the commit: amaiorano@e18b7d9

Edit: The only thing left to do is double-click to open the Remotes dialog. Since Remote nodes can have children, we have the same issue as I have with my submodules ROT work (this was mentioned above). I you want, I can use the same solution I already implemented for submodules here right away (double-click no longer expands inner nodes); or we can wait until my submodules work is merged to later add double-click to open on remotes. Let me know!

@gerhardol
Copy link
Member

or we can wait until my submodules work is merged to later add double-click to open on remotes. Let me know!

Most important is that it is consistent, I suggest you make a choice (it is likely the initial implementation that sticks).

@amaiorano
Copy link
Contributor

amaiorano commented Jan 8, 2019

Most important is that it is consistent, I suggest you make a choice (it is likely the initial implementation that sticks).

Okay, I'm going to bring in the change to disable expand/collapse on double-clicking nodes in the left panel. This will apply to all nodes. This will only apply to nodes that don't have special double-click behaviour.

@amaiorano
Copy link
Contributor

Okay, latest version on my fork now has double-click to open Remotes dialog, along with the change to disable expand/collapse on any inner node that overrides OnDoubleClick (like Visual Studio does in Solution Explorer).

@RussKie can you test out this latest version and let me know if it fits the bill? I've implemented pretty much everything mentioned on this thread. If you're happy with it, I'll clean up the commits and open a PR.

@RussKie
Copy link
Member Author

RussKie commented Jan 8, 2019

Love it!

@amaiorano
Copy link
Contributor

Love it!

Great! Will create PR soon.

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

No branches or pull requests

4 participants