1Productivity Notes 2================== 3 4Table of Contents 5----------------- 6 7* [General](#general) 8 * [Cache compilations with `ccache`](#cache-compilations-with-ccache) 9 * [Disable features with `./configure`](#disable-features-with-configure) 10 * [Make use of your threads with `make -j`](#make-use-of-your-threads-with-make--j) 11 * [Multiple working directories with `git worktrees`](#multiple-working-directories-with-git-worktrees) 12* [Writing code](#writing-code) 13 * [Format C/C++/Protobuf diffs with `clang-format-diff.py`](#format-ccprotobuf-diffs-with-clang-format-diffpy) 14 * [Format Python diffs with `yapf-diff.py`](#format-python-diffs-with-yapf-diffpy) 15* [Rebasing/Merging code](#rebasingmerging-code) 16 * [More conflict context with `merge.conflictstyle diff3`](#more-conflict-context-with-mergeconflictstyle-diff3) 17* [Reviewing code](#reviewing-code) 18 * [Reduce mental load with `git diff` options](#reduce-mental-load-with-git-diff-options) 19 * [Reference PRs easily with `refspec`s](#reference-prs-easily-with-refspecs) 20 * [Diff the diffs with `git range-diff`](#diff-the-diffs-with-git-range-diff) 21 22General 23------ 24 25### Cache compilations with `ccache` 26 27The easiest way to faster compile times is to cache compiles. `ccache` is a way to do so, from its description at the time of writing: 28 29> ccache is a compiler cache. It speeds up recompilation by caching the result of previous compilations and detecting when the same compilation is being done again. Supported languages are C, C++, Objective-C and Objective-C++. 30 31Install `ccache` through your distribution's package manager, and run `./configure` with your normal flags to pick it up. 32 33To use ccache for all your C/C++ projects, follow the symlinks method [here](https://ccache.samba.org/manual/latest.html#_run_modes) to set it up. 34 35### Disable features with `./configure` 36 37After running `./autogen.sh`, which generates the `./configure` file, use `./configure --help` to identify features that you can disable to save on compilation time. A few common flags: 38 39```sh 40--without-miniupnpc 41--disable-bench 42--disable-wallet 43--without-gui 44``` 45 46### Make use of your threads with `make -j` 47 48If you have multiple threads on your machine, you can tell `make` to utilize all of them with: 49 50```sh 51make -j"$(($(nproc)+1))" 52``` 53 54### Multiple working directories with `git worktrees` 55 56If you work with multiple branches or multiple copies of the repository, you should try `git worktrees`. 57 58To create a new branch that lives under a new working directory without disrupting your current working directory (useful for creating pull requests): 59```sh 60git worktree add -b my-shiny-new-branch ../living-at-my-new-working-directory based-on-my-crufty-old-commit-ish 61``` 62 63To simply check out a commit-ish under a new working directory without disrupting your current working directory (useful for reviewing pull requests): 64```sh 65git worktree add --checkout ../where-my-checkout-commit-ish-will-live my-checkout-commit-ish 66``` 67 68----- 69 70This synergizes well with [`ccache`](#cache-compilations-with-ccache) as objects resulting from unchanged code will most likely hit the cache and won't need to be recompiled. 71 72You can also set up [upstream refspecs](#reference-prs-easily-with-refspecs) to refer to pull requests easier in the above `git worktree` commands. 73 74Writing code 75------------ 76 77### Format C/C++/Protobuf diffs with `clang-format-diff.py` 78 79See [contrib/devtools/README.md](contrib/devtools/README.md#clang-format-diff.py). 80 81### Format Python diffs with `yapf-diff.py` 82 83Usage is exactly the same as [`clang-format-diff.py`](#format-ccprotobuf-diffs-with-clang-format-diffpy). You can get it [here](https://github.com/MarcoFalke/yapf-diff). 84 85Rebasing/Merging code 86------------- 87 88### More conflict context with `merge.conflictstyle diff3` 89 90For resolving merge/rebase conflicts, it can be useful to enable diff3 style using `git config merge.conflictstyle diff3`. Instead of 91 92```diff 93<<< 94yours 95=== 96theirs 97>>> 98``` 99 100 you will see 101 102```diff 103<<< 104yours 105||| 106original 107=== 108theirs 109>>> 110``` 111 112This may make it much clearer what caused the conflict. In this style, you can often just look at what changed between *original* and *theirs*, and mechanically apply that to *yours* (or the other way around). 113 114Reviewing code 115-------------- 116 117### Reduce mental load with `git diff` options 118 119When reviewing patches which change indentation in C++ files, use `git diff -w` and `git show -w`. This makes the diff algorithm ignore whitespace changes. This feature is also available on github.com, by adding `?w=1` at the end of any URL which shows a diff. 120 121When reviewing patches that change symbol names in many places, use `git diff --word-diff`. This will instead of showing the patch as deleted/added *lines*, show deleted/added *words*. 122 123When reviewing patches that move code around, try using `git diff --patience commit~:old/file.cpp commit:new/file/name.cpp`, and ignoring everything except the moved body of code which should show up as neither `+` or `-` lines. In case it was not a pure move, this may even work when combined with the `-w` or `--word-diff` options described above. `--color-moved=dimmed-zebra` will also dim the coloring of moved hunks in the diff on compatible terminals. 124 125### Reference PRs easily with `refspec`s 126 127When looking at other's pull requests, it may make sense to add the following section to your `.git/config` file: 128 129``` 130[remote "upstream-pull"] 131 fetch = +refs/pull/*:refs/remotes/upstream-pull/* 132 url = git@github.com:litecoin-project/litecoin.git 133``` 134 135This will add an `upstream-pull` remote to your git repository, which can be fetched using `git fetch --all` or `git fetch upstream-pull`. Afterwards, you can use `upstream-pull/NUMBER/head` in arguments to `git show`, `git checkout` and anywhere a commit id would be acceptable to see the changes from pull request NUMBER. 136 137### Diff the diffs with `git range-diff` 138 139It is very common for contributors to rebase their pull requests, or make changes to commits (perhaps in response to review) that are not at the head of their branch. This poses a problem for reviewers as when the contributor force pushes, the reviewer is no longer sure that his previous reviews of commits are still valid (as the commit hashes can now be different even though the diff is semantically the same). `git range-diff` can help solve this problem by diffing the diffs. 140 141For example, to identify the differences between your previously reviewed diffs P1-5, and the new diffs P1-2,N3-4 as illustrated below: 142``` 143 P1--P2--P3--P4--P5 <-- previously-reviewed-head 144 / 145...--m <-- master 146 \ 147 P1--P2--N3--N4--N5 <-- new-head (with P3 slightly modified) 148``` 149 150You can do: 151```sh 152git range-diff master previously-reviewed-head new-head 153``` 154 155Note that `git range-diff` also work for rebases. 156 157----- 158 159`git range-diff` also accepts normal `git diff` options, see [Reduce mental load with `git diff` options](#reduce-mental-load-with-git-diff-options) for useful `git diff` options. 160 161You can also set up [upstream refspecs](#reference-prs-easily-with-refspecs) to refer to pull requests easier in the above `git range-diff` commands. 162