···11+package git
22+33+import (
44+ "fmt"
55+ "strings"
66+)
77+88+// preReceiveHook returns the bytes of a pre-receive hook script
99+// that prints m before exiting successfully
1010+func preReceiveHook(m string) []byte {
1111+ return []byte(fmt.Sprintf("#!/bin/rc\necho -n %s\n", quote(m)))
1212+}
1313+1414+const quoteChar = '\''
1515+1616+func needsQuote(s string) bool {
1717+ for i := 0; i < len(s); i++ {
1818+ c := s[i]
1919+ if c == quoteChar || c <= ' ' { // quote, blanks, or control characters
2020+ return true
2121+ }
2222+ }
2323+ return false
2424+}
2525+2626+// Quote adds single quotes to s in the style of rc(1) if they are needed.
2727+// The behaviour should be identical to Plan 9's quote(3).
2828+func quote(s string) string {
2929+ if s == "" {
3030+ return "''"
3131+ }
3232+ if !needsQuote(s) {
3333+ return s
3434+ }
3535+ var b strings.Builder
3636+ b.Grow(10 + len(s)) // Enough room for few quotes
3737+ b.WriteByte(quoteChar)
3838+ for i := 0; i < len(s); i++ {
3939+ c := s[i]
4040+ if c == quoteChar {
4141+ b.WriteByte(quoteChar)
4242+ }
4343+ b.WriteByte(c)
4444+ }
4545+ b.WriteByte(quoteChar)
4646+ return b.String()
4747+}
+31
worktree_plan9.go
···11+package git
22+33+import (
44+ "syscall"
55+ "time"
66+77+ "gopkg.in/src-d/go-git.v4/plumbing/format/index"
88+)
99+1010+func init() {
1111+ fillSystemInfo = func(e *index.Entry, sys interface{}) {
1212+ if os, ok := sys.(*syscall.Dir); ok {
1313+ // Plan 9 doesn't have a CreatedAt field.
1414+ e.CreatedAt = time.Unix(int64(os.Mtime), 0)
1515+1616+ e.Dev = uint32(os.Dev)
1717+1818+ // Plan 9 has no Inode.
1919+ // ext2srv(4) appears to store Inode in Qid.Path.
2020+ e.Inode = uint32(os.Qid.Path)
2121+2222+ // Plan 9 has string UID/GID
2323+ e.GID = 0
2424+ e.UID = 0
2525+ }
2626+ }
2727+}
2828+2929+func isSymlinkWindowsNonAdmin(err error) bool {
3030+ return true
3131+}