@@ -694,3 +694,65 @@ Multiple Logs at a Time
694694Note, you can also turn on more than one log at a time as well, e.x.::
695695
696696 (lldb) log enable -f /tmp/lldb-types-log.txt lldb types expression
697+
698+ Using git-bisect in the presence of branch forwarding/feature branches
699+ ======================================================================
700+
701+ ``git-bisect `` is a useful tool for finding where a regression was
702+ introduced. Sadly ``git-bisect `` does not handle long lived branches
703+ and will in fact choose commits from upstream branches that may be
704+ missing important content from the downstream branch. As an example,
705+ consider a situation where one has the following straw man commit flow
706+ graph::
707+
708+ github/master -> github/tensorflow
709+
710+ In this case if one attempts to use ``git-bisect `` on
711+ github/tensorflow, ``git-bisect `` will sometimes choose commits from
712+ github/master resulting in one being unable to compile/test specific
713+ tensorflow code that has not been upstreamed yet. Even worse, what if
714+ we are trying to bisect in between two that were branched from
715+ github/tensorflow and have had subsequent commits cherry-picked on
716+ top. Without any loss of generality, lets call those two tags
717+ ``tag-tensorflow-bad `` and ``tag-tensorflow-good ``. Since both of
718+ these tags have had commits cherry-picked on top, they are technically
719+ not even on the github/tensorflow branch, but rather in a certain
720+ sense are a tag of a feature branch from master/tensorflow. So,
721+ ``git-bisect `` doesn't even have a clear history to bisect on in
722+ multiple ways.
723+
724+ With those constraints in mind, we can bisect! We just need to be
725+ careful how we do it. Lets assume that we have a test script called
726+ ``test.sh `` that indicates error by the error code. With that in hand,
727+ we need to compute the least common ancestor of the good/bad
728+ commits. This is traditionally called the "merge base" of the
729+ commits. We can compute this as so::
730+
731+ TAG_MERGE_BASE=$(git merge-base tags/tag-tensorflow-bad tags/tag-tensorflow-good)
732+
733+ Given that both tags were taken from the feature branch, the reader
734+ can prove to themselves that this commit is guaranteed to be on
735+ ``github/tensorflow `` and not ``github/master `` since all commits from
736+ ``github/master `` are forwarded using git merges.
737+
738+ Then lets assume that we checked out ``$TAG_MERGE_BASE `` and then ran
739+ ``test.sh `` and did not hit any error. Ok, we can not bisect. Sadly,
740+ as mentioned above if we run git-bisect in between ``$TAG_MERGE_BASE ``
741+ and ``tags/tag-tensorflow-bad ``, ``git-bisect `` will sometimes choose
742+ commits from ``github/master `` which would cause ``test.sh `` to fail
743+ if we are testing tensorflow specific code! To work around this
744+ problem, we need to start our bisect and then tell ``git-bisect `` to
745+ ignore those commits by using the skip sub command::
746+
747+ git bisect start tags/tag-tensorflow-bad $TAG_MERGE_BASE
748+ for rev in $(git rev-list $TAG_MERGE_BASE..tags/tag-tensorflow-bad --merges --first-parent); do
749+ git rev-list $rev^2 --not $rev^
750+ done | xargs git bisect skip
751+
752+ Once this has been done, one uses ``git-bisect `` normally. One thing
753+ to be aware of is that ``git-bisect `` will return a good/bad commits
754+ on the feature branch and if one of those commits is a merge from the
755+ upstream branch, one will need to analyze the range of commits from
756+ upstream for the bad commit afterwards. The commit range in the merge
757+ should be relatively small though compared with the large git history
758+ one just bisected.
0 commit comments