Skip to content

Migrate deprecated AllBranchesLogCmd to AllBranchesLogCmds #4345

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

Merged
merged 1 commit into from
May 7, 2025

Conversation

ChrisMcD1
Copy link
Contributor

@ChrisMcD1 ChrisMcD1 commented Feb 28, 2025

  • PR Description

Fixes #3961

Their issue where the default allBranchesLogCmd default remains present is because we just do a lo.Uniq(lo.WithoutEmpty()) on the combined list of allBranchesLogCmd and allBranchesLogCmds.

At the point of this code, it is not possible to tell whether the value present in allBranchesLogCmd is user-provided or not. We have already merged the config with the default config, so the user not setting anything, and the user explicitly setting "Yes, I want the default", are indistinguishable.

Based on that bug report, I'm assuming that users that have not set anything for allBranchesLogCmd, but have set something for allBranchesLogCmds, just want the list they have specified in the plural version. Some users have likely figured out they can explicitly set allBranchesLogCmd: "" to get this behavior, but most would not.

To achieve this desired behavior, I figure it is easiest to just migrate all user config to allBranchesLogCmds. If they have explicitly set a non-empty value in allBranchesLogCmd, it will be pulled over. If they set an empty string, it will be excluded.

  • Please check if the PR fulfills these requirements
  • Cheatsheets are up-to-date (run go generate ./...)
  • Code has been formatted (see here)
  • Tests have been added/updated (see here for the integration test guide)
  • Text is internationalised (see here)
  • If a new UserConfig entry was added, make sure it can be hot-reloaded (see here)
  • Docs have been updated if necessary
  • You've read through your own file changes for silly mistakes etc

@ChrisMcD1
Copy link
Contributor Author

@stefanhaller Could you give this a look?

Also, is there somewhere I should include a notice of breaking changes on re-write? Last time we did this there were some nix people using immutable config files that ran into issues because they don't let LazyGit do write-back.

@stefanhaller stefanhaller added the bug Something isn't working label Apr 29, 2025
Copy link
Collaborator

@stefanhaller stefanhaller left a comment

Choose a reason for hiding this comment

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

Great work! Looks mostly good, just my usual bunch of minor nitpicks below.

And sorry for taking so long to review.


