When using Git, there are a few tips that are particularly useful when working on the Chromium codebase, especially due to its size.
git COMMAND [FLAGS] [ARGUMENTS]
Various git commands have underlying executable with a hyphenated name, such as git-grep
, but these can also be called via the git
wrapper script as git grep
(and man
should work either way too).
The following resources can provide background on how Git works:
For a simple workflow (always commit all changed files, don't keep local revisions), the following script handles check; you may wish to call it gci
(git commit) or similar.
Amending a single revision is generally easier for various reasons, notably for rebasing and for checking that CLs have been committed. However, if you don't use local revisions (a local branch with multiple revisions), you should make sure to upload revisions periodically to code review if you ever need to go to an old version of a CL.
#!/bin/bash # Commit all, amending if not initial commit. if git status | grep -q "# Your branch is ahead of 'master' by 1 commit." then git commit --all --amend else git commit --all # initial, not amendment fi
git branch # list branches git checkout - # change to last branch
To quickly list the 5 most recent branches, add the following to .gitconfig
in the [alias]
section:
last5 = "!git for-each-ref --sort=committerdate refs/heads/ \ --format='%(committerdate:short) %(refname:short)' | tail -5 | cut -c 12-"
A nicely color-coded list, sorted in descending order by date, can be made by the following bash function:
git-list-branches-by-date() { local current_branch=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD) local normal_text=$(echo -ne '\E[0m') local yellow_text=$(echo -ne '\E[0;33m') local yellow_bg=$(echo -ne '\E[7;33m') git for-each-ref --sort=-committerdate \ --format=$' %(refname:short) \ \t%(committerdate:short)\t%(authorname)\t%(objectname:short)' \ refs/heads \ | column -t -s $'\t' -n \ | sed -E "s:^ (${current_branch}) :* ${yellow_bg}\1${normal_text} :" \ | sed -E "s:^ ([^ ]+): ${yellow_text}\1${normal_text}:" }
Use git-grep
instead of grep
and git-ls-files
instead of find
, as these search only files in the index or tracked files in the work tree, rather than all files in the work tree.
Note that git-ls-files
is rather simpler than find
, so you'll often need to use xargs
instead of -exec
if you want to process matching files.
To make global changes across the source tree, it‘s often easiest to use sed
with git-ls-files
, using -i
for in-place changing (this is generally safe, as we don’t use symlinks much, but there are few places that do). Remember that you don't need to use xargs
, since sed can take multiple input files. E.g., to strip trailing whitespace from C++ and header files:
sed -i -E 's/\s+$//' $(git ls-files '*.cpp' '*.h')
You may also find git-grep
useful for limiting the scope of your changes, using -l
for listing files.
sed -i -E '...' $(git grep -lw Foo '*.cpp' '*.h')
Remember that you can restrict sed actions to matching (or non-matching) lines. For example, to skip lines with a line comment, use the following:
'\,//, ! s/foo/bar/g'
git diff --shortstat
Displays summary statistics, such as:
2104 files changed, 9309 insertions(+), 9309 deletions(-)