The Change-Id is important for Gerrit to know whether a commit that is pushed for code review should create a new change or whether it should create a new patch set for an existing change.
The Change-Id is a SHA-1 that is prefixed with an uppercase I
. It is specified as footer in the commit message (last paragraph):
Improve foo widget by attaching a bar. We want a bar, because it improves the foo by providing more wizbangery to the dowhatimeanery. Bug: #42 Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b Signed-off-by: A. U. Thor
If a commit that has a Change-Id in its commit message is pushed for review, Gerrit checks if a change with this Change-Id already exists for this project and target branch, and if yes, Gerrit creates a new patch set for this change. If not, a new change with the given Change-Id is created.
If a commit without Change-Id is pushed for review, Gerrit creates a new change and generates a Change-Id for it. Since in this case the Change-Id is not included in the commit message, it must be manually inserted when a new patch set should be uploaded. Most projects already require a Change-Id when pushing the very first patch set. This reduces the risk of accidentally creating a new change instead of uploading a new patch set. Any push without Change-Id then fails with missing Change-Id in commit message footer.
Amending and rebasing a commit preserves the Change-Id so that the new commit automatically becomes a new patch set of the existing change, when it is pushed for review.
Push new Patch Set
$ git commit --amend $ git push origin HEAD:refs/for/master
Change-Ids are unique for a branch of a project. E.g. commits that fix the same issue in different branches should have the same Change-Id, which happens automatically if a commit is cherry-picked to another branch. This way you can search by the Change-Id in the Gerrit web UI to find a fix in all branches.
Change-Ids can be created automatically by installing the commit-msg
hook as described in the Change-Id documentation.
Instead of manually installing the commit-msg
hook for each git repository, you can copy it into the git template directory. Then it is automatically copied to every newly cloned repository.
While a change is in review the HEAD of the target branch can evolve. In this case the change can be rebased onto the new HEAD of the target branch. When there are no conflicts the rebase can be done directly from the change screen, otherwise it must be done locally.
Rebase a Change locally
// update the remote tracking branches $ git fetch // fetch and checkout the change // (checkout command copied from change screen) $ git fetch https://gerrithost/myProject refs/changes/74/67374/2 && git checkout FETCH_HEAD // do the rebase $ git rebase origin/master // resolve conflicts if needed and stage the conflict resolution ... $ git add// continue the rebase $ git rebase --continue // push the commit with the conflict resolution as new patch set $ git push origin HEAD:refs/for/master
Doing a manual rebase is only necessary when there are conflicts that cannot be resolved by Gerrit. If manual conflict resolution is needed also depends on the submit type that is configured for the project.
Generally changes shouldn’t be rebased without reason as it increases the number of patch sets and creates noise with notifications. However if a change is in review for a long time it may make sense to rebase it from time to time, so that reviewers can see the delta against the current HEAD of the target branch. It also shows that there is still an interest in this change.
Note |
Never rebase commits that are already part of a central branch. |
If there is feedback from code review and a change should be improved a new patch set with the reworked code should be uploaded.
This is done by amending the commit of the last patch set. If needed this commit can be fetched from Gerrit by using the fetch command from the download commands in the change screen.
It is important that the commit message contains the Change-Id of the change that should be updated as a footer (last paragraph). Normally the commit message already contains the correct Change-Id and the Change-Id is preserved when the commit is amended.
Push Patch Set
// fetch and checkout the change // (checkout command copied from change screen) $ git fetch https://gerrithost/myProject refs/changes/74/67374/2 && git checkout FETCH_HEAD // rework the change $ git add... // amend commit $ git commit --amend // push patch set $ git push origin HEAD:refs/for/master
Note |
Never amend a commit that is already part of a central branch. |
Pushing a new patch set triggers email notification to the reviewers.
https://gerrit-documentation.storage.googleapis.com/Documentation/3.0.1/intro-user.html
https://gerrit-documentation.storage.googleapis.com/Documentation/3.0.1/user-review-ui.html#download
https://www.gerritcodereview.com/
http://gerrit-documentation.storage.googleapis.com/Documentation/2.8.1/user-changeid.html#amend