Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
git_bisect [2019/02/20 18:27] – [Overview] rpjdaygit_bisect [2019/02/26 21:54] (current) – [Bisection while ignoring feature branches] rpjday
Line 8: Line 8:
   * [[https://git-scm.com/docs/git-bisect-lk2009.html|git-bisect-lk2009]]   * [[https://git-scm.com/docs/git-bisect-lk2009.html|git-bisect-lk2009]]
  
-===== Cute features of bisection =====+===== SYNOPSIS ===== 
 + 
 +<code> 
 +git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>
 +                 [--no-checkout] [<bad> [<good>...]] [--] [<paths>...] 
 +git bisect (bad|new|<term-new>) [<rev>
 +git bisect (good|old|<term-old>) [<rev>...] 
 +git bisect terms [--term-good | --term-bad] 
 +git bisect skip [(<rev>|<range>)...] 
 +git bisect reset [<commit>
 +git bisect (visualize|view) 
 +git bisect replay <logfile> 
 +git bisect log 
 +git bisect run <cmd>... 
 +git bisect help 
 +</code> 
 + 
 +===== Basic bisection ===== 
 + 
 +==== Defining the endpoints ==== 
 + 
 +Any of the following (bad, followed by good): 
 + 
 +<code> 
 +$ git bisect start v4.20 v4.19 
 +</code> 
 + 
 +or 
 + 
 +<code> 
 +$ git bisect start 
 +$ git bisect good v4.19 
 +$ git bisect bad v4.20 
 +</code> 
 + 
 +after which you should see: 
 + 
 +<code> 
 +Bisecting: 7499 revisions left to test after this (roughly 13 steps) 
 +[ec9c166434595382be3babf266febf876327774d] Merge tag 'mips_fixes_4.20_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux 
 +</code> 
 + 
 +==== Displaying the current commit ==== 
 + 
 +At any time, examine the current commit with: 
 + 
 +<code> 
 +$ git show 
 +commit ec9c166434595382be3babf266febf876327774d (HEAD) 
 +Merge: 685f7e4f1614 c61c7def1fa0 
 +Author: Linus Torvalds <torvalds@linux-foundation.org> 
 +Date:   Fri Oct 26 14:39:22 2018 -0700 
 + 
 +    Merge tag 'mips_fixes_4.20_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux 
 +     
 +    Pull MIPS fixes from Paul Burton: 
 +     "A couple of MIPS fixes that should have ideally made it for v4.19, but 
 +      hey-ho here they are now: 
 +     
 +       - A fix for potential poor stack placement introduced in v4.19-rc8. 
 +     
 +       - A fix for a warning introduced in use of TURBOchannel devices by 
 +         DMA changes in v4.16" 
 +     
 +    * tag 'mips_fixes_4.20_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: 
 +      MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit 
 +      TC: Set DMA masks for devices 
 +</code> 
 + 
 +==== The bisection step ==== 
 + 
 +After testing the current checkout for the error, do one of: 
 + 
 +<code> 
 +$ git bisect good 
 +$ git bisect bad 
 +</code> 
 + 
 +to refine the interval containing the error. 
 + 
 +==== The end result ==== 
 + 
 +After binary search, you will end up with something like: 
 + 
 +<code> 
 +$ git bisect good 
 +130d6f946f6f2a972ee3ec8540b7243ab99abe97 is the first bad commit 
 +commit 130d6f946f6f2a972ee3ec8540b7243ab99abe97 
 +Author: Thomas Gleixner <tglx@linutronix.de> 
 +Date:   Sun Nov 25 19:33:40 2018 +0100 
 + 
 +    x86/l1tf: Show actual SMT state 
 +    ... snip ... 
 +</code> 
 + 
 +Once you're done: 
 + 
 +<code> 
 +$ git bisect reset 
 +</code> 
 +===== Advanced bisection =====
  
 ==== Alternate terms ==== ==== Alternate terms ====
Line 126: Line 226:
 This option may be useful when the test you would perform in each step does not require a checked out tree. This option may be useful when the test you would perform in each step does not require a checked out tree.
  
-===== Bisection with feature branches (WARNING: INCOMPLETE!) =====+===== Bisection while ignoring feature branches =====
  
-Rather than bisecting completely on lengthy feature branches, restrict the search to just those commits where feature branches were merged into ''master'', so the ultimate goal is to say, "//That// merged feature branch is the one that caused the problem," possibly inspiring another round of more focused bisection.+NOTE: This explanation is based on the writeup [[https://blog.smart.ly/2015/02/03/git-bisect-debugging-with-feature-branches/|here]].
  
-Firstlist //all// revisions in the range of interest (Linux kernel source used here):+If we have two commits directly on the ''master'' branchand we try to bisect using those two commits as good and bad endpoints, it's entirely possible that we could end up processing many, many, many commits based on the number of (potentially lengthyfeature branches that were merged into ''master'' between the two commits.
  
-<code> +Rather than bisecting completely on those lengthy feature branches, we can restrict the search to just those commits where feature branches were merged into ''master'', so the ultimate goal is to say, "//That// merged feature branch is the one that caused the problem," possibly inspiring another round of more focused bisection. (This also considers the possibility of a stand-alone commit directly on the ''master'' branch as well.) Let's demonstrate this using the Linux kernel source repository, defining ''v4.18'' as the good commit, and ''v4.19'' as the bad commit.
-$ git rev-list v4.14..v4.15 +
-d8a5b80568a9cb66810e75b182018e9edb68e8ff +
-24b1cccf922914f3d6eeb84036dde8338bc03abb +
-32c6cdf75c9270848d2d0ed7c814eba05b47081f +
-07b0137c0268b8d0694a5f09284449353a1a6fed +
-624441927ff6af871d793dfa49fa347c8450e250 +
-39e383626caffd2b5f4407710157b32172898869 +
-... massive snip ... +
-</code>+
  
-Just count the commits available to bisection with either of:+First, let'count the number of commits we would normally need to process if we used basic bisection based on those two endpoints:
  
 <code> <code>
-$ git rev-list v4.14..v4.15 | wc -l +$ git rev-list v4.18..v4.19 | wc -l 
-16223 +15204
-$ git rev-list ^v4.14 v4.15 | wc -l +
-16223+
 $ $
 </code> </code>
  
-Next, restrict yourself to just merge commits (which could include merges on feature branches, but we will deal with those shortly):+That's a lot of commits so let's see if we can reduce that number. The basis for ignoring all of the commits on feature branches is to generate a list of commits to //ignore//and feed that list to ''git bisect skip'' to cut down on the work. The first step is to generate a list of merge commits between the two endpoints
  
 <code> <code>
-$ git rev-list v4.14..v4.15 --merges | wc -l +$ git rev-list v4.18..v4.19 --merges | wc -l 
-1357+1161
 $ $
 </code> </code>
  
-Furtherfollow only the //first parent// commit upon seeing a merge commit (to exclude any commits on feature branchesincluding those pesky merge commits):+So there are 1161 merge commits in the testable rangebut we need to further disqualify merge commits exclusively on feature branches, so let's restrict ourselves to just the //first parents// of those merge commits, which guarantees that all of those merge commits are on the ''master'' branch:
  
 <code> <code>
-$ git rev-list v4.14..v4.15 --merges --first-parent | wc -l +$ git rev-list v4.18..v4.19 --merges --first-parent | wc -l 
-435+426
 $ $
 </code> </code>
  
-The above set of commits represents the merge commits on ''master'' we would like to bisectbut we need to use them as the basis to identify the commits on each feature branch we want to //skip// so let's wrap that command in a loop in preparation:+What the above set of merge commits represents are those merge commits for which we want to totally ignore all commits on the feature branch that contributed to each of those commits. For each merge commit above (call it ''rev''), we list all commits reachable from the second parent (the one on the feature branch, ''rev^2''), but not reachable from the parent on the master branch (''rev^''), and pass //all// such commits to ''git bisect skip''.
  
 <code> <code>
-for rev in $(git rev-list v4.14..v4.15 --merges --first-parent) ; do +for rev in $(git rev-list v4.18..v4.19 --merges --first-parent); do 
-> echo ${rev} +  git rev-list $rev^2 --not $rev^ 
-done | wc -l +done | xargs git bisect skip
-435 +
-$+
 </code> </code>
  
-Now, for each merge commit on ''master'' being represented by ''rev'' above, we need to use ''git rev-list'' to generate the list of commits we want to skip from the bisection, and those would be the commits exclusively on the feature branch being merged, which are those commits reachable in each case from the //second// parent of ''rev'' (the feature branch), but not the //first// parent:+Given that our basic search would have processed 15204 commits, we can count how many commits will now be pruned from the bisection:
  
 <code> <code>
-git rev-list ${rev}^2 ^${rev}^+for rev in $(git rev-list v4.18..v4.19 --merges --first-parent); do 
 +  git rev-list $rev^2 --not $rev^ 
 +done | sort | uniq | wc -l 
 +14714 
 +$
 </code> </code>
  • git_bisect.1550687278.txt.gz
  • Last modified: 2019/02/20 18:27
  • by rpjday