| # Advanced Gerrit Usage |
| |
| This file gives some more advanced examples of Gerrit workflows. This includes |
| using Gerrit dependency chains and managing local git history. |
| |
| ## Uploading a new dependent change |
| |
| If you wish to work on multiple related changes without waiting for them to |
| land, you can do so in Gerrit using dependent changes. There doesn't appear to |
| be any official documentation for this, but the rule seems to be: if the parent |
| of the commit you are pushing has a Change-Id line, that change will also be the |
| current change's parent. This is useful so you can look at only the relative |
| diff between changes instead of looking at all of them relative to master. |
| |
| To put this into an example, let's say you have a commit for feature A with |
| Change-Id: aaa and this is in the process of being reviewed on Gerrit. Now |
| let's say you want to start more work based on it before it lands on master. |
| |
| ``` bash |
| git checkout featureA |
| git checkout -b featureB |
| git branch --set-upstream-to featureA |
| # ... edit some files |
| # ... git add ... |
| git commit |
| ``` |
| |
| The git history then looks something like this: |
| |
| ``` |
| ... ---- master |
| \ |
| A |
| \ |
| B <- HEAD |
| ``` |
| |
| and `git log` might show: |
| |
| ``` |
| commit 47525d663586ba09f40e29fb5da1d23e496e0798 (HEAD -> featureB) |
| Author: btolsch <btolsch@chromium.org> |
| Date: Fri Mar 23 10:18:01 2018 -0700 |
| |
| Add some better things |
| |
| commit 167a541e0a2bd3de4710965193213aa1d912f050 (featureA) |
| Author: btolsch <btolsch@chromium.org> |
| Date: Thu Mar 22 13:18:09 2018 -0700 |
| |
| Add some good things |
| |
| Change-Id: aaa |
| ``` |
| |
| Now you can push B to create a new change for it in Gerrit: |
| |
| ``` bash |
| git push origin HEAD:refs/for/master |
| ``` |
| |
| In Gerrit, there would then be a "relation chain" shown where the feature A |
| change is the parent of the feature B change. If A introduces a new file which |
| B changes, the review for B will only show the diff from A. |
| |
| ## Examples for maintaining local git history |
| |
| ``` |
| D-E --- feature B |
| / ^N |
| A-B-C-F-G-H --- feature A |
| / ^M ^O |
| / |
| ... ---- master |
| /| |
| M O |
| | |
| N |
| ``` |
| |
| Consider a local repo with a master branch and two feature branches. Commits M, |
| N, and O are squash commits that were pushed to Gerrit. The arrow/caret (`^`) |
| indicates whence those were created. M, N, and O should all have Change-Id |
| lines in them (this can be done with the [commit-msg |
| hook](https://gerrit-documentation.storage.googleapis.com/Documentation/2.14.7/cmd-hook-commit-msg.html)). |
| M and O are separate patchsets in one review (M containing A, B, C and O |
| containing A, B, C, F, G) and N is the first patchset in a new review that is |
| dependent on the first patchset of the first review. |
| |
| Starting without M, N, or O, the commands to create them are as follows: |
| |
| ``` bash |
| git checkout C |
| git checkout -b M |
| git rebase -i origin/master # squash commits |
| # Note: make sure a Change-Id line exists on M at this point since N will need |
| # it. You can git commit --amend with the commit-msg hook active or add it via |
| # git commit --amend after pushing. Don't git commit --amend after creating N |
| # though. |
| git push origin HEAD:refs/for/master |
| git checkout E |
| git checkout -b N |
| git rebase -i C --onto M # squash commits |
| git push origin HEAD:refs/for/master |
| git checkout G |
| git checkout -b O |
| git rebase -i origin/master # squash commits and copy the Change-Id line from M |
| git push origin HEAD:refs/for/master |
| ``` |
| |
| ``` |
| D-E --- feature B |
| / ^Q |
| A-B-C-F-G-H --- feature A |
| / ^P |
| / |
| ... ---- master |
| /|\ |
| M O P |
| | | |
| N Q |
| ``` |
| |
| The next example shows an additional patchset being uploaded for feature A |
| (commit P) and feature B being rebased onto A, then uploaded to Gerrit as commit |
| Q. |
| |
| Starting from the endpoint of the previous commands, this point can be reached |
| as follows: |
| |
| ``` bash |
| git checkout H |
| git checkout -b P |
| git rebase -i origin/master # squash commits, same note as M about Change-Id |
| git push origin HEAD:refs/for/master |
| git checkout featureB # E |
| git rebase # assume featureA is set as featureB's upstream branch |
| git checkout -b Q |
| git rebase -i H --onto P |
| git push origin HEAD:refs/for/master |
| ``` |