threads / discuss / 26122

Expected behaviour of 'git log -S' when searching in a merged/deleted file?

Subject: Expected behaviour of 'git log -S' when searching in a merged/deleted file?

## tl;dr

5 messages between Dec 22, 2010 and Dec 23, 2010.

replies: 4people: 2as markdown or json

Jonathan del Strother· Dec 22, 2010, 13:37 UTC · lore
Hi,
I was trying to find a particular string in my project this morning.
'git grep mystring' suggested that the string didn't exist in my repo,
but 'git log -Smystring' turned up a single commit that had added it.
It took me a long time to figure out that in the past, a branch had
added that string to foo.c, but a second branch deleted foo.c, and the
two branches were later merged (deleting foo.c and ignoring mystring).
 I was surprised that 'git log -S' didn't show the merge commit as the
point at which the string had been removed.

I've attached a testcase which I would expect to pass (perhaps naively), but doesn't. Is this a git bug, or do I misunderstand git log -S?

--
#!/bin/sh
test_description='git log'
. ./test-lib.sh
test_expect_success setup '
	echo haystack\\nhaystack\\nhaystack\\nhaystack\\n > haystack &&
	git add haystack &&
	test_tick &&
	git commit -m initial &&
	git checkout -b branchA &&
	echo needle >haystack &&
	git add haystack &&
	test_tick &&
	git commit -m "adding needle" &&
	git checkout -b branchB HEAD~1 &&
	git rm haystack &&
	test_tick &&
	git commit -m "removing haystack" &&
	git merge branchA || git rm haystack &&
	test_tick &&
	git commit -m "merging: haystack and needle removed"
'

printf "merging: haystack and needle removed\nadding needle" > expect test_expect_success 'log -S in a merge-deleted file' '

	git log -Sneedle --pretty="format:%s" > actual &&
	test_cmp expect actual
'
test_done
Junio C Hamano· Dec 22, 2010, 18:17 UTC · re: Jonathan del Strother · lore

Re: Expected behaviour of 'git log -S' when searching in a merged/deleted file?

Jonathan del Strother <jdelstrother@gmail.com> writes:
Show 6 quoted lines
> I was trying to find a particular string in my project this morning.
> 'git grep mystring' suggested that the string didn't exist in my repo,
> but 'git log -Smystring' turned up a single commit that had added it.
> It took me a long time to figure out that in the past, a branch had
> added that string to foo.c, but a second branch deleted foo.c, and the
> two branches were later merged (deleting foo.c and ignoring mystring).
This is a typical case of the history simplification in action, isn't it?

"log" will give you one possible and simplest explanation of how the project came into the current shape. Because side branches with changes that were discarded before merging it to the history that lead to the commit you run "log" from do not contribute anything to the end result, "log" will not traverse the entire side branch when it sees the merge.

Try your "log" with --full-history, perhaps?
Jonathan del Strother· Dec 23, 2010, 09:47 UTC · re: Junio C Hamano · lore

Re: Expected behaviour of 'git log -S' when searching in a merged/deleted file?

On 22 December 2010 18:17, Junio C Hamano <gitster@pobox.com> wrote:
Show 16 quoted lines
> Jonathan del Strother <jdelstrother@gmail.com> writes:
>
>> I was trying to find a particular string in my project this morning.
>> 'git grep mystring' suggested that the string didn't exist in my repo,
>> but 'git log -Smystring' turned up a single commit that had added it.
>> It took me a long time to figure out that in the past, a branch had
>> added that string to foo.c, but a second branch deleted foo.c, and the
>> two branches were later merged (deleting foo.c and ignoring mystring).
>
> This is a typical case of the history simplification in action, isn't it?
>
> "log" will give you one possible and simplest explanation of how the
> project came into the current shape.  Because side branches with changes
> that were discarded before merging it to the history that lead to the
> commit you run "log" from do not contribute anything to the end result,
> "log" will not traverse the entire side branch when it sees the merge.

I don't follow ... 'log' isn't showing me how the project came into it's current shape. In the test case I posted, for example, it's showing me that 'needle' was added to the repository at some point, but it neglects to mention that it was removed. If 'needle' was added and removed within the duration of a single branch, I could understand "git log -S" never finding 'needle' due to history simplication, but I don't understand how simplification applies here.

>
> Try your "log" with --full-history, perhaps?
Doesn't seem to affect the output in this case.
Junio C Hamano· Dec 23, 2010, 16:03 UTC · re: Jonathan del Strother · lore

Re: Expected behaviour of 'git log -S' when searching in a merged/deleted file?

Jonathan del Strother <jdelstrother@gmail.com> writes:
> ....  If 'needle' was added
> and removed within the duration of a single branch, I could understand
> "git log -S" never finding 'needle' due to history simplication, but I
> don't understand how simplification applies here.

Ahh, sorry, I misunderstood the scenario. Just like you do not see a patch output from "log -p", the diff machinery (including -S and its newer cousin -G) does not kick in by default for merge commits (this is a bit of white lie as "log -p" defaults to "combine diff", i.e. be silent on any uninteresting merge that takes its results literally from either parent).

Please try it with "-m" (not "--full-history"). We _might_ want to change this behaviour for -S/-G but it needs a bit more thought.

Jonathan del Strother· Dec 23, 2010, 17:27 UTC · re: Junio C Hamano · lore

Re: Expected behaviour of 'git log -S' when searching in a merged/deleted file?

On 23 December 2010 16:03, Junio C Hamano <gitster@pobox.com> wrote:
Show 16 quoted lines
> Jonathan del Strother <jdelstrother@gmail.com> writes:
>
>> ....  If 'needle' was added
>> and removed within the duration of a single branch, I could understand
>> "git log -S" never finding 'needle' due to history simplication, but I
>> don't understand how simplification applies here.
>
> Ahh, sorry, I misunderstood the scenario.  Just like you do not see a
> patch output from "log -p", the diff machinery (including -S and its newer
> cousin -G) does not kick in by default for merge commits (this is a bit of
> white lie as "log -p" defaults to "combine diff", i.e. be silent on any
> uninteresting merge that takes its results literally from either parent).
>
> Please try it with "-m" (not "--full-history").  We _might_ want to change
> this behaviour for -S/-G but it needs a bit more thought.
>
Yep, '-m' produces the expected (or at least, *my* expected) results.

← back to recent threads