开发者

Using git to find first introduction of token on a specific line of a file

Let's say I have a file A.cpp, and I notice an error on line 15 of the file. Let's say the error is a "const" on a function that returns a pointer to a member variable, meaning using const on the function is technically correct but semantically wrong. I would like to discuss the semantics with the author who made the change.

Using git, is there a way to find out which revision introduced the "const" token? More specifically, I'd like to know who introduced the token.

"git blame" shows who made the last change to the line, but I would actually like开发者_C百科 to find the first commit containing the token.


There are a few possible ways of doing it.

  • git blame, or better graphical blame tool (like git gui blame or the blame view in git instaweb / gitweb) to browse history of a line, going back in history until you find appropriate commit.

  • so called "pickaxe search", i.e. git log -S with appropriate token / regexp, to find (list) all commits where number of given tokens changed (which usually means where given token was added or deleted), e.g.:

    git log --reverse -p -S'const int foobar' -- A.cpp
    
  • git bisect where "bad" commit would mean the one with 'const' where there it shouldn't be (testing using e.g. grep).


git bisect is what you are looking for. With this command you can find quickly what commit introduced the const.

You start the process with git bisect start, then mark an old version without the const as good with git bisect good and and the current one as bisect bad. Then the system will send you to a version in the middle. You can check if the evil const is there, and mark that version good or bad depending on it. Then The process is repeated until you find the bad commit.


The change may not have always been on line 15 of A.cpp, so use the surrounding context. Say it was a definition of const int foobar:

git grep 'const *int *foobar' \
  $(git log --reverse --pretty=format:%H -- A.cpp) -- \
  A.cpp | head -1

This searches forward in time through all commits on the current branch that touch A.cpp and finds the first one that contains the offending pattern. The output will be the commit's SHA-1 and the matching line in its revision of A.cpp.

Once you know the commit, use git show to learn the author.


If the line existed without the const token in some commit that you know, you can start there and use the --reverse flag on git-blame to find the last revision in which the line didn't have the const token. Then just look at the next revision on the file after that.


I use QGit for this, select the lines of interest, and filter on that, then you see only the list of change for that line. For a single line it's not to had to jump around a few revisions.

via:

  • open QGit on repository
  • open Tree view
  • find file
  • find line
  • select line of interest
  • press 'filter revision of selected lines' button, looks like a funnel.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