Gerrit hook API - gerrit

I'm using Gerrit Code review.
I have a problem with it. There are some hooks with Gerrit, one of them is:
patchset-created --change <change id> --change-url <change url>
--project <project name> --branch <branch> --uploader <uploader>
--commit <sha1> --patchset <patchset id>
Gerrit will call it if you push some change to Gerrit.
The commit parameter passed in is the sha1 commit number, but what I want is the commit log. For example, if I do git commit -m "id:110", I want to get id:110.
How can I get it? Is there any API I can use?

You can use git log or git show, run from within the correct repository. Your hook will be passed the repo via --repository. The hook will be called from a useful working directory (I just checked into this last week, I think it cd's into the repo before running the hook?)
git log $SHA1 or git show $SHA1 depending on which information you want.
That said, I'd prefer a better solution. I'm looking to add the diff / patchset to the information, and it is not available via any of the gerrit hooks.

i have solve the problem myself.it seems that gerrit has not such apis.
but , if patchset-created hook is called , the change parameter it passed in is usefull,
if refer to a private key of gerrit database table ,named Change ,every git push to gerrit it record such change to the Change table , include the commit message , so , you can use the change parameter to query the table , so got the commit message from the hook !

Related

gerrit query doesn't print PL

ssh -p 29418 review.test.com gerrit query --patch-sets 199423
This prints most of the fields I see in gerrit page but not the PL, I see PL in gerrit page, is there a way to make the gerrit query print the same? I am new to gerrit, thanks in advance.
If by PL you mean the rules.pl file you can't get that by using gerrit query.
You can download and edit the config for your project by using Git commands:
git fetch origin refs/meta/config:config
git checkout config
... edit or create the rules.pl file
git add rules.pl
git commit -m "My submit rules"
git push origin HEAD:refs/meta/config
Documentation

Checkout bitbucket pull requests locally

I found this gist, showing how to check out a pull request locally from GitHub.
I'm using bitbucket and I'm looking for a similar function.
Can you help me?
Thank you
One may fetch the code from Bitbucket Server's pull requests using:
git fetch origin refs/pull-requests/$PR_NO/from:$LOCAL_BRANCH
I found this answer and thought that it was actually possible to fetch refs for a pull request on bitbucket.
But it's not.
The answer for the OP's question is that it is NOT possible: there's been an open feature request issue about it that has been unanswered and unattended for four five SIX SEVEN years.
The workaround?
You can get the PR as a downloadable .patch file you can download and apply to a new branch you create manually. But you won't easily be able to apply updates.
I figured another way out, which I've implemented in git-repo, so everybody can use it. What I'm doing is use the API to get the PR's remote and branch, and automatically create a new upstream and branch locally. That way you can get updates from the PR poster. The downside is the clutter of git remotes.
edit: I hope this gets done and the feature request is closed. But there has been a solution for this on dedicated bitbucket servers for some time now, but not on the bitbucket.org service. On June 5th, a bitbucket staff member commented on this ticket:
Hi y'all -- thanks again for your feedback and patience on this issue. This feature is still high on the priority list in the backlog. When we have more information to share about the expected delivery of this feature, we will share it here.
I followed this article Pull request Fetching.
It worked but I found out I just need add one line to the current repo, rather than create a folk repo and an upstream repo. Run this line
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
You can also add it manually to the file .git/config in your project.
Next run git pull you should see a list:
[new ref] refs/pull-requests/488/from -> origin/pr/488
[new ref] refs/pull-requests/666/from -> origin/pr/666
Then you can run git checkout origin/pr/666 to get the pull request changes.
Fetch/Checkout Pull Requests
This works for bitbucket. Other server could have different refs: (refspecs) or no refs: at all.
First Time
First of all you need to add the pull request refs: of the remote repository. To do that to a repository (e.g. aliased 'upstream'):
git config --add remote.upstream.fetch '+refs/pull-requests/*/from:refs/remotes/upstream/pull-requests/*'
That is, you add the last line on git .config file:
[remote "origin"]
url = ssh://git#git.blablabla.net/~user/repository.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pull-requests/*
Fetching
Then if you perform the remote fetch you should see the retrieval of (also) all the pull requests:
git fetch upstream
From ssh://git.blablabla.net/somepath/repository
* [new ref] refs/pull-requests/1188/from -> upstream/pull-requests/1188
* [new ref] refs/pull-requests/1741/from -> upstream/pull-requests/1741
* [new ref] refs/pull-requests/2394/from -> upstream/pull-requests/2394
Checking out
Finally you can checkout the pull-request you prefer:
git checkout pull-requests/2723
Successfully tested on dedicated bitbucket server 27/02/19.
When is not possible to checkout the pull request, a trick is that you can checkout the last commit of that pull request
git checkout <hash code of last commit>
If you use forks probably "origin" is your fork, so first of all you should add the main remote.
Take the URL of the main remote clicking the "Clone" button in the repository page the same way you do when you clone a repository
git remote add upstream $UPSTREAM_URL
fetch the pull request
git fetch upstream refs/pull-requests/$PR_NO/from:$LOCAL_BRANCH
checkout the new branch
git checkout $LOCAL_BRANCH
If you are using forked repository and you want to pull PR from original or other repo then use below commands.
1. git fetch ${URLofOriginalRepo}
“+refs/pull-requests/*/from:refs/remotes/origin/pr/*”
2. git checkout origin/pr/${PR_NUMBER}
URLOfOriginalRepo is the url repository from which you want to pull the PR. This url is the one you use to clone the repo using ssh key.
After running these command you can see the open PR's on this repo. Then pull the one you want.
for eg.
git fetch ssh://hostname.net:8080/repofolder/repo.git.git “+refs/pull-requests//from:refs/remotes/origin/pr/”
&&
git fetch origin/pr/854
It seems the easiest way to do this is still to get a patch of the pull request. Based on this question's answer, Alexandre's comment is still the only way to do this. It uses this BitBucket API call.
I used the following bash script:
USER=username
PASSWORD=password
REPO=repo-name
PULL_NO=42
OUTPUT_FILE=output.patch
# Add -i to include the HTTP-header in the output for debugging
curl -u $USER:$PASSWORD https://bitbucket.org/api/2.0/repositories/$USER/$REPO/pullrequests/$PULL_NO/patch -L -o $OUTPUT_FILE
Save that to a file called pull-patch.sh and fill in the environment variables with your account details. The script requires that you have curl installed (e.g. sudo apt install curl). Then run:
chmod +x pull-patch.sh
./pull-patch.sh
And a file called output.patch should be created from the pull request.
In bitbucket what you can do is
git config remote.origin.fetch "+refs/heads/:refs/remotes/origin/"
and then
git fetch
after that you can checkout to the branch you want to
git checkout BRANCH_NAME
P.S: Hopefully bitbucket will sort this out https://jira.atlassian.com/browse/BCLOUD-5814
I found this difficult in bit bucket, so, I tried a different approach. If a person give a pull request to my repo in bitbucket, i set his(bill) origin by him name(bill) . then to this -
git checkout -b bill-auth bill/bill-auth
Here bill is that contributer repo origin / link , then bill-auth is his branch name.
Here I am creating a branch same name as his(bill) feature branch.
git fetch origin refs/pull-requests/$PR_NO/merge - it works for Butbucket v5.14.1

How to change a patchset and push it as a new one?

Is it possible to fetch an existing patchset (that has not been merged into my local machine), change and push it as a new Patch Set?
#Uncletall put all the steps there and the link, the only thing is that you should not delete the changeId and you should do a git commit --amend. I am giving him a +1.
It should be like this
On Gerrit, go to the review, select "checkout", on the Download field as opposed to "pull", "cherry-pick", or "patch", then copy the command.
On the git project paste the copied link from above
This will create a detached head, which is a branch with no name (I've been through the desert on a horse with no name, It felt good to be out of the rain.)
Name that horse! git checkout -b new_branch_name
Change what you want and do a git add on the files you want.
Do git commit --amend and keep the same Change-Id.
Push your changes:
git push origin <new_branch_name>:refs/for/<thatgerritbranchyouwanttochange>
Just follow the below steps:
cherry-pick your patch (from gerrit UI) to your machine.
Modify the content and run git add <modified file>.
Amend the last commit using git commit --amend that pops up a COMMIT-EDITMGS window. Save it accordingly.
Push your change to gerrit using git push origin HEAD:refs/for/branch_name
It will create a new patch set.
Consult Trying out a Change in the official documentation.
Here is what you do:
Checkout the change as described in the documentation
Create a local branch from the FETCH_HEAD
Modify your code
Commit the change using git --amend and remove the Change-Id in the commit message
A new Change-Id will automatically be added and this will result in a new Change Set
Push your change for review and Gerrit will see it as a new Change Set
As pointed out by #magnus-bäck, I was describing how to create a new Change-Set. If you want to add a new Patch Set to the current review you should NOT remove the Change-Id.

Git Working tree is dirty

If I execute git review git shows me "Working tree is dirty" error.
I made a commit and I sent to review. After that I update the branch from the upstream using git pull. Now I need to modify the previous commit message, so, there are my commands:
1) git reset <id-of-the-commit-to-modify>
2) git commit --amend
vim was opened to modify my commit. But here appears information about my commit and others commits as well and I don't know why. However, I modified the commit message and write/close vim.
3) git review
This command raise this error:
Errors running git rebase -i remotes/gerrit/master
doc/source/configuration.rst: needs update
doc/source/developing.rst: needs update
tools/sample_data.sh: needs update
Working tree is dirty
What I doing wrong?
git reset <id-of-the-commit-to-modify> without a mode option is defaulted to --mixed . This is what is said on the reset in the manual
--mixed
Resets the index but not the working tree (i.e., the changed files are preserved but not marked for commit) and reports what has not been updated. This is the default action.
This basically means your index has been reset, but not your working files. So all files that you pulled from upstream are still left in your working tree.
You should use git reset --hard <id-of-the-commit-to-modify> This will reset your index and remove the files that came with your upstream pull. You can then amend your commit and send it for review.
once a change was pushed to Gerrit, then it can be fetched directly. On the Gerrit review board you can find the chekcout command for each patchset, something like this: git fetch ssh://ebalbar#gerrit.ericsson.se:29418/TCC/TitanSim refs/changes/86/129686/5 && git checkout FETCH_HEAD Then, you can amend the commit as usual, and push the new change again. AFter that checkout your local branch and reset it with the remote branch: git reset --hard origin/<remote_branch> also a nice answer how to modify a commit which was pushed directly.

Let Jenkins build project from a Mercurial commit

Is there a way to specify a hook in the single repository?
Now we have specified the hook in the "/etc/mercurial/hgrc" file, but every time it builds twice, and it builds for each commit in each repository.
So we want to specify a build per repository.
This is how we implemented the hook:
[hooks]
changegroup = curl --silent http://jenkins:8080/job/ourProject/build
It's on a Ubuntu server.
Select the Poll SCM option under Build Triggers.
Make sure that schedule form is empty.
You should be creating in the .hg directory, /home/user/mercurial/.hg/hgrc and add hooks as:
[hooks]
commit.jenkins = wget -q http://localhost:8080/mercurial/notifyCommit?url=file:///home/user/mercurial > /dev/null
incoming.jenkins = wget -q http://localhost:8080/mercurial/notifyCommit?url=file:///home/user/mercurial > /dev/null
You should make sure that
Your Jenkins project doesn't poll
You use the proper notifyCommit URLs for your Mercurial hooks: https://wiki.jenkins-ci.org/display/JENKINS/Mercurial+Plugin
Ok, I found what I looked for (I'm the bounty; my case is Mercurial with a specific branch).
In the main/origin repository, place a hook with your desired build script. Pregroupchange is to maintain the incoming changes. I have a rhodecode installed on the main repository and itself has its own hooks.
In this way, I still trigger Jenkins and still have the changes afther the trigger for rhodecode push notifications and others.
[hooks]
pregroupchange = /path/to/script.extention
In the script, place your desired actions, also a trigger for Jenkins. Don't forget to enable in Jenkins:Job:Configure:Build Triggers:checkbox Trigger builds remotely + put here your desired_token (for my case: Mercurial).
Because you can't trigger only to a specific branch in Mercurial, I found the branch name in this way. Also, to trigger from a remote script, you need to give in Jenkins read permission for anonymous overall, or create a specific user with credentials and put them into the trigger URL.
Bash example:
#!/bin/bash
BRANCH_NAME=`hg tip --template "{branch}"`
if [ $BRANCH_NAME = "branch_name" ]; then
curl --silent http://jenkins_domain:port/path/to/job?token=desired_token
fi
For the original question:
In this way you only execute one build, for a desired branch. Hooks are meant only for the main repository in case you work with multiple clones and multiple developers. You may have your local hooks, but don't trigger Jenkins from you local, for every developer. Trigger Jenkins only from the main repository when a push came (commit, incoming, and groupchange). Your local hooks are for other things, like email, logs, configuration, etc.

Resources