cmdsKeyNode, cmdsValueNode := yaml_utils.LookupKey(gitNode, "allBranchesLogCmds")
if cmdsKeyNode == nil {
// Create dummy node and attach it onto the root git node
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's "dummy" about this? I find this comment more confusing than helpful, and I think we might just delete it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added an additional comment to clarify what I meant.
For me, it feels a bit odd to create the empty sequence, which would be nonsensical to do if we didn't then prepend the element onto it. So I'm just calling out that odd implementation.

If you still think the comment is confusing, or the implementation is trivial, I'm happy to remove.

(And we do technically support the weird case where the user has just removed the default allBranchesLogCmd by setting it equal to "", and then done nothing else. The clearing behavior of setting it to "" is why we check if the value is an empty string further down)

Copy link
Collaborator

Choose a reason for hiding this comment

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

It was really just the "dummy" that I found confusing. The new comment is great. (Personally I still think it isn't needed; it's clear enough what the code is doing. But if you find it helpful, no objections.)

Comment on lines 373 to 375
if cmdsValueNode.Kind != yaml.SequenceNode {
return fmt.Errorf("You should have an allBranchesLogCmds defined as a sequence!")
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I find it slightly confusing to do this here, where in half of the cases we have just created this ourselves and know it's the right type. I would move this up to an else block after line 370. (Yes, it then runs unnecessarily even when cmdValueNode is empty and there's nothing to migrate, but it doesn't hurt to throw the error in that case too; loading the non-migrated config file would have failed anyway.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, if that feels more coherent to you. My thought was just to keep it local to the moment that stuff would break should it not be defined as a sequence node.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, I like this better, thanks for changing. It's really minor though.

I pushed one more fixup to replace the unneeded fmt.Errorf with errors.New (7067885); I missed this the first time around. (I thought we had a linter check for this? Seems not.)

return fmt.Errorf("You should have an allBranchesLogCmds defined as a sequence!")
}
// Prepending the individual element to make it show up first in the list, which was prior behavior
cmdsValueNode.Content = append([]*yaml.Node{{Kind: yaml.ScalarNode, Value: cmdValueNode.Value}}, cmdsValueNode.Content...)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have utils.Prepend for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I have used it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh.... it actually triggers a package import loop :(

# github.com/jesseduffield/lazygit/pkg/utils
package github.com/jesseduffield/lazygit
        imports github.com/jesseduffield/lazygit/pkg/app from main.go
        imports github.com/jesseduffield/lazygit/pkg/app/daemon from entry_point.go
        imports github.com/jesseduffield/lazygit/pkg/commands/models from rebase.go
        imports github.com/jesseduffield/lazygit/pkg/utils from commit.go
        imports github.com/jesseduffield/lazygit/pkg/common from dummies.go
        imports github.com/jesseduffield/lazygit/pkg/config from common.go
        imports github.com/jesseduffield/lazygit/pkg/utils from app_config.go: import cycle not allowed

Is that worth trying to tease apart, or does it not matter? It's a one-liner even inside the utils, so I don't feel the benefit is very high

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh wow, that's annoying. Sure, for this PR it's totally ok to leave it as is, but in the future we should look into fixing this; it should be possible to depend on something as simple as utils/slice from anywhere else.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I opened #4538 to fix this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Migrated to utils.Prepend after rebasing off master.

Comment on lines 770 to 772
if err != nil {
t.Error(err)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

There's assert.NoError for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used!

The godocs example had it being used in an if guard, so I did that too

Copy link
Collaborator

Choose a reason for hiding this comment

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

Good. I have to say I'm torn about using the if guard; we don't do this anywhere else in our code. I get its purpose, but I wonder if it's the right tradeoff; it helps making the test output potentially less confusing in the case that the test does fail with an error, but how often is that going to happen? And it comes at the cost of making the test a little harder to read, which I find more important here, so I'd vote for removing the condition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, removed the condition, I have no particular affinity for it.

Maybe going around and making all the tests use the condition would be a good small task for me to do? I view it sort of like an:

if err == nil {
   assertMoreStuff
}

so it doesn't feel really out of place to me (although I wish it would follow the more normal err != nil convention)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I still prefer not to do this. I like the simplicity of just listing all test expectations without conditions, this makes the tests very clear and easy to read. As I said, the downside is that you might get two failed expectations instead of just one if a test fails, but that's not a big deal, and it will happen very rarely anyway.

@@ -100,6 +100,19 @@ func lookupKey(node *yaml.Node, key string) (*yaml.Node, *yaml.Node) {
return nil, nil
}

// Returns the key and value if they were present
func RemoveKey(node *yaml.Node, key string) (*yaml.Node, *yaml.Node) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it would make sense to add a test for this, we have tests for most other things in yaml_utils.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ChrisMcD1 I had a need for this function in a PR of mine (#4525), so I stole this function from your PR and added tests for it. (Would also appreciate a review of the rest of the branch if you feel like it.)

@stefanhaller
Copy link
Collaborator

Also, is there somewhere I should include a notice of breaking changes on re-write? Last time we did this there were some nix people using immutable config files that ran into issues because they don't let LazyGit do write-back.

It would be good if we could do one or both of the suggestions from #4210 (comment). Would you be up for giving that a try? I'll hold off merging this one before next Saturday's release to give us a bit more time for that.

@ChrisMcD1 ChrisMcD1 force-pushed the 3961-all-branches-log branch 2 times, most recently from 0d38051 to 5b964f8 Compare May 5, 2025 00:52
@ChrisMcD1
Copy link
Contributor Author

@stefanhaller Comments addressed!

Got a load of garbage commits to just show you how I was thinking through your suggestions. Will squash them after review prior to merge.

Will remove RemoveKey helper once your PR that also uses it is merged and I rebase off of master.

@stefanhaller
Copy link
Collaborator

Got a load of garbage commits to just show you how I was thinking through your suggestions.

No worries, but just out of curiosity: why didn't you continue to use fixup commits for these? I like doing that and putting a bit of explanation into the body of the commit messages, seems like the best of both worlds to me.

@ChrisMcD1
Copy link
Contributor Author

No worries, but just out of curiosity: why didn't you continue to use fixup commits for these? I like doing that and putting a bit of explanation into the body of the commit messages, seems like the best of both worlds to me.

I was not aware until right now that you could do a body on a fixup commit, I only ever create them with F in Lazygit while selecting the commit I'm targeting. What is your flow where you add a body?

@stefanhaller
Copy link
Collaborator

I was not aware until right now that you could do a body on a fixup commit,

Yes, for the auto-squash functionality only the subject is used, the body can be anything you want. Of course it's lost when squashing, so it's only useful during review.

I only ever create them with F in Lazygit while selecting the commit I'm targeting. What is your flow where you add a body?

I also use F to create them, and then I just reword them afterwards.

@ChrisMcD1 ChrisMcD1 force-pushed the 3961-all-branches-log branch from 7067885 to 9df51c8 Compare May 7, 2025 03:30
This solves jesseduffield#3961 because
we no longer have a combination of the default and the user defined
list. We just have the user defined list.
@ChrisMcD1 ChrisMcD1 force-pushed the 3961-all-branches-log branch from 9df51c8 to 1028f8e Compare May 7, 2025 03:34
@stefanhaller
Copy link
Collaborator

LGTM!

@stefanhaller stefanhaller merged commit e6bd9d0 into jesseduffield:master May 7, 2025
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

allBranchesLogCmds always includes default log command
2 participants