Search code examples
gitbitbucketgit-pushpull-request

Extract url from git push remote response


When I push my changes to our Bitbucket server, along with the usual stats, the server responds with several lines preceded with 'remote:'. One of those lines contains a URL to few the diff for the pushed branch and create a pull request. I currently highlight the URL and copy/paste it into a browser window to create my pull request, but I am looking to speed that process up. Is there a way to extract the URL and pass it to 'clip' to save it to the clipboard as part of a git alias?

I also thought about trying to re-create the URL using a combination of the current branch name and the remote URL, but there are several differences between the remote URL and the pull request URL so it seemed easier to extract the URL rather than re-create it.

Counting objects: 47, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (45/45), done.
Writing objects: 100% (47/47), 12.81 KiB | 0 bytes/s, done.
Total 47 (delta 40), reused 3 (delta 2)
remote:
remote: Create pull request for feature/somefeature:
remote:   https://code.ourbitbucketserver.com/projects/myteam/repos/somerepo/compare/commits?sourceBranch=refs/heads/feature/somefeature
remote:
To https://code.ourbitbucketserver.com/scm/myteam/somerepo.git
 * [new branch]        feature/somefeature -> feature/somefeature
Branch feature/somefeature set up to track remote branch feature/somefeature from origin.

Solution

bcurrent = "!git rev-parse --abbrev-ref HEAD"
publishold = "!f() { git push -u ${1-origin} $(git bcurrent); }; f"
publishnew = "!f() { git push -u ${1-origin} $(git bcurrent) --progress 2>&1 | awk '/^remote:.*compare/ { system(\"echo \" $2 \" | clip\") } { print }'; }; f"

The bcurrent and publishold aliases are what I started with for reference.

The accepted answer set me in the right direction. I ran into a few issues along the way that I want to explain.

  1. git push outputs some of the message (including the url) over stderr instead of stdout. So we have to redirect stderr with the 2>&1. Also added the --progress flag so git will output stderr even if it isn't connected to the console since we are piping the output to awk. See git stderr output can't pipe
  2. clip does not accept parameters at the command line and input must be piped into it.
  3. Since my git alias is a shell function, I had to escape the double quotes in the system call.

Solution

  • You can use awk in your alias. The following will print the output fully and additinally call clip with the URL as argument:

    echo 'Counting objects: 47, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (45/45), done.
    Writing objects: 100% (47/47), 12.81 KiB | 0 bytes/s, done.
    Total 47 (delta 40), reused 3 (delta 2)
    remote:
    remote: Create pull request for feature/somefeature:
    remote:   https://code.ourbitbucketserver.com/projects/myteam/repos/somerepo/compare/commits?sourceBranch=refs/heads/feature/somefeature
    remote:
    To https://code.ourbitbucketserver.com/scm/myteam/somerepo.git
     * [new branch]        feature/somefeature -> feature/somefeature
    Branch feature/somefeature set up to track remote branch feature/somefeature from origin.' | awk '/^remote:.*compare/ { system("clip " $2) } { print }'