blob: b12419d77761c9c95ca2dfaed015115f6411942e [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
boushleyc9e974922017-03-31 20:20:4121 course is useful for Subversion users switching to Git.
andybons22afb312015-08-31 02:24:5122* [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.
Ernesto Izquierdo Clua8fed53e2023-05-09 16:34:2526* [A Visual Git Reference](https://marklodato.github.io/visual-git-guide/index-en.html)
boushleyc9e974922017-03-31 20:20:4127 -- a resource that explains various Git operations for visual learners.
andybons22afb312015-08-31 02:24:5128* [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
Hong Xu747ba9f2023-07-22 00:14:1132## Optimizing (Speeding up) Git for a Large Repository
33
34Git has numerous options, among which some are intended to optimize for large
35repositories.
36[feature.manyFiles](https://git-scm.com/docs/git-config#Documentation/git-config.txt-featuremanyFiles)
37is a convenient option that turns on the group of options that optimize for
38large repositories. Run the following inside the Chromium git repository:
39
40 git config feature.manyFiles true
41
Colin Blundell4fcadea2017-06-13 14:44:1742## Configuring the output of "git log"
43
44By default, the date that "git log" displays is the "author date." In Chromium,
45this generally corresponds to the date that the committed patch was last
46uploaded. In most cases, however, the date that is of interest is the date that
47the patch was committed in the tree. To configure "git log" to instead display
48the latter date for your Chromium checkout, execute the following command:
49
50```shell
51git config format.pretty 'format:%C(auto,yellow)commit %H%C(auto)%d%nAuthor: %an <%ae>%nCommitted: %cd%n%n%w(0,4,4)%B%-%n'
52```
53
54If you want to change *all* your repos (e.g., because you have multiple Chromium
55checkouts and don't care about having the default for other repos), add
56"--global" after "config" in the above command.
57
andybons3322f762015-08-24 21:37:0958## Committing changes
andybons3322f762015-08-24 21:37:0959
andybons22afb312015-08-31 02:24:5160For a simple workflow (always commit all changed files, don't keep local
61revisions), the following script handles check; you may wish to call it `gci`
62(git commit) or similar.
63
64Amending a single revision is generally easier for various reasons, notably for
65rebasing and for checking that CLs have been committed. However, if you don't
66use local revisions (a local branch with multiple revisions), you should make
67sure to upload revisions periodically to code review if you ever need to go to
68an old version of a CL.
69
70```bash
andybons3322f762015-08-24 21:37:0971#!/bin/bash
72# Commit all, amending if not initial commit.
Andrew Williamsbbc1a1e2021-07-21 01:51:2273if git status | grep -q "Your branch is ahead of 'origin/main' by 1 commit."
andybons3322f762015-08-24 21:37:0974then
75 git commit --all --amend
76else
77 git commit --all # initial, not amendment
78fi
79```
80
81## Listing and changing branches
andybons22afb312015-08-31 02:24:5182
83```shell
andybons3322f762015-08-24 21:37:0984git branch # list branches
85git checkout - # change to last branch
86```
andybons22afb312015-08-31 02:24:5187
88To quickly list the 5 most recent branches, add the following to `.gitconfig`
89in the `[alias]` section:
90
91```shell
92last5 = "!git for-each-ref --sort=committerdate refs/heads/ \
93 --format='%(committerdate:short) %(refname:short)' | tail -5 | cut -c 12-"
andybons3322f762015-08-24 21:37:0994```
95
andybons22afb312015-08-31 02:24:5196A nicely color-coded list, sorted in descending order by date, can be made by
97the following bash function:
98
99```bash
andybons3322f762015-08-24 21:37:09100git-list-branches-by-date() {
101 local current_branch=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD)
102 local normal_text=$(echo -ne '\E[0m')
103 local yellow_text=$(echo -ne '\E[0;33m')
104 local yellow_bg=$(echo -ne '\E[7;33m')
105 git for-each-ref --sort=-committerdate \
andybons22afb312015-08-31 02:24:51106 --format=$' %(refname:short) \
107 \t%(committerdate:short)\t%(authorname)\t%(objectname:short)' \
108 refs/heads \
andybons3322f762015-08-24 21:37:09109 | column -t -s $'\t' -n \
110 | sed -E "s:^ (${current_branch}) :* ${yellow_bg}\1${normal_text} :" \
111 | sed -E "s:^ ([^ ]+): ${yellow_text}\1${normal_text}:"
112}
113```
114
115## Searching
andybons3322f762015-08-24 21:37:09116
andybons22afb312015-08-31 02:24:51117Use `git-grep` instead of `grep` and `git-ls-files` instead of `find`, as these
118search only files in the index or _tracked_ files in the work tree, rather than
119all files in the work tree.
120
121Note that `git-ls-files` is rather simpler than `find`, so you'll often need to
122use `xargs` instead of `-exec` if you want to process matching files.
andybons3322f762015-08-24 21:37:09123
124## Global changes
andybons3322f762015-08-24 21:37:09125
andybons22afb312015-08-31 02:24:51126To make global changes across the source tree, it's often easiest to use `sed`
127with `git-ls-files`, using `-i` for in-place changing (this is generally safe,
128as we don't use symlinks much, but there are few places that do). Remember that
129you don't need to use `xargs`, since sed can take multiple input files. E.g., to
130strip trailing whitespace from C++ and header files:
andybons3322f762015-08-24 21:37:09131
andybons22afb312015-08-31 02:24:51132 sed -i -E 's/\s+$//' $(git ls-files '*.cpp' '*.h')
133
134
135You may also find `git-grep` useful for limiting the scope of your changes,
136using `-l` for listing files.
137
138 sed -i -E '...' $(git grep -lw Foo '*.cpp' '*.h')
139
140Remember that you can restrict sed actions to matching (or non-matching) lines.
141For example, to skip lines with a line comment, use the following:
142
143 '\,//, ! s/foo/bar/g'
144
andybons3322f762015-08-24 21:37:09145## Diffs
andybons22afb312015-08-31 02:24:51146
147 git diff --shortstat
148
andybons3322f762015-08-24 21:37:09149Displays summary statistics, such as:
andybons22afb312015-08-31 02:24:51150
151 2104 files changed, 9309 insertions(+), 9309 deletions(-)