0

I have a bash script that uses hub to create pull-requests easily. In bash it works fine, I just type gpr <base_branch> and does the logic in the code.

# git pr
function gpr() {
    # exit if no base branch supplied
    if [[ ! $1 ]]; then
        echo "No base branch supplied. Exiting"
        return
    fi

    if [[ ! $2 ]]; then
        echo "Creating pull-request"
        echo "No pull-request message set."
        read -p "Do you want to use the last commit message as pull-request message. Y or N? " choice
        if [[ $choice =~ ^[Yy]$ ]]; then
            # Use last commit message
            COMMIT=$(git log -1 HEAD --pretty=format:%s)
            echo "Using last commit message: $COMMIT"
            MESSAGE="-m '$COMMIT'"
        else
            # Use own message
            read -p "Enter message: " message
            MESSAGE=-"m '$message'"
        fi
    fi
    COMMAND="hub pull-request -b $1 $MESSAGE"
    echo "Creating pull-request against $1 branch with message: $MESSAGE"
    eval $COMMAND
    echo "Pull-request created successfully"
}

Which in the end will result to hub pull-request -b <base_branch> -m <pull-request message or last commit message>

But how do I convert this to zsh?

I tried pasting the code to .zshrc but it seems to be not working. I get the following when running gpr <base_branch>

gpr develop
Creating pull-request
No pull-request message set.
gpr:read:10: -p: no coprocess
gpr:read:18: -p: no coprocess
Creating pull-request against develop branch with message: -m ''
And vim appears

In bash the process goes like this

gpr develop
Creating pull-request
No pull-request message set.
Do you want to use the last commit message as pull-request message. Y or N? y
Using last commit message: [UIUX-x] Commit message
Creating pull-request against develop branch with message: -m '[UIUX-x] Commit message'
https://github.com/<author>/<repo>/pull/<num>
Pull-request created successfully
3
  • Instead of a shell function, how about a script in ~/bin/ or whatever (just set your PATH right) with a shebang pointing to bash? Sep 4, 2017 at 12:26
  • Uhh, I'm not quite sure how to achieve that. I'm also doing this in wsl so it's easier for me to just add my own function to zsh.
    – Dev
    Sep 5, 2017 at 4:16
  • According to this it might work in WSL. (1) Write your code to a file gpr without lines: function ... and the last }. (2) Make the very first line a shebang: #!/bin/bash. (3) Make the file executable: chmod +x gpr. (4) Move the file to ~/bin directory. (5) Add ~/bin path to PATH unless it's already there. Then gpr will be handled by bash even in zsh. This is not an answer; it may solve your problem but it doesn't answer the question. Sep 5, 2017 at 6:33

1 Answer 1

2

The problem is that zsh's read function takes different options than bash's. In bash, read -p specifies a prompt; in zsh, it says to read from a coprocess (which doesn't exist). You need to switch to the zsh syntax, which puts the prompt after the variable to read (delimited by a question mark):

read "choice?Do you want to use the last commit message as pull-request message. Y or N? "
...
read -p "message?Enter message: "

Also, I'd make two other recommendations (for both bash and zsh): first, use lowercase or mixed-case variable names; there are a large number of all-caps variable names with special meaning to the shell, system, etc (and they're not the same between bash and zsh), and it's way to easy to accidentally re-use one of them with weird consequences.

Second, building the command in a variable and then evaling it is not safe (in either bash or zsh). Either use an array, or just put the message (and just the message) in a variable and execute the command directly:

if ...
    message=$commit
else ...
    read message
fi

echo "Creating pull-request against $1 branch with message: $message"
hub pull-request -b "$1" -m "$message"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .