Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

How to get the line number of a diff? #806

@campoy

Description

@campoy

I'm currently trying to obtain the lines that are new code in a diff.
To do so I wrote the code below

func diffHeadAndPrevious(path, branch string) error {
	logrus.Infof("cloning")
	opts := &git.CloneOptions{
		URL:           path,
		ReferenceName: plumbing.ReferenceName("refs/heads/" + branch),
		SingleBranch:  true,
	}
	repo, err := git.PlainClone("repo", false, opts)
	if err != nil {
		return fmt.Errorf("could not clone repo: %v", err)
	}

	logrus.Infof("done cloning")
	headRef, err := repo.Head()
	if err != nil {
		return fmt.Errorf("could not fetch head: %v", err)
	}

	headCommit, err := repo.CommitObject(headRef.Hash())
	if err != nil {
		return fmt.Errorf("could not get commit for head: %v", err)
	}
	headTree, err := headCommit.Tree()
	if err != nil {
		return fmt.Errorf("could not fetch head tree: %v", err)
	}

	if headCommit.NumParents() > 1 {
		return fmt.Errorf("not sure how to handle merge commits yet")
	} else if headCommit.NumParents() == 0 {
		return nil
	}
	prevCommit, err := headCommit.Parent(0)
	if err != nil {
		return fmt.Errorf("could not fetch previous commit: %v", err)
	}
	prevTree, err := prevCommit.Tree()
	if err != nil {
		return fmt.Errorf("could not fetch previous tree: %v", err)
	}

	changes, err := object.DiffTree(headTree, prevTree)
	if err != nil {
		return fmt.Errorf("could not diff trees: %v", err)
	}

	patch, err := changes.Patch()
	if err != nil {
		return fmt.Errorf("could not get change patch: %v", err)
	}
	for _, p := range patch.FilePatches() {
		if p.IsBinary() {
			continue
		}
		for _, chunk := range p.Chunks() {
			if chunk.Type() != diff.Add {
				continue
			}
			fmt.Printf(chunk.Content())
		}
	}

	return nil
}

This works and if called with diffHeadAndPrevious("https://github.com/campoy/goodgopher", "pr") it will print the content of the lines that changed:

                        Body: &comment.message,
                        Path: &comment.path,
                        // CommitID: commits[len(commits)-1].SHA,

Unfortunately I'd like to know what lines are those in the destination file.
I spent a decent amount of time searching around the documentation but couldn't find anything.

Help, please.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions