{"contents":"package git\n\nimport (\n\t\"time\"\n\n\t\"github.com/go-git/go-git/v5/plumbing/object\"\n\t\"github.com/go-git/go-git/v5/plumbing/storer\"\n)\n\n// LastCommitInfo holds information about the last commit that touched a file.\ntype LastCommitInfo struct {\n\tHash string `json:\"hash\"`\n\tMessage string `json:\"message\"`\n\tAuthor string `json:\"author\"`\n\tWhen time.Time `json:\"when\"`\n}\n\n// LastCommitForPath walks the commit history to find the last commit that modified\n// the given path.\nfunc (repo *Repo) LastCommitForPath(filePath string) (*LastCommitInfo, error) {\n\tcommit, err := repo.HeadCommit()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\titer := object.NewCommitIterCTime(commit, nil, nil)\n\tdefer iter.Close()\n\n\tvar result *LastCommitInfo\n\terr = iter.ForEach(func(c *object.Commit) error {\n\t\tif len(c.ParentHashes) == 0 {\n\t\t\t// Root commit touches all files\n\t\t\tif _, err := c.File(filePath); err == nil {\n\t\t\t\tresult = commitInfo(c)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tparent, err := c.Parent(0)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tpatch, err := parent.Patch(c)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tfor _, fp := range patch.FilePatches() {\n\t\t\tfrom, to := fp.Files()\n\t\t\tname := \"\"\n\t\t\tif to != nil {\n\t\t\t\tname = to.Path()\n\t\t\t} else if from != nil {\n\t\t\t\tname = from.Path()\n\t\t\t}\n\t\t\tif name == filePath {\n\t\t\t\tresult = commitInfo(c)\n\t\t\t\treturn storer.ErrStop\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\nfunc commitInfo(c *object.Commit) *LastCommitInfo {\n\treturn \u0026LastCommitInfo{\n\t\tHash: c.Hash.String(),\n\t\tMessage: c.Message,\n\t\tAuthor: c.Author.Name,\n\t\tWhen: c.Author.When,\n\t}\n}\n","path":"git/last_commit.go","ref":"main"}