blob: 9576c4bc4bf44d403922739525c37f1335f5a0bd [file] [log] [blame] [view]
andybons22afb312015-08-31 02:24:511# Git Tips
andybons3322f762015-08-24 21:37:092
andybons22afb312015-08-31 02:24:513When using Git, there are a few tips that are particularly useful when working
4on the Chromium codebase, especially due to its size.
andybons3322f762015-08-24 21:37:095
andybons22afb312015-08-31 02:24:516[TOC]
7
8## Remember the basic git convention:
9
10 git COMMAND [FLAGS] [ARGUMENTS]
11
12Various git commands have underlying executable with a hyphenated name, such as
13`git-grep`, but these can also be called via the `git` wrapper script as
14`git grep` (and `man` should work either way too).
andybons3322f762015-08-24 21:37:0915
16## Git references
17
18The following resources can provide background on how Git works:
19
andybons22afb312015-08-31 02:24:5120* [Git-SVN Crash Course](http://git-scm.com/course/svn.html) -- this crash
21 course is useful for Subversion users witching to Git.
22* [Think Like (a) Git](http://think-like-a-git.net/) -- does a great job of
23 explaining the main purpose of Git operations.
24* [Git User's Manual](http://schacon.github.com/git/user-manual.html) -- a
25 great resource to learn more about ho to use Git properly.
26* [A Visual Git Reference](http://marklodato.github.com/visual-git-guide/index-en.html)
27 -- a resource that explains various Git operations for visual reasons.
28* [Git Cheat Sheet](http://cheat.errtheblog.com/s/git) -- now that you
29 understand Git, here's a cheat sheet to quickly remind you of all the
30 commands you need.
andybons3322f762015-08-24 21:37:0931
32## Committing changes
andybons3322f762015-08-24 21:37:0933
andybons22afb312015-08-31 02:24:5134For a simple workflow (always commit all changed files, don't keep local
35revisions), the following script handles check; you may wish to call it `gci`
36(git commit) or similar.
37
38Amending a single revision is generally easier for various reasons, notably for
39rebasing and for checking that CLs have been committed. However, if you don't
40use local revisions (a local branch with multiple revisions), you should make
41sure to upload revisions periodically to code review if you ever need to go to
42an old version of a CL.
43
44```bash
andybons3322f762015-08-24 21:37:0945#!/bin/bash
46# Commit all, amending if not initial commit.
47if git status | grep -q "# Your branch is ahead of 'master' by 1 commit."
48then
49 git commit --all --amend
50else
51 git commit --all # initial, not amendment
52fi
53```
54
55## Listing and changing branches
andybons22afb312015-08-31 02:24:5156
57```shell
andybons3322f762015-08-24 21:37:0958git branch # list branches
59git checkout - # change to last branch
60```
andybons22afb312015-08-31 02:24:5161
62To quickly list the 5 most recent branches, add the following to `.gitconfig`
63in the `[alias]` section:
64
65```shell
66last5 = "!git for-each-ref --sort=committerdate refs/heads/ \
67 --format='%(committerdate:short) %(refname:short)' | tail -5 | cut -c 12-"
andybons3322f762015-08-24 21:37:0968```
69
andybons22afb312015-08-31 02:24:5170A nicely color-coded list, sorted in descending order by date, can be made by
71the following bash function:
72
73```bash
andybons3322f762015-08-24 21:37:0974git-list-branches-by-date() {
75 local current_branch=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD)
76 local normal_text=$(echo -ne '\E[0m')
77 local yellow_text=$(echo -ne '\E[0;33m')
78 local yellow_bg=$(echo -ne '\E[7;33m')
79 git for-each-ref --sort=-committerdate \
andybons22afb312015-08-31 02:24:5180 --format=$' %(refname:short) \
81 \t%(committerdate:short)\t%(authorname)\t%(objectname:short)' \
82 refs/heads \
andybons3322f762015-08-24 21:37:0983 | column -t -s $'\t' -n \
84 | sed -E "s:^ (${current_branch}) :* ${yellow_bg}\1${normal_text} :" \
85 | sed -E "s:^ ([^ ]+): ${yellow_text}\1${normal_text}:"
86}
87```
88
89## Searching
andybons3322f762015-08-24 21:37:0990
andybons22afb312015-08-31 02:24:5191Use `git-grep` instead of `grep` and `git-ls-files` instead of `find`, as these
92search only files in the index or _tracked_ files in the work tree, rather than
93all files in the work tree.
94
95Note that `git-ls-files` is rather simpler than `find`, so you'll often need to
96use `xargs` instead of `-exec` if you want to process matching files.
andybons3322f762015-08-24 21:37:0997
98## Global changes
andybons3322f762015-08-24 21:37:0999
andybons22afb312015-08-31 02:24:51100To make global changes across the source tree, it's often easiest to use `sed`
101with `git-ls-files`, using `-i` for in-place changing (this is generally safe,
102as we don't use symlinks much, but there are few places that do). Remember that
103you don't need to use `xargs`, since sed can take multiple input files. E.g., to
104strip trailing whitespace from C++ and header files:
andybons3322f762015-08-24 21:37:09105
andybons22afb312015-08-31 02:24:51106 sed -i -E 's/\s+$//' $(git ls-files '*.cpp' '*.h')
107
108
109You may also find `git-grep` useful for limiting the scope of your changes,
110using `-l` for listing files.
111
112 sed -i -E '...' $(git grep -lw Foo '*.cpp' '*.h')
113
114Remember that you can restrict sed actions to matching (or non-matching) lines.
115For example, to skip lines with a line comment, use the following:
116
117 '\,//, ! s/foo/bar/g'
118
andybons3322f762015-08-24 21:37:09119## Diffs
andybons22afb312015-08-31 02:24:51120
121 git diff --shortstat
122
andybons3322f762015-08-24 21:37:09123Displays summary statistics, such as:
andybons22afb312015-08-31 02:24:51124
125 2104 files changed, 9309 insertions(+), 9309 deletions(-)