1. When to use this skill
Use this skill when you need to create, update, or manage a chain of dependent changelists (CLs) in Gerrit (stacked CLs) for the Dart SDK or similar repositories using Chromium's depot_tools.
2. Core Concepts
- Relation Chain: Gerrit links commits together based on their parent-child relationship in the pushed git history.
- Change-Id: Gerrit identifies a CL by the Change-Id: line in the commit message.
- Commit Hash: Gerrit identifies a Patchset within a CL by the git commit hash.
3. Procedural Workflows
Creating Stacked CLs
- Start with the base CL:
git new-branch branch1 # Make changes git commit -m "First change" git cl upload - Create the dependent CL:
Create a new branch on top of
branch1.
Gerrit will automatically create a relation chain.git checkout branch1 git new-branch branch2 # Make dependent changes git commit -m "Second change" git cl upload
Updating a Specific CL in a Stack
To update a specific CL without confusing Gerrit, you must ensure that the commit you push has the correct Change-Id and that it is the last Change-Id in the commit message if multiple are present (though ideally, keep only one).
Method A: Amending (If allowed by user rules)
If allowed to amend, this is the cleanest way:
- Checkout the branch for the CL you want to update.
- Make changes.
- Run
git commit --amend. Keep the originalChange-Idline intact! - Run
git cl upload.
Method B: New Commit + Squash (Following strict no-amend rules)
If forbidden from amending active PRs:
- Make changes on the branch.
- Commit as a new commit (generating a new Change-Id).
- To update the existing CL on Gerrit without creating a new one:
- Squash the new commit into the previous one using git reset --soft HEAD~2 (assuming one fixup commit) and then committing again.
- CRITICAL: Ensure the final commit message contains only the
Change-Idof the CL you want to update. If multipleChange-Id:lines are present, Gerrit will typically use the last one!
Resolving Conflicts in Stacked CLs
When rebasing a dependent branch (e.g., branch2) on top of an updated base branch (branch1), conflicts may arise in generated files (like .wat files).
- Accept OURS (the upstream/base version) during conflict resolution to get past the rebase conflict quickly.
- Complete the rebase (
git rebase --continue). - Re-generate the expectations or generated files using the appropriate tool (e.g.,
ir_test.dart -w). - Commit the newly generated files to keep the expectation history clean and accurate.
4. Critical Pitfalls
- Multiple Change-Ids in a Commit Message: If you squash commits or copy-paste messages, you might end up with multiple
Change-Id:lines. Gerrit reads them and usually routes the update to the CL corresponding to the lastChange-Idin the message. Always clean up commit messages to have exactly one targetChange-Id. - No New Changes: If you try to push a commit that is identical in content to an existing patchset, Gerrit will reject it. To force a new patchset (e.g., to restore an older state), use
git commit --amend --no-editto update the committer timestamp and generate a new commit hash.