Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git-diff-base should use merge-base instead of direct diff #1653

Closed
bdsl opened this issue Jan 20, 2022 · 7 comments · Fixed by #1654
Closed

git-diff-base should use merge-base instead of direct diff #1653

bdsl opened this issue Jan 20, 2022 · 7 comments · Fixed by #1654
Milestone

Comments

@bdsl
Copy link
Contributor

bdsl commented Jan 20, 2022

Question Answer
Infection version 0.26.0
Test Framework version PHPUnit 9.5.4
PHP version 7.4
Platform e.g. Ubuntu/Windows/MacOS

I'm not sure whether this should be classified as a bug or a change request. The docs don't seem to specify exactly what the behaviour should be.

Currently when using --git-diff-base=master infection seems to be generating mutants for any lines that appear in a direct diff between HEAD and master. I think instead it should use a diff between HEAD and the merge-base of HEAD and master - i.e. the diff you see on a github pull request.

We are trying out infection to give us an automatic critique of work done in PRs, and it's confusing when this includes stuff that changed on master because of an unrelated PR.

I can work around the issue for now by running git merge-base HEAD origin/master and passing the output of that to the CLI param.

@maks-rafalko
Copy link
Member

maks-rafalko commented Jan 20, 2022

Let me ask if I understood the issue correctly.

Given the following example from merge-base docs:

	 o---o---o---B
	/
---o---X---o---o---o---A
  1. do you want Infection to automatically do a diff between B and X?
  2. do you say that currently Infection does a diff between B and A?

If yes & yes, what do you think if we add this information to the docs and allow people to control it themselves?

If they want to diff with merge-base, they do it like you said.
If they want to diff between HEAD and current master - just --git-diff-base=master

Does it make sense?

@bdsl
Copy link
Contributor Author

bdsl commented Jan 20, 2022

Yes, if B is HEAD then when I do --git-diff-base=A I would like to see mutants generated only for the diff between B and X - i.e. for the changes introduced on branch B. That seems natural for evaluating the quality of work done in branch B and to inform a decision about whether it's ready to merge into A.

We could just add something to the docs, but I'm not sure what the use case is for the direct diff between B and A.

@bdsl
Copy link
Contributor Author

bdsl commented Jan 20, 2022

I think typically the diff between B and X is going to be very similar to the diff between the hypothetical commit that merges B into A and A.

@maks-rafalko maks-rafalko added this to the next milestone Jan 20, 2022
@bdsl
Copy link
Contributor Author

bdsl commented Jan 21, 2022

Happy to make a PR for this, could probably use some guidance since I haven't contributed to infection before. I guess there's an option to introduce a new command line argument instead of changing the behaviour of the existing one.

@maks-rafalko
Copy link
Member

Happy to make a PR for this, could probably use some guidance since I haven't contributed to infection before

awesome.

I would start from here:

public function provide(string $gitDiffFilter, string $gitDiffBase): string
{
$filter = $this->shellCommandLineExecutor->execute(sprintf(
'git diff %s --diff-filter=%s --name-only | grep src/ | paste -s -d "," -',
escapeshellarg($gitDiffBase),
escapeshellarg($gitDiffFilter)
));
if ($filter === '') {
throw NoFilesInDiffToMutate::create();
}
return $filter;
}
public function provideWithLines(string $gitDiffBase): string
{
return $this->shellCommandLineExecutor->execute(sprintf(
"git diff %s --unified=0 --diff-filter=AM | grep -v -e '^[+-]' -e '^index'",
escapeshellarg($gitDiffBase)
));
}

the first method is used for --git-diff-filter option, the second one is for --git-diff-lines. I believe both options should work with the new merge-base update.

I guess there's an option to introduce a new command line argument instead of changing the behaviour of the existing one.

I'm personally ok with updating behavior for current options. We are on 0.x branch, so BC changes are kind of expected. At least it's better than introducing 2 more options in addition to 2 mentioned above

@bdsl
Copy link
Contributor Author

bdsl commented Jan 21, 2022

Thanks, I'll see if I can get the PR in this weekend.

bdsl added a commit to bdsl/infection that referenced this issue Jan 24, 2022
bdsl added a commit to bdsl/infection that referenced this issue Jan 24, 2022
bdsl added a commit to bdsl/infection that referenced this issue Jan 25, 2022
bdsl added a commit to bdsl/infection that referenced this issue Jan 25, 2022
maks-rafalko pushed a commit that referenced this issue Jan 26, 2022
…se (#1653) (#1654)

* Use merge-base (three dot diff) instead of direct diff for git-diff-base (#1653)

* Add command line dumping for debugging

* Fetch full history to allow finding common ancestor, not just last commit

* Remove var_dumps

* Debug with git depth 1

* Fall back to direct diff if merge base commit is not avialable

* Restore deep git fetch

* Kill UnwrapTrim mutant
bdsl added a commit to bdsl/infection that referenced this issue Jan 26, 2022
…se (infection#1653) (infection#1654)

* Use merge-base (three dot diff) instead of direct diff for git-diff-base (infection#1653)

* Add command line dumping for debugging

* Fetch full history to allow finding common ancestor, not just last commit

* Remove var_dumps

* Debug with git depth 1

* Fall back to direct diff if merge base commit is not avialable

* Restore deep git fetch

* Kill UnwrapTrim mutant
maks-rafalko pushed a commit that referenced this issue Jan 27, 2022
#1655)

* Use merge-base (three dot diff) instead of direct diff for git-diff-ase (#1653) (#1654)

* Use merge-base (three dot diff) instead of direct diff for git-diff-base (#1653)

* Add command line dumping for debugging

* Fetch full history to allow finding common ancestor, not just last commit

* Remove var_dumps

* Debug with git depth 1

* Fall back to direct diff if merge base commit is not avialable

* Restore deep git fetch

* Kill UnwrapTrim mutant

* Fix php parse error

* Add test_it_falls_back_to_direct_diff_if_merge_base_is_not_availabe

* Skip test on Windows
@maks-rafalko
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants