Search code examples
fish

How can I get this bash sub shell to work in Fish?


I'm trying to get this command line working in Fish.

git show $(git log --pretty=oneline | fzf | cut -d ' ' -f1)

What is supposed to happen is git log --pretty=oneline | fzf | cut -d ' ' -f1 lets you select a commit interactively from git log and then returns the commit hash which is passed to git show.

I thought Fish uses parentheses for "subcommands" but this doesn't work.

git show (git log --pretty=oneline | fzf | cut -d ' ' -f1)

It goes straight to the default output of git show which is the HEAD commit.

I suspect my idea of how the shell works is incorrect. Any help appreciated.

UPDATE

This is the output from the pipeline

$ git log --pretty=oneline | fzf | cut -d ' ' -f1
3eb7a8fa09ac94cf4a76109b896f7ba58959f5a8

UPDATE 2

As answered by @faho, this is a bug in Fish.

You can workaround for now by using a tempfile

git log --pretty=oneline | fzf | cut -d ' ' -f1 > $TMPDIR/fzf.result; and git show (cat $TMPDIR/fzf.result)`

Or, more succinctly using xargs

git log --pretty=oneline | fzf | cut -d ' ' -f1 | xargs -o git show

Solution

  • This is fish issue #1362, which is also mentioned in fzf's readme.

    There's an easy workaround: Instead of a command substitution, use read, like

    git log --pretty=oneline | fzf | cut -d ' ' -f 1 | read -l answer
    git show $answer
    

    (fzf currently uses a tempfile in its fish bindings, but I'm working on rectifying that)