blob: f479eb9a077c90b1923619752f8f9199367a2ca8 [file] [log] [blame] [view]
maruel9e198a82016-08-11 15:32:191# git-cl
2
3The git-cl README describes the git-cl command set. This document describes how
4code review and git work together in general, intended for people familiar with
5git but unfamiliar with the code review process supported by Rietveld and
6Gerrit.
7
8
qyearsley274c1592016-09-05 00:16:199## Rietveld concepts and terms
maruel9e198a82016-08-11 15:32:1910
11A Rietveld review is for discussion of a single change or patch. You upload a
12proposed change, the reviewer comments on your change, and then you can upload a
13revised version of your change. Rietveld stores the history of uploaded patches
14as well as the comments, and can compute diffs in between these patches. The
15history of a patch is very much like a small branch in git, but since Rietveld
qyearsley274c1592016-09-05 00:16:1916is VCS-agnostic, the concepts don't map perfectly. The identifier for a single
17review thread including patches and comments in Rietveld is called an **issue**.
maruel9e198a82016-08-11 15:32:1918
19Rietveld provides a basic uploader that understands git. This program is used by
20git-cl, and is included in the git-cl repo as upload.py.
21
22
23## Basic interaction with git
24
25The fundamental problem you encounter when you try to mix git and code review is
26that with git it's nice to commit code locally, while during a code review
27you're often requested to change something about your code. There are a few
28different ways you can handle this workflow with git:
29
301. 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
qyearsley274c1592016-09-05 00:16:1932 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`.)
maruel9e198a82016-08-11 15:32:19352. 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
40The Rietveld patch uploader just takes arguments to `git diff`, so either of the
41above workflows work fine. If all you want to do is upload a patch, you can use
42the upload.py provided by Rietveld with arguments like this:
43
44 upload.py --server server.com <args to "git diff">
45
46The first time you upload, it creates a new issue; for follow-ups on the same
47issue, 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
54git-cl simplifies the above in the following ways:
55
561. `git cl config` puts a persistent --server setting in your .git/config.
572. 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.)
613. 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
66In the common case, this means that calling simply `git cl upload` will always
67upload the correct diff to the correct place.
68
69
70## Patch series
71
72The above is all you need to know for working on a single patch.
73
74Things get much more complicated when you have a series of commits that you want
75to get reviewed. Say your history looks like O--A--B--C. If you want to upload
76that as a single review, everything works just as above.
77
78But what if you upload each of A, B, and C as separate reviews? What if you
79then need to change A?
80
qyearsley274c1592016-09-05 00:16:19811. 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'.
maruel9e198a82016-08-11 15:32:19852. 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
99In practice, this comes up pretty rarely. Suggestions for better workflows are
100welcome.
tandriie594e212016-08-22 21:18:02101
qyearsley274c1592016-09-05 00:16:19102## Bash auto completion
tandriie594e212016-08-22 21:18:02103
1041. Ensure that your base git commands are autocompleted
105[doc](https://git-scm.com/book/en/v1/Git-Basics-Tips-and-Tricks).
1062. Add this to your .bashrc:
qyearsley274c1592016-09-05 00:16:19107
tandriie594e212016-08-22 21:18:02108 # 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
qyearsley274c1592016-09-05 00:16:19112
tandriie594e212016-08-22 21:18:021133. Profit.