Example #1
0
func (gitfs *GitFs) getGitAttrByPath(repoPath string, path string) (*fuse.Attr, fuse.Status) {
	repo, _, _, tree, err := gitfs.getMasterTreeFromRepo(repoPath)
	if err != nil {
		return nil, fuse.EPERM
	}

	repoInfo, err := os.Stat(repoPath)
	if err != nil {
		gitfs.logger.Debugf("Failed to Stat %s due to %s", repoPath, err)
		return nil, fuse.ToStatus(err)
	}

	if path == "" {
		attr := fuse.ToAttr(repoInfo)
		attr.Mode &= ^uint32(0222)
		attr.Nlink = 2 + gitfs.treeEntryCount(tree, repoPath)
		return attr, fuse.OK
	}

	entry, err := tree.EntryByPath(path)
	if err != nil {
		gitfs.logger.Debugf("Cannot find path %s from tree %s of Git Repository %s due to %s", path, tree.Id().String(), repoPath, err)
		return nil, fuse.ENOENT
	}
	gitfs.logger.Debugf("Found path %s from tree %s of Git Repository %s", path, tree.Id().String(), repoPath)

	var attr fuse.Attr
	attr.Mode = toFileMode(entry.Filemode)
	if stat, ok := repoInfo.Sys().(*syscall.Stat_t); ok {
		attr.Uid = stat.Uid
		attr.Gid = stat.Gid
		attr.Blksize = uint32(stat.Blksize)
		attr.Rdev = uint32(stat.Rdev)
	}
	attr.Ino = crc64.Checksum(entry.Id[:], crc64.MakeTable(crc64.ECMA))
	now := time.Now()
	attr.SetTimes(&now, &now, &now)

	switch entry.Type {
	case libgit2.ObjectTree:
		tree, err := repo.LookupTree(entry.Id)
		if err != nil {
			gitfs.logger.Errorf("Failed to find tree %s from Git Repository %s", entry.Id, repoPath)
			return nil, fuse.EPERM
		}
		defer tree.Free()
		gitfs.logger.Debugf("Found tree %s of Git Repository %s", tree.Id().String(), repoPath)
		attr.Size = 4096
		attr.Nlink = 2 + gitfs.treeEntryCount(tree, repoPath)
	case libgit2.ObjectBlob:
		blob, err := repo.LookupBlob(entry.Id)
		if err != nil {
			gitfs.logger.Errorf("Failed to find blob %s from Git Repository %s", entry.Id, repoPath)
			return nil, fuse.EPERM
		}
		defer blob.Free()
		gitfs.logger.Debugf("Found blob %s of Git Repository %s", blob.Id().String(), repoPath)
		attr.Nlink = 1
		attr.Size = uint64(blob.Size())
	default:
		gitfs.logger.Debugf("GetAttr: Unsupported object type %s of %s from Git Repository %s", entry.Type.String(), entry.Id, repoPath)
		return nil, fuse.ENOENT
	}
	attr.Blocks = (attr.Size + 511) / 512
	return &attr, fuse.OK
}