-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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 to switch branches in Commit View (#4115) #4117
Allow to switch branches in Commit View (#4115) #4117
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great start. Did you say you had to learn go for this? That must have been an understatement. :)
A few thoughts on the UX:
- In the menu, the option to check out a detached head needs to come first. I do realize that this is probably not going to be the most common choice, but for the muscle memory of existing users it is important that
space, enter
still does the same thing as before. - Instead of just showing the raw hash, I'd probably say something like "detached head at selected commit", or "detached head at fa1afe1" (use short hash)
- For menus we prefer UIs that don't change based on context; we prefer to always show all potentially available options, and strike out the ones that are not applicable (see the "delete branch" menu for a good example). In this case this means that we should always show the menu; when there are no branches at the selected commit, the second menu entry could say "branch at selected commit", with a DisabledReason explaining that there is none.
- I always find it useful to have keybindings for menu entries. We could use
d
for detached head; it's less obvious what to use for branches since they are dynamic, but we could assign1
,2
and so on (stopping at9
when there are more branches, which should be unlikely in practice...)
Other remarks:
- An integration test would be nice. I haven't checked yet whether there's an existing test for checking out a commit that could be extended.
- Can we please say "they" instead of "he" when talking about users in the commit message? :)
765b6bd
to
818515a
Compare
Thanks, but those were actually my first lines of Go code I wrote. But it's not my first programming language, I have to admit. ;)
Even it is not as convenient for me, I understand, that we do not want to break with the users habits, so I implement it as you requested. My question is: do you think, we could add a configuration option, which would give the user the choice, what comes first? So we can keep the current behavior as default, but guys like me can just configure the application to let branches come first in this menu?
I understand, that this makes sense in a lot of context, but because there is an option, which is always available (detached head) and depending on the number of branches (or in future even tags) a variable number of other options, I am not sure, if a striked out "default" option is really helpful. If we combine that with the configuration option I just described, it would be inconvenient, because it would force me to manually select the only available option, even when there is no other sensible option.
Agreed, I will see, that I add this to the implementation.
Absolutely, as we just saw, that would have helped me to detect the mistake I made by choosing the wrong checkout method, and which I oversaw on manual testing (but I have to admit, that I rushed a bit for fast feedback 😅 ).
Of course. Actually I was careful about this in my feature request, but when typing the commit message my german brain subconsciously sneaked in a "generic maskulinum". 😉 |
Hm ok, if you feel so strongly about the detached head option not being the default one, then I should reconsider whether my suggestion is important enough. In general, muscle memory is an important consideration for lazygit, but maybe in this case it's not so much of a deal that it should outweigh the drawbacks. I don't think a configuration option is justified for something like this. Also, personally I very rarely check out a commit as a detached head; most of the time when I want to check out a commit (e.g. in order to test whether it cleanly builds) I just press Another reason why I thought the detached head should come first is for consistency with checking out a remote branch, or checking out a branch by name ( So, enough reasons to put the local branch(es) first, so let's keep that the way you have it in your branch now. For the other issue though, I feel rather strongly about it: I find it confusing if a keybindings sometimes shows a confirmation and other times a menu, depending on context. And I wonder how much of a problem it is that you have to type Also, we have precedence for this kind of thing: if you press |
I'm torn about what to show first: even if in this case users are more likely to want to switch to the branch than the commit, the intention is to roll this pattern out for more actions (drop, etc) and if we do that, we should be consistent in the ordering across those actions. I very much want to preserve the muscle memory for dropping commits, and so I think we should just always have the commit as the first option in the menu. Worth mentioning some alternative approaches before we commit to this one:
Option 2 sounds especially appealing to me as it means we get all the branch options for free without needing to maintain a separate way of interacting with branches, and it's easy to get back to the commits view with a single keypress if you misclicked. |
8fb839e
to
67c4eb4
Compare
I understand that and with shortcuts I'm actually agnostic about what comes first. Pushed my current implementation as suggested by @stefanhaller, but with the detached option first.
Actually this was what I tried to describe here with Option2. The What I like about the first approach: The command is named "checkout" and having all checkout options discoverable behind this command would match the expectation of most users (especially non-git-experts). Checking out a commit in detached head mode, when branches are available at this very commit is probably a very rare use case. I actually never had the desire to do so and I'm using Git for about 15 years now. The advantage of the second option would be, that we wouldn't need to overload existing commands with different semantics (dropping a commit is something different than deleting a branch). How about having both? Enhancing checkout as I already did (with improvements and polishing as you guys suggest) and having a dedicated branch operation menu for everything else I listed at #4115. |
67c4eb4
to
73af3b5
Compare
Good point about dropping, I totally agree that the commit needs to come first in that case. However, I'm not convinced it is necessary for the order to be consistent across dropping and checkout; those are very different operations. I'd rather think it should be consistent across pressing space in the commits view, versus pressing space in the remote branches view; in the latter case, local branch comes first, and detached head second.
I find Option 2 mainly attractive from an implementation point of view (it's the least amount of work). From a user's point of view I find it the least desirable, because it's the least immediate interaction; I find it preferable to stay in the commits panel for these operations. Option 1 is mainly attractive because it keeps the key bindings clean (there is only a single one to add, vs. potentially several if we go this route). Apart from that I'm on the fence whether I like it better or worse than what's proposed here. |
Looks like you figured that out meanwhile.
I don't find this to be a problem. |
73af3b5
to
32dab41
Compare
@stefanhaller I implemented your suggestions (I hope I didn't forget anything) and cleaned up the commits a bit. If you are satisfied with the current stage, we can merge it. But I can also squash everything together, if you want to avoid the back-and-forth in the history. If there is anything else to change, I appreciate your feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better. Yes, I'd prefer everything to be squashed into one commit at this point. (For the future, I prefer fixup!
commits in cases like this; they make the iterative development transparent, but at the same time they make it clear what the final history is going to look like.)
Still quite a few comments below, but many are at the level of nitpicking now.
The order question is still unresolved; I feel I'd still prefer the local branch to come first, but I can live with either order. We need @jesseduffield to make the final call here.
And finally, adding an integration test or two would be great. Let me know if you need help with that.
32dab41
to
5bc8f3d
Compare
I reworded the commits, is it in the form you would like to have it? The disadvantage of automatically squashable fixup commits is that you cannot distinguish them from their title.
I addressed most of them, but please have a look at my comments to finalize it.
I put the detached checkout first as @jesseduffield requested and I am not sure, what your last take was on that. You seemed rather agnostic with a tendency to "be consistent with the muscle memory of the users". With the short keys I am fine with keeping the detached head first as it is now implemented.
Some entry point and an example would be helpful. Are there some guidelines or special rules I need to obey? |
5bc8f3d
to
dad705d
Compare
Yes, perfect. (For next time, that is; in this case I thought you'd already squash the ones that we dealt with already, and only add new ones for new changes; no big deal either way though, these things are a bit of a matter of taste.)
Adding a brief description in the body like you did is a perfect way of dealing with this. You can even see these in github by clicking on the little
I thought I was pretty elaborate on that. Maybe I wrote too much, as I sometimes have a tendency of doing. I was originally hung up on the muscle memory thing, not realizing that it's not really so important in this particular case; then you convinced me that having the local branch first is better, and I agreed with that, and still do. Let me try to summarize the reasons again:
I just whipped up a quick example here: dad705d. I found this easier than explaining what I would do... |
Re: order of menu items: I'm happy to go with your suggestion @stefanhaller. I feel like we might need to revise this once we've rolled out more of these branch-specific options but I'm happy to go with your approach now. Re: menu layout: I agree, no need for colours or separate columns |
So just to recap the open points, I still need to do:
I will try to fulfill at least the first two points tomorrow. The third point I don't know if I can realize it tomorrow. Then I will be away from my computer for the next 5 days.
|
dad705d
to
00a1aa8
Compare
I pushed a few fixups again, see their commit messages. I'm happy with this now, I'd say this is ready to merge. Regarding the test that I added, I didn't really consider that a WIP commit. I think we can leave it as it is (unless you feel it should test more cases; I'll leave that up to you). |
Many thanks. It is good to see, that you use the placeholder pattern for strings already - I just wasn't sure if I'm on the right track (but honestly I didn't look for similar strings systematically).
I now actually see, that the test was pretty complete. And no, I currently don't see any additions needed.
So am I. 👍 Thanks for your support @stefanhaller, it was a very nice experience to collaborate with you, and I learned quite a bit. I felt very welcome, so I would be happy to continue contributing to the project. ❤️ Should I squash the fixups or would you do it before merging? |
Glad to hear this. Looking forward to your next contribution!
Either way is fine for me. If you do, please also rebase on master again. |
When the user checks out a commit which has a local branch ref attached to it, they can select between checking out the branch or checking out the commit as detached head.
b118a55
to
f4c8287
Compare
Squashed and rebased, ready to merge. 👍 |
This new menu ordering broke my muscle memory. But first, I want to clarify if this prompt is only supposed to show up when trying to checkout a commit that is also the last commit of a local branch? The original PR says:
But the code doesn't match that, it will insert a useless option if there are no local branches: lazygit/pkg/gui/controllers/helpers/refs_helper.go Lines 298 to 305 in 40d6800
My workflow often involves checking out individual commits as detached head. I always get this popup asking for checking out a branch or the commit as detached head. Of course, the first option - selected by default - is disabled because there is "no branch found at the selected commit". Given that it knows the first option cannot be chosen, why is it the default? It should select the first non-disabled option by default, so the old muscle memory of |
We went a little back and forth on the behavior during development, discussing various aspects of it, including the muscle memory thing, and eventually forgot to update the PR description, so no, it doesn't match the behavior any more. Sorry about that. You can learn more about the decisions we made by reading the discussion above.
I'm very interested to learn more about this. Can you describe this workflow more? |
In the discussion above, I just saw you did consider my usage above but thought it would be uncommon:
Anyway it seems odd to me to add a useless option that does nothing, and also select it by default.
Sometimes I would fix a bug first before writing a test. In that situation, I would move the test commit to be before the bug fix commit, then checkout the bug fix commit and run the test to ensure it fails and that the bug fix commit successfully fixed the bug. Or sometimes I would just want to look at a previous state of some code. I have also checked out different commits to compile a different version to them run them. I suppose in all those situations, you could create a branch at that commit and checkout that branch. But why do that when you only need to "check out" that commit? I only create a branch when I actually want to "branch" the code. I create tags for releases, but surely it's not uncommon to run different unreleased development builds. (For the first use case, I am indeed branching the code, but rebasing and rearranging commits should be common; a bug fix commit and its test commit is quite linear and if it's just 2 or so commits, it won't cause any confusion to edit linear history) If you search "git checkout specific commit", there are many stack overflow questions and blogs, etc. It doesn't seem like a niche feature to me. Maybe people like having a branch to avoid losing changes? I do indeed create a branch in that case, but I would have checked out to the commit first, discover I need to edit, then create a branch. |
See, that's what I suspected 😄. I do both of these things all the time (several times every day, no exaggeration). However, I don't press There are many reasons why that's better:
So, I feel that sometimes it's a good thing to break people's muscle memory to make them realize there are better ways to achieve what they want to do. 😄 |
Thanks for the suggestion, I'll have to try out your workflow for a while first. I guess it's not such a big change just for checking out things. For editing I prefer a slower and more manual way of commit first, review the diff, then edit history. It gives me the opportunity to double check my edits. But I can just use edit as a checkout replacement and avoid actually editing with it. Thanks (Git's use of names is just odd: using "rebase edit" to "check out" a commit is better than using |
When the user checks out a commit which has a local branch ref attached to it, they can select between checking out the branch or checking out the commit as detached head. If no local branch is attached to the commit, the behavior is like before: They are asked to confirm, if they want to checkout the commit as detached head.
Requested in #4115.
Note: I tried also to consider remote branches, but because I wasn't able to correlate remote branches to their commits, I deferred it and leave it open for later improvement.
go generate ./...
)