Skip to content

Commit

Permalink
Add better ModTime in gitfs and ArchGitTime helper (for `SOURCE…
Browse files Browse the repository at this point in the history
…_DATE_EPOCH`)
  • Loading branch information
tianon committed Jan 12, 2024
1 parent 8fbedb3 commit 6a201d6
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
16 changes: 16 additions & 0 deletions cmd/bashbrew/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"regexp"
"strings"
"time"

"github.com/urfave/cli"

Expand Down Expand Up @@ -110,6 +111,21 @@ func (r Repo) archGitFS(arch string, entry *manifest.Manifest2822Entry) (fs.FS,
return fs.Sub(gitFS, entry.ArchDirectory(arch))
}

// returns the timestamp of the ArchGitCommit -- useful for SOURCE_DATE_EPOCH
func (r Repo) ArchGitTime(arch string, entry *manifest.Manifest2822Entry) (time.Time, error) {
f, err := r.archGitFS(arch, entry)
if err != nil {
return time.Time{}, err
}

fi, err := fs.Stat(f, ".")
if err != nil {
return time.Time{}, err
}

return fi.ModTime(), nil
}

func gitCommitFS(commit string) (fs.FS, error) {
if err := ensureGitInit(); err != nil {
return nil, err
Expand Down
13 changes: 12 additions & 1 deletion pkg/gitfs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ import (

// https://github.com/go-git/go-git/issues/296

func CommitTime(commit *goGitPlumbingObject.Commit) time.Time {
if commit.Committer.When.After(commit.Author.When) {
return commit.Committer.When
} else {
return commit.Author.When
}
}

func CommitHash(repo *goGit.Repository, commit string) (fs.FS, error) {
gitCommit, err := repo.CommitObject(goGitPlumbing.NewHash(commit))
if err != nil {
Expand All @@ -31,6 +39,7 @@ func CommitHash(repo *goGit.Repository, commit string) (fs.FS, error) {
storer: repo.Storer,
tree: tree,
name: ".",
Mod: CommitTime(gitCommit),
},
}, nil
}
Expand All @@ -49,6 +58,8 @@ type gitFS struct {
tree *goGitPlumbingObject.Tree
entry *goGitPlumbingObject.TreeEntry // might be nil ("." at the top-level of the repo)

Mod time.Time

// cached values
name string // full path from the repository root
size int64 // Tree.Size value for non-directories (more efficient than opening/reading the blob)
Expand Down Expand Up @@ -343,7 +354,7 @@ func (f gitFS) Mode() fs.FileMode {

// https://pkg.go.dev/io/fs#FileInfo: modification time
func (f gitFS) ModTime() time.Time {
return time.Time{} // TODO maybe pass down whichever is more recent of commit.Author.When vs commit.Committer.When ?
return f.Mod
}

// https://pkg.go.dev/io/fs#FileInfo: abbreviation for Mode().IsDir()
Expand Down
32 changes: 32 additions & 0 deletions pkg/gitfs/tarscrub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,35 @@ func ExampleGitVarnish() {
fmt.Printf("%x\n", h.Sum(nil))
// Output: 3aef5ac859b23d65dfe5e9f2a47750e9a32852222829cfba762a870c1473fad6
}

// this example is nice because it has a different committer vs author timestamp
// https://github.com/tianon/docker-bash/commit/eb7e541caccc813d297e77cf4068f89553256673
// https://github.com/docker-library/official-images/blob/8718b8afb62ff1a001d99bb4f77d95fe352ba187/library/bash
func ExampleGitBash() {
repo, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: "https://github.com/tianon/docker-bash.git",
SingleBranch: true,
})
if err != nil {
panic(err)
}

commit, err := gitfs.CommitHash(repo, "eb7e541caccc813d297e77cf4068f89553256673")
if err != nil {
panic(err)
}

f, err := fs.Sub(commit, "5.2")
if err != nil {
panic(err)
}

h := sha256.New()

if err := tarscrub.WriteTar(f, h); err != nil {
panic(err)
}

fmt.Printf("%x\n", h.Sum(nil))
// Output: 011c8eda9906b94916a14e7969cfcff3974f1fbf2ff7b8e5c1867ff491dc01d3
}

0 comments on commit 6a201d6

Please sign in to comment.