maruel | 9e198a8 | 2016-08-11 15:32:19 | [diff] [blame] | 1 | # git-cl |
| 2 | |
| 3 | The git-cl README describes the git-cl command set. This document describes how |
| 4 | code review and git work together in general, intended for people familiar with |
| 5 | git but unfamiliar with the code review process supported by Rietveld and |
| 6 | Gerrit. |
| 7 | |
| 8 | |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 9 | ## Rietveld concepts and terms |
maruel | 9e198a8 | 2016-08-11 15:32:19 | [diff] [blame] | 10 | |
| 11 | A Rietveld review is for discussion of a single change or patch. You upload a |
| 12 | proposed change, the reviewer comments on your change, and then you can upload a |
| 13 | revised version of your change. Rietveld stores the history of uploaded patches |
| 14 | as well as the comments, and can compute diffs in between these patches. The |
| 15 | history of a patch is very much like a small branch in git, but since Rietveld |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 16 | is VCS-agnostic, the concepts don't map perfectly. The identifier for a single |
| 17 | review thread including patches and comments in Rietveld is called an **issue**. |
maruel | 9e198a8 | 2016-08-11 15:32:19 | [diff] [blame] | 18 | |
| 19 | Rietveld provides a basic uploader that understands git. This program is used by |
| 20 | git-cl, and is included in the git-cl repo as upload.py. |
| 21 | |
| 22 | |
| 23 | ## Basic interaction with git |
| 24 | |
| 25 | The fundamental problem you encounter when you try to mix git and code review is |
| 26 | that with git it's nice to commit code locally, while during a code review |
| 27 | you're often requested to change something about your code. There are a few |
| 28 | different ways you can handle this workflow with git: |
| 29 | |
| 30 | 1. Rewriting a single commit. Say the origin commit is O, and you commit your |
| 31 | initial work in a commit A, making your history like O--A. After review |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 32 | comments, you `git commit --amend`, effectively erasing A and making a new |
| 33 | commit A', so history is now O--A'. (Equivalently, you can use |
| 34 | `git reset --soft` or `git rebase -i`.) |
maruel | 9e198a8 | 2016-08-11 15:32:19 | [diff] [blame] | 35 | 2. Writing follow-up commits. Initial work is again in A, and after review |
| 36 | comments, you write a new commit B so your history looks like O--A--B. When |
| 37 | you upload the revised patch, you upload the diff of O..B, not A..B; you |
| 38 | always upload the full diff of what you're proposing to change. |
| 39 | |
| 40 | The Rietveld patch uploader just takes arguments to `git diff`, so either of the |
| 41 | above workflows work fine. If all you want to do is upload a patch, you can use |
| 42 | the upload.py provided by Rietveld with arguments like this: |
| 43 | |
| 44 | upload.py --server server.com <args to "git diff"> |
| 45 | |
| 46 | The first time you upload, it creates a new issue; for follow-ups on the same |
| 47 | issue, you need to provide the issue number: |
| 48 | |
| 49 | upload.py --server server.com --issue 1234 <args to "git diff"> |
| 50 | |
| 51 | |
| 52 | ## git-cl to the rescue |
| 53 | |
| 54 | git-cl simplifies the above in the following ways: |
| 55 | |
| 56 | 1. `git cl config` puts a persistent --server setting in your .git/config. |
| 57 | 2. The first time you upload an issue, the issue number is associated with the |
| 58 | current *branch*. If you upload again, it will upload on the same issue. |
| 59 | (Note that this association is tied to a branch, not a commit, which means |
| 60 | you need a separate branch per review.) |
| 61 | 3. If your branch is _tracking_ (in the `git checkout --track` sense) another |
| 62 | one (like origin/master), calls to `git cl upload` will diff against that |
| 63 | branch by default. (You can still pass arguments to `git diff` on the |
| 64 | command line, if necessary.) |
| 65 | |
| 66 | In the common case, this means that calling simply `git cl upload` will always |
| 67 | upload the correct diff to the correct place. |
| 68 | |
| 69 | |
| 70 | ## Patch series |
| 71 | |
| 72 | The above is all you need to know for working on a single patch. |
| 73 | |
| 74 | Things get much more complicated when you have a series of commits that you want |
| 75 | to get reviewed. Say your history looks like O--A--B--C. If you want to upload |
| 76 | that as a single review, everything works just as above. |
| 77 | |
| 78 | But what if you upload each of A, B, and C as separate reviews? What if you |
| 79 | then need to change A? |
| 80 | |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 81 | 1. One option is rewriting history: write a new commit A', then use |
| 82 | `git rebase -i` to insert that diff in as O--A--A'--B--C as well as squash |
| 83 | it. This is sometimes not possible if B and C have touched some lines |
| 84 | affected by A'. |
maruel | 9e198a8 | 2016-08-11 15:32:19 | [diff] [blame] | 85 | 2. Another option, and the one espoused by software like topgit, is for you to |
| 86 | have separate branches for A, B, and C, and after writing A' you merge it |
| 87 | into each of those branches. (topgit automates this merging process.) This |
| 88 | is also what is recommended by git-cl, which likes having different branch |
| 89 | identifiers to hang the issue number off of. Your history ends up looking |
| 90 | like: |
| 91 | |
| 92 | O---A---B---C |
| 93 | \ \ \ |
| 94 | A'--B'--C' |
| 95 | |
| 96 | Which is ugly, but it accurately tracks the real history of your work, can be |
| 97 | thrown away at the end by committing A+A' as a single `squash` commit. |
| 98 | |
| 99 | In practice, this comes up pretty rarely. Suggestions for better workflows are |
| 100 | welcome. |
tandrii | e594e21 | 2016-08-22 21:18:02 | [diff] [blame] | 101 | |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 102 | ## Bash auto completion |
tandrii | e594e21 | 2016-08-22 21:18:02 | [diff] [blame] | 103 | |
| 104 | 1. Ensure that your base git commands are autocompleted |
| 105 | [doc](https://git-scm.com/book/en/v1/Git-Basics-Tips-and-Tricks). |
| 106 | 2. Add this to your .bashrc: |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 107 | |
tandrii | e594e21 | 2016-08-22 21:18:02 | [diff] [blame] | 108 | # The next line enables bash completion for git cl. |
| 109 | if [ -f "$HOME/bin/depot_tools/git_cl_completion.sh" ]; then |
| 110 | . "$HOME/bin/depot_tools/git_cl_completion.sh" |
| 111 | fi |
qyearsley | 274c159 | 2016-09-05 00:16:19 | [diff] [blame] | 112 | |
tandrii | e594e21 | 2016-08-22 21:18:02 | [diff] [blame] | 113 | 3. Profit. |