[NFC] Trim trailing whitespace in *.rst
[platform/upstream/llvm.git] / llvm / docs / GitBisecting.rst
1 ===================
2 Bisecting LLVM code
3 ===================
4
5 Introduction
6 ============
7
8 ``git bisect`` is a useful tool for finding which revision caused a bug.
9
10 This document describes how to use ``git bisect``. In particular, while LLVM
11 has a mostly linear history, it has a few merge commits that added projects --
12 and these merged the linear history of those projects. As a consequence, the
13 LLVM repository has multiple roots: One "normal" root, and then one for each
14 toplevel project that was developed out-of-tree and then merged later.
15 As of early 2020, the only such merged project is MLIR, but flang will likely
16 be merged in a similar way soon.
17
18 Basic operation
19 ===============
20
21 See https://git-scm.com/docs/git-bisect for a good overview. In summary:
22
23   .. code-block:: bash
24
25      git bisect start
26      git bisect bad main
27      git bisect good f00ba
28
29 git will check out a revision in between. Try to reproduce your problem at
30 that revision, and run ``git bisect good`` or ``git bisect bad``.
31
32 If you can't repro at the current commit (maybe the build is broken), run
33 ``git bisect skip`` and git will pick a nearby alternate commit.
34
35 (To abort a bisect, run ``git bisect reset``, and if git complains about not
36 being able to reset, do the usual ``git checkout -f main; git reset --hard
37 origin/main`` dance and try again).
38
39 ``git bisect run``
40 ==================
41
42 A single bisect step often requires first building clang, and then compiling
43 a large code base with just-built clang. This can take a long time, so it's
44 good if it can happen completely automatically. ``git bisect run`` can do
45 this for you if you write a run script that reproduces the problem
46 automatically. Writing the script can take 10-20 minutes, but it's almost
47 always worth it -- you can do something else while the bisect runs (such
48 as writing this document).
49
50 Here's an example run script. It assumes that you're in ``llvm-project`` and
51 that you have a sibling ``llvm-build-project`` build directory where you
52 configured CMake to use Ninja. You have a file ``repro.c`` in the current
53 directory that makes clang crash at trunk, but it worked fine at revision
54 ``f00ba``.
55
56   .. code-block:: bash
57
58      # Build clang. If the build fails, `exit 125` causes this
59      # revision to be skipped
60      ninja -C ../llvm-build-project clang || exit 125
61
62      ../llvm-build-project/bin/clang repro.c
63
64 To make sure your run script works, it's a good idea to run ``./run.sh`` by
65 hand and tweak the script until it works, then run ``git bisect good`` or
66 ``git bisect bad`` manually once based on the result of the script
67 (check ``echo $?`` after your script ran), and only then run ``git bisect run
68 ./run.sh``. Don't forget to mark your run script as executable -- ``git bisect
69 run`` doesn't check for that, it just assumes the run script failed each time.
70
71 Once your run script works, run ``git bisect run ./run.sh`` and a few hours
72 later you'll know which commit caused the regression.
73
74 (This is a very simple run script. Often, you want to use just-built clang
75 to build a different project and then run a built executable of that project
76 in the run script.)
77
78 Bisecting across multiple roots
79 ===============================
80
81 Here's how LLVM's history currently looks:
82
83   .. code-block:: none
84
85      A-o-o-......-o-D-o-o-HEAD
86                    /
87        B-o-...-o-C-
88
89 ``A`` is the first commit in LLVM ever, ``97724f18c79c``.
90
91 ``B`` is the first commit in MLIR, ``aed0d21a62db``.
92
93 ``D`` is the merge commit that merged MLIR into the main LLVM repository,
94 ``0f0d0ed1c78f``.
95
96 ``C`` is the last commit in MLIR before it got merged, ``0f0d0ed1c78f^2``. (The
97 ``^n`` modifier selects the n'th parent of a merge commit.)
98
99 ``git bisect`` goes through all parent revisions. Due to the way MLIR was
100 merged, at every revision at ``C`` or earlier, *only* the ``mlir/`` directory
101 exists, and nothing else does.
102
103 As of early 2020, there is no flag to ``git bisect`` to tell it to not
104 descend into all reachable commits. Ideally, we'd want to tell it to only
105 follow the first parent of ``D``.
106
107 The best workaround is to pass a list of directories to ``git bisect``:
108 If you know the bug is due to a change in llvm, clang, or compiler-rt, use
109
110   .. code-block:: bash
111
112      git bisect start -- clang llvm compiler-rt
113
114 That way, the commits in ``mlir`` are never evaluated.
115
116 Alternatively, ``git bisect skip aed0d21a6 aed0d21a6..0f0d0ed1c78f`` explicitly
117 skips all commits on that branch. It takes 1.5 minutes to run on a fast
118 machine, and makes ``git bisect log`` output unreadable. (``aed0d21a6`` is
119 listed twice because git ranges exclude the revision listed on the left,
120 so it needs to be ignored explicitly.)
121
122 More Resources
123 ==============
124
125 https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection