There is one not so well known feature of Git called git-bisect which can help you with finding commits that introduced specific changes in the repository. It is usually described as a way to find bugs, but we can easily extend the description, because you can search for many other things, e.g. you can search for a commit where a certain feature was implemented, where dependencies were changed or for a commit that broke the build.
Git-bisect uses binary search to help you reduce the number of commits that have to be checked. First, you start by typing
git bisect start. Then you provide Git with two commits: one called bad and one called good. Bad commit is the commit where the change is already introduced (this terminology refers to bugs, hence it is called bad commit) and good commit is older commit where the specific change is not present yet.
git bisect start
git bisect good bb992dc2d210d105156e56b80adb920185dcb2a1
git bisect bad 829964a059669334f9c7674170987ded74db42d5
If you don’t specify the version, current version will be used. After that, Git will checkout commits between these two (every time cutting the interval in half) and ask you to check if it is good or bad. Then it is up to you to see whether presented version of the repository contains the feature or bug that you are looking for. When you are ready, write
git bisect good or
git bisect bad. Based on your description, Git will pick next commit that has to be checked. If you can’t or you don’t want to check current revision, type
git bisect skip.
Repeat the process until search is over. At the end, Git will tell you the commit that was the first one to introduce the change. Use
git bisect reset to reset the repository to the previous state.
Although using git-bisect like this is useful, the real power comes with
git bisect run, which can search the repository automatically. You just need to provide a script that will decide whether certain revision is good or bad. You can find more information in the git-bisect documentation.