Skip to content

Conversation

@carlfriedrich
Copy link
Collaborator

@carlfriedrich carlfriedrich commented Jul 14, 2022

When using glo (forgit::log) we can press Enter to show the changeset of the selected commit. The presentation, however, is rendered using the basic git diff command. We have a much more user friendly diff command gd (forgit::diff) right in forgit, though. Use this instead.

Fixes #217.

Check list

  • I have performed a self-review of my code
  • I have commented my code in hard-to-understand areas
  • I have made corresponding changes to the documentation

Description

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Breaking change
  • Documentation change

Test environment

  • Shell
    • bash
    • zsh
    • fish
  • OS
    • Linux
    • Mac OS X
    • Windows
    • Others:

@cjappl cjappl requested a review from wfxr July 15, 2022 02:08
@cjappl
Copy link
Collaborator

cjappl commented Jul 15, 2022

Looks reasonable enough to me! Thanks for the help, leaving to wfxr to approve officially

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch 2 times, most recently from ee72cef to 52ab616 Compare July 17, 2022 12:14
Copy link
Collaborator

@cjappl cjappl left a comment

Choose a reason for hiding this comment

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

Looks good to me. Please don't merge until @wfxr gives his thumbs up

@wfxr
Copy link
Owner

wfxr commented Jul 18, 2022

Looks like something went wrong paring the commit hash?
image

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch from 52ab616 to 2675443 Compare July 18, 2022 12:35
@carlfriedrich
Copy link
Collaborator Author

@wfxr Thanks for your feedback. I did not verify my changes in zsh in the first place, so I'm sorry that it didn't work.

After some checking it turns out that my (rather unrelated) quotation changes from \" to ' are causing the problem. I always prefer using different quotes over escaping, so I changed this on the run, but obviously zsh interprets this differently than bash.

I updated my branch with the quotation changes reverted. Should work in zsh now.

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch 3 times, most recently from 29e32ab to 119aff1 Compare July 18, 2022 12:52
@carlfriedrich
Copy link
Collaborator Author

I just updated my branch again to synchronize the quotation changes to the fish version. Should be ready to go now.

@wfxr
Copy link
Owner

wfxr commented Jul 19, 2022

@carlfriedrich Now the preview window works but when I hit enter it crashes:

image

With some background processes:
image

@carlfriedrich
Copy link
Collaborator Author

@wfxr Ah, I see. Obviously it tries to use bash for the function call to forgit::diff. What's your $SHELL environment variable set to?

@wfxr
Copy link
Owner

wfxr commented Jul 19, 2022

@wfxr Ah, I see. Obviously it tries to use bash for the function call to forgit::diff. What's your $SHELL environment variable set to?

@carlfriedrich /opt/homebrew/bin/zsh

@wfxr
Copy link
Owner

wfxr commented Jul 19, 2022

@carlfriedrich Maybe you should capture the printed commit hash from forgit::log and then call forgit::diff with it.

@carlfriedrich
Copy link
Collaborator Author

@wfxr Well, that's exactly what I'm doing. Strange. Can't reproduce this here. Can you try with a clean shell environment?

env -i TERM=xterm-color SHELL=/opt/homebrew/bin/zsh /opt/homebrew/bin/zsh
source forgit.plugin.zsh
glo

Does it happen there as well?

@wfxr
Copy link
Owner

wfxr commented Jul 19, 2022

@wfxr Well, that's exactly what I'm doing. Strange. Can't reproduce this here. Can you try with a clean shell environment?

env -i TERM=xterm-color SHELL=/opt/homebrew/bin/zsh /opt/homebrew/bin/zsh
source forgit.plugin.zsh
glo

Does it happen there as well?

@carlfriedrich Still the same.

Maybe you should capture the printed commit hash from forgit::log and then call forgit::diff with it.

I meant:

forgit::log() {
    # ....
    commit_hash=(eval "git log $graph --color=always --format='$log_format' $* $forgit_emojify" |
        FZF_DEFAULT_OPTS="$opts" fzf | capture_commit_hash)
    # call forgit::diff with $commit_hash
}

BTW remove enter keybind for fzf opts so that the selected line will be printed when hit enter.

@wfxr
Copy link
Owner

wfxr commented Jul 19, 2022

@carlfriedrich Would you mind if I add a commit to this pr?

@carlfriedrich
Copy link
Collaborator Author

@wfxr Give me a few minutes, I am fixing it right now. Your proposal above would not be the same, because the log routine would quit after exiting from the first diff.

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch 2 times, most recently from 7c00af9 to 3ff1bb8 Compare July 19, 2022 09:28
@carlfriedrich
Copy link
Collaborator Author

@wfxr Sorry, took a bit longer that I thought. Had to double-check my test environment (turned out that it still wasn't working correctly) and had a business call in between. However, now I am confident that it works in all three shells, at least on my machine. :-) Can you check again?

@wfxr
Copy link
Owner

wfxr commented Jul 19, 2022

@carlfriedrich Still crashes:
image

I'm using zsh-defer to load most of the plugins including forgit in my zshrc. Maybe the plugin is not ready when calling forgit::diff?

@carlfriedrich
Copy link
Collaborator Author

@wfxr Ah, I wasn't aware of zsh-defer until now. Yes, in this case forgit is obviously not loaded yet when forgit::diff is called.

Different to bash, unfortunately zsh does not support function exporting, so there's no way to pass the functions of the current environment to a new subshell. Starting an interactive shell explicitly, which loads .zshrc and along with that forgit again, seems to be the only way to have forgit functions in a subshell.

Is there a way to either

  • bypass zsh-defer loading or
  • wait until defered loading is completed?

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch from f569dd6 to cdad8b3 Compare July 19, 2022 14:30
@carlfriedrich
Copy link
Collaborator Author

@wfxr Even though I do not find it ideal, I have added a wait loop if the forgit functions are not found immediately. Can you check this?

Better and cleaner way to do this would be transferring all the forgit functions to an actual executable script, so that they do not have to be loaded to the environment in the first place, but are available via the PATH. That would require some refactoring, though, and I assume that wouldn't be what zsh calls a "plugin" anymore, since we would have more than one file, correct?

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch 2 times, most recently from 54f049c to 92a4b84 Compare July 19, 2022 15:27
@carlfriedrich
Copy link
Collaborator Author

@wfxr I found a better solution: instead of a waiting loop, do not rely on forgit being loaded via .bashrc / .zshrc at all, but reload it explicitly instead. This seems far more reasonable and should work in both bash and zsh. Can you check again?

@carlfriedrich carlfriedrich force-pushed the use-forgit-diff-in-log branch from 92a4b84 to aa8110e Compare July 19, 2022 15:43
@carlfriedrich
Copy link
Collaborator Author

carlfriedrich commented Jul 19, 2022

@wfxr Sorry for spam. :-) I just re-added the -i flag for spawning an interactive shell, because otherwise user defined forgit variable settings would be lost for the subshell. If these get loaded deferred as well, I wouldn't know how to work around this, though. Can you check if this works now for you?

@wfxr
Copy link
Owner

wfxr commented Jul 20, 2022

Hi @carlfriedrich Thanks for your effort for this PR. Now I can jump into the forgit::diff.

forgit_log_pr_219.mp4

However there still some issues.

  1. When hit enter the following message appears at the top of the window:

image

  1. I found I cannot see the detailed changes through the preview window anymore, which makes it difficult to quickly browse changes.

image

  1. As the video shows the screen will be messed up every first time I hit enter in the sub shell.

image

IMO entering a interactive shell in a fzf keybinding is too tricky which will cause some unexpected behaviors we don't known even if the above problems were solved. The other thing I concern is there are a log of guys who use oh-my-zsh or enabled many plugins take quite a few seconds to load the shell. This change will result in forgit::log with little usability.

So I tend to keep it simple and stupid.

@carlfriedrich
Copy link
Collaborator Author

carlfriedrich commented Jul 20, 2022

@wfxr Thanks a lot for your detailed feedback. Really appreciate your responsiveness and will to check my changes.

Hi @carlfriedrich Thanks for your effort for this PR. Now I can jump into the forgit::diff.

Yeah, finally! :-)

However there still some issues.

  1. When hit enter the following message appears at the top of the window:

Okay, I have no idea where that comes from. :-/

  1. I found I cannot see the detailed changes through the preview window anymore, which makes it difficult to quickly browse changes.

That was a deliberate change. I like the preview short and overview-like, then being able to enter the change to see the detailed diff. I understand, however, that this is personal preference and doesn't meet everyone's taste.

  1. As the video shows the screen will be messed up every first time I hit enter in the sub shell.

I have no idea about that either, and cannot reproduce it unfortunately.

IMO entering a interactive shell in a fzf keybinding is too tricky which will cause some unexpected behaviors we don't known even if the above problems were solved. The other thing I concern is there are a log of guys who use oh-my-zsh or enabled many plugins take quite a few seconds to load the shell. This change will result in forgit::log with little usability.

I see your point here. Obviously your zsh setup is already so much different from my test environment that it causes issues with this change, so there will probably be more issues with other setups.

I just wanted to bring something upstream that I am using in bash for quite a few months now, so that other people can benefit from it. However, I didn't expect it to be incompatible with zsh. Too bad. :-/

One last option would be to make this feature bash-only, but I assume that you would like to keep the features for all shells on par?

And one last general question for the bigger picture: I am not familiar with the zsh / oh-my-zsh plugin system. Is there a way to have a plugin that adds its folder to the PATH, so that we could have forgit in form of an executable script instead of env functions? Would that be an option? Because IMO we could use forgit feature chaining in more scenarios than just with glo -> gd (e.g. cherry picking by first interactively selecting the source branch instead of having to pass the source branch as an argument (that is so un-forgit-y :-))), which would make forgit much more user-friendly. And with forgit being an executable script we wouldn't have the issues concerning the functions being unknown to subshells.

@carlfriedrich
Copy link
Collaborator Author

So here's another shot for integrating forgit::diff into forgit::log, similar to the cherry-pick implementation of #216 and just like proposed by @wfxr above. This implementation does not mess with subshells in the enter command anymore and makes use of the actual fzf output.

I do not find it ideal, though. After quitting the diff, a new fzf instance is started, so the previous selection is gone. This makes it hard to browse through subsequent commit diffs. Unfortunately fzf does not provide a way to pre-select a line.

@wfxr @cjappl What do you think? On one hand I think this is an improvement concerning usability, because forgit's diff function provides a better (and more consistent) user experience than a plain git diff. On the other hand the resetting log window after each diff is a step back imo.

@wfxr
Copy link
Owner

wfxr commented Sep 21, 2022

@carlfriedrich I tested this implementation. As you said, both improvements and flaws are significant. How about making it an optional feature to satisfy users who like this feature more without affecting others?

When using glo (forgit log) we can press Enter to show the changeset of
the selected commit. The presentation, however, was rendered using the
basic git diff command. We have a much more user friendly diff command
gd (forgit diff) right in forgit, though. Use this instead.
@carlfriedrich
Copy link
Collaborator Author

With the changes of #241 we have finally a proper way to do this. Since the new commit was actually part of #241 during testing and approved along with those changes, I am directly merging this as well.

@carlfriedrich carlfriedrich merged commit 42c8e00 into wfxr:master Nov 26, 2022
@carlfriedrich carlfriedrich deleted the use-forgit-diff-in-log branch November 26, 2022 12:28
@nathanchance
Copy link

For what it's worth, this messes with the ability to view larger commit messages in forgit::log, which means I cannot use this much for my Linux kernel work :/ is there a way for this feature to coexist with that ability?

@carlfriedrich
Copy link
Collaborator Author

@nathanchance I'm sorry that this disrupts your workflow.

You can bring back the old behaviour by defining a custom enter command and adding it to your FORGIT_LOG_FZF_OPTS variable before sourcing forgit:

export FORGIT_LOG_ENTER_CMD="echo {} | grep -Eo '[a-f0-9]+' | head -1 | tr -d '[:space:]' | xargs -I% git show --color=always % | LESS='-Rc' less"
export FORGIT_LOG_FZF_OPTS="--bind='enter:execute($FORGIT_LOG_ENTER_CMD)'"

But may I ask why the new behavior actually prevents you from viewing the commit message? Don't you have it displayed in your preview window?
FYI: You can scroll within forgit's preview window by defining fzf keybindings in FORGIT_FZF_DEFAULT_OPTS. forgit already has defined standard values for this (Down: Alt+J / Alt+N, Up: Alt+K / Alt+P).

Would one of these two options work for you?

@nathanchance
Copy link

@nathanchance I'm sorry that this disrupts your workflow.

No worries!

You can scroll within forgit's preview window by defining fzf keybindings in FORGIT_FZF_DEFAULT_OPTS. forgit already has defined standard values for this (Down: Alt+J / Alt+N, Up: Alt+K / Alt+P).

Aha, I did not know about being able to scroll the preview window! That will work just fine for this, thanks a lot for pointing it out!

@carlfriedrich
Copy link
Collaborator Author

@nathanchance Great, thanks for your feedback!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Why not use forgit::diff on forgit::log enter?

4 participants