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: blame, Fix panic when contents and commits have different length #751

Closed
wants to merge 4 commits into from

Conversation

williamfzc
Copy link

@williamfzc williamfzc commented Apr 27, 2023

Fixes: #603

@lonegunmanb
Copy link

This bug is really annoying, it caused an BridgeCrew Yor's issue, could we merge this patch asap?

@pjbgf pjbgf changed the title Fix git blame panic: contents and commits have different length git: blame, Fix panic when contents and commits have different length Apr 27, 2023
@pjbgf
Copy link
Member

pjbgf commented Apr 27, 2023

@williamfzc please squash the commits and reword the commit message to align with the contributing guidelines (e.g. PR's new title).

@williamfzc
Copy link
Author

@williamfzc please squash the commits and reword the commit message to align with the contributing guidelines (e.g. PR's new title).

done

references.go Outdated
@@ -104,6 +104,16 @@ func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, curre
default: // more than one parent contains the path
// TODO: detect merges that had a conflict, because they must be
// included in the result here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of case 1 and default are the same. This switch could be simplified with:

	case 0:
		*result = append(*result, current)
		return nil
	default: // or or more than one parent contains the path
		different, err := differentContents(path, current, parents)
		if err != nil {
			return err
		}
		if len(different) > 0 {
			*result = append(*result, current)
		}

		for _, p := range parents {
			err := walkGraph(result, seen, p, path)
			if err != nil {
				return err
			}
		}
	}

@pjbgf
Copy link
Member

pjbgf commented May 11, 2023

@williamfzc @lonegunmanb the tests are failing as now we are returning more references than the tests expect. Please amend go-git/utils/revlist2humantest.bash so that the git rev-list returns the new references. From a quick look we may need to add --full-history.

Then you can use that script to update the test cases here.

@williamfzc
Copy link
Author

williamfzc commented May 13, 2023

@williamfzc @lonegunmanb the tests are failing as now we are returning more references than the tests expect. Please amend go-git/utils/revlist2humantest.bash so that the git rev-list returns the new references. From a quick look we may need to add --full-history.

Then you can use that script to update the test cases here.

@pjbgf ok I have updated all the references. But I am not sure that if they are correct :( .

@pjbgf
Copy link
Member

pjbgf commented May 20, 2023

When the references generated by walkGraph align with the ones returned from revlist2humantest.bash the tests will pass. I had another quick look and different test cases yield slightly mismatches, so it would take a combination of further digging into the git rev-list docs and potentially amending our logic to get this fixed.

Apologies but at the moment I don't have the free time to dig in and help more. Feel free to continue trying and ping me if you need another review (or a tests kick off).

Fix `references` to simulate `rev-list` command's behavior
@lonegunmanb
Copy link

Hi @pjbgf, we‘ve tried to fix the broken tests and updated the pr, would you please kick off the tests? If there're still test errors I'd like to submit my own pr based on @williamfzc's branch so we can fix this panic bug asap, thanks!

}
if !equals {
h1, _ := blobHash(path, cs[i])
h2, _ := blobHash(path, cs[i-1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why recalculate the hash for every entry twice? Keep the hash from the last iteration?

h2, _ := blobHash(path, cs[i-1])
equal := h1 == h2

if !equal {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need for equal, just do if h1 != h2

// sorted commit list. Duplication is defined according to "comp". It
// will always keep the first commit of a series of duplicated commits.
// sorted commit list. Duplication is defined according to the blob hash.
// It will always keep the first commit of a series of duplicated commits.
func removeComp(path string, cs []*object.Commit, comp contentsComparatorFn) ([]*object.Commit, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comp is no longer used, if it really isn't needed then remove the param and rename the function

@@ -90,20 +89,15 @@ func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, curre
case 0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer need the switch here, just change to if len(parents) == 0 {?

@@ -114,6 +108,19 @@ func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, curre
return nil
}

func derivedFromOneParent(path string, current *object.Commit, parents []*object.Commit) (bool, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does derivedFromOneParent mean? You are going through all of the parents?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all parents, maybe I should rename the function to derivedFromAnyParent.

@@ -114,6 +108,19 @@ func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, curre
return nil
}

func derivedFromOneParent(path string, current *object.Commit, parents []*object.Commit) (bool, error) {
for _, parent := range parents {
different, err := differentContents(path, current, []*object.Commit{parent})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

differentContents already iterates the list? Why do you need to pass each of the parents individually? Can't you just pass parents?

@lonegunmanb
Copy link

Hi @pjbgf this pr is no longer updated, I've opened a new one #780 based on @williamfzc's work.

@williamfzc
Copy link
Author

Thanks @lonegunmanb .
Let's continue in #780

@williamfzc williamfzc closed this May 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

git blame panic: contents and commits have different length
4 participants