Git:查找已删除的代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1528513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:10:51  来源:igfitidea点击:

Git: Find deleted code

git

提问by Ivan

This is making me nuts.

这让我发疯。

How do I find code that was deleted?

如何找到被删除的代码?

I ended up finding where it was created with this:

我最终找到了它的创建位置:

$ git log --pretty=oneline -S'some code'

And that's good enough, but I was also curious to find where it got deleted, and so far, no dice.

这已经足够了,但我也很想知道它在哪里被删除了,到目前为止,没有骰子。

First, I tried git diff HEAD..HEAD^|grep 'some code', expanding the range each time, until I found the lines where it was removed. Nice, so suppose I found it on range HEAD^^..HEAD^^^, then I do git show HEAD^^^and git show HEAD^^with grep, but the code is nowhere to be found!

首先,我尝试了git diff HEAD..HEAD^|grep 'some code',每次都扩大范围,直到找到被删除的行。尼斯,所以假设我发现它的范围HEAD^^..HEAD^^^,然后我做的git show HEAD^^^git show HEAD^^grep,但代码是无处可寻!

Then I read up a bit on git bisect, and sure enough, it gives me a single revision where the culprit is supposed to be... Again, git show rev|grep 'some code'comes up empty...

然后我读了一点git bisect,果然,它给了我一个修订版,罪魁祸首应该是......再次,git show rev|grep 'some code'空洞......

What the? What am I doing wrong?

什么?我究竟做错了什么?

Thanks!

谢谢!

采纳答案by Pat Notz

Hmph, works for me:

哼,对我有用:

$ git init
Initialized empty Git repository in /Users/pknotz/foo/.git/

$ echo "Hello" > a

$ git add a

$ git commit -am "initial commit"
[master (root-commit) 7e52a51] initial commit
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 a

$ echo " World" >> a

$ git commit -am "Be more specific"
[master 080e9fe] Be more specific
 1 files changed, 1 insertions(+), 0 deletions(-)

$ echo "Hello" > a

$ git commit -am "Be less specific"
[master 00f3fd0] Be less specific
 1 files changed, 0 insertions(+), 1 deletions(-)

$ cat a
Hello

$ git log -SWorld
commit 00f3fd0134d0d54aafbb9d959666efc5fd492b4f
Author: Pat Notz <[email protected]>
Date:   Tue Oct 6 17:20:48 2009 -0600

    Be less specific

commit 080e9fe84ff89aab9d9d51fb5d8d59e8f663ee7f
Author: Pat Notz <[email protected]>
Date:   Tue Oct 6 17:20:33 2009 -0600

    Be more specific

Or, is this not what you mean?

或者,这不是你的意思吗?

回答by Simone

git log -S<string>does the job, but if you need to make more complex searches you can use git log -G<regex>.

git log -S<string>完成这项工作,但如果您需要进行更复杂的搜索,您可以使用git log -G<regex>.

From the man:

来自man

-G<regex>

Look for differences whose patch text contains added/removed lines that match <regex>.

-G<regex>

查找补丁文本包含匹配的添加/删除行的差异<regex>

回答by Dionysius

Found your question while driving nuts myself and so far no answer were sufficient. I've found a way to find the specific commit, but it is only shown when diffing between these commits. I can't explain why git works that way, but I'll elaborate my findings:

在自己发疯时发现了您的问题,到目前为止还没有足够的答案。我找到了一种找到特定提交的方法,但只有在这些提交之间存在差异时才会显示。我无法解释为什么 git 会这样工作,但我会详细说明我的发现:



Problem explained

问题说明

With '-S' or '-G' we can only find where it was added, not removed. To elaborate:

使用 '-S' 或 '-G' 我们只能找到添加的位置,而不是删除的位置。详细说明:

$ git log --format="%H" -S"127.0.124.1"
857aa361293abbb351d6d6becaa55ec011aebc93
$ git show 857aa361293abbb351d6d6becaa55ec011aebc93 | grep "127.0.124.1" # remove grep to see full diff
+       return "127.0.124.1", nil


Step by step

一步步

I got the idea from miku86 on dev.to. First we try to find the last commit our string existed:

我从dev.to 上的 miku86那里得到了这个想法。首先,我们尝试找到我们的字符串存在的最后一次提交:

$ git --no-pager grep "127.0.124.1" $(git rev-list --all) # | head -n1 | cut -d: -f1 # uncomment to only show the hash of the first one
ba0b2d348f4e33857c96acf5a6231cf9d89ddb1b:some/file.go:        return "127.0.124.1"
0d19a98d6434da0b4b5cc2bac190b9b1de36d992:some/file.go:        return "127.0.124.1"
84274c5712bacbbee1dca5567cef77a2b6f356d2:some/file.go:        return "127.0.124.1"
42e692643ff8a5dce7a89e985062b3d38c60fcc0:some/file.go:        return "127.0.124.1"

Which results in ba0b2d348f4e33857c96acf5a6231cf9d89ddb1bis our searched commit. Next we try to find the commit following after this one until HEAD:

结果ba0b2d348f4e33857c96acf5a6231cf9d89ddb1b是我们搜索到的提交。接下来,我们尝试在此之后找到以下提交,直到 HEAD:

$ git rev-list ba0b2d348f4e33857c96acf5a6231cf9d89ddb1b.. # | tail -n1 # uncomment to only show the last one
[...]
c82d040f7be2f8955075655843400a36ceb75303
aa0568b543db57564770d73e736aaf50fd749fb4
dde61dae0cf648e7f4dd8a5c194bcf9be1745793

Which is dde61dae0cf648e7f4dd8a5c194bcf9be1745793, since this is the last one in this list we're looking for.

也就是dde61dae0cf648e7f4dd8a5c194bcf9be1745793,因为这是我们要查找的列表中的最后一个。

So that means dde61dae0cf648e7f4dd8a5c194bcf9be1745793should contain that removal?

所以这意味着dde61dae0cf648e7f4dd8a5c194bcf9be1745793应该包含删除?

$ git show dde61dae0cf648e7f4dd8a5c194bcf9be1745793 | grep "127.0.124.1" # remove grep to see full diff
#<no output>

No?!? Well what's the diff then from that to our first found commit?

不?!?那么与我们第一次发现的提交有什么不同?

$ git diff ba0b2d348f4e33857c96acf5a6231cf9d89ddb1b..dde61dae0cf648e7f4dd8a5c194bcf9be1745793 | grep "127.0.124.1" # remove grep to see full diff
-       return "127.0.124.1"

Here we've found it. Thats odd. But since we're using a diff between commits, did I made a mistake and there are other commits inbetween?

我们在这里找到了。真奇怪。但是由于我们在提交之间使用差异,我是否犯了错误并且中间还有其他提交?

$ git log --pretty=oneline ba0b2d348f4e33857c96acf5a6231cf9d89ddb1b..dde61dae0cf648e7f4dd8a5c194bcf9be1745793
dde61dae0cf648e7f4dd8a5c194bcf9be1745793 network interface

No, we seem to haven't make a mistake. Thats odd. But yeah, that's how far I got to find the specific spot of change where the string vanished.

不,我们似乎没有犯错。真奇怪。但是,是的,这就是我找到字符串消失的特定变化点的距离。



Additionally

此外

I can confirm using git bisectthat dde61dae0cf648e7f4dd8a5c194bcf9be1745793is the commit I was looking for.

我可以确认使用git bisectdde61dae0cf648e7f4dd8a5c194bcf9be1745793是我正在寻找的提交。

# bisecting a while...
$ git bisect bad 
dde61dae0cf648e7f4dd8a5c194bcf9be1745793 is the first bad commit
commit dde61dae0cf648e7f4dd8a5c194bcf9be1745793
Author: ...
Date:   Fri Oct 18 11:04:26 2019 +0200

    network interface

:100644 100644 242e81c363c2c7069efb018821821553b98f2c97 416c27f5351a9d92a6914b34846c6de51d83dd0d M      go.mod
:040000 040000 715c3ab5b3f4579d8054618f1e11fc05fb425324 e6731408a1ac1ff0428128ccbb1fbfaad4c789ab M      network
[...]