github.com/rcowham/go-libgitfastimport@v0.1.6/cmd_comment.go (about) 1 // Copyright (C) 2017-2018, 2021 Luke Shumaker <lukeshu@lukeshu.com> 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package libfastimport 17 18 import ( 19 "strconv" 20 "strings" 21 22 "github.com/pkg/errors" 23 ) 24 25 // This file deals with comments, and with commands for which the 26 // specification says (or said) that the command "can be used anywhere 27 // in the stream that comments are accepted". 28 29 // comment ///////////////////////////////////////////////////////////////////// 30 31 // CmdComment is a comment line; not a real command. 32 type CmdComment struct { 33 Comment string 34 } 35 36 func (c CmdComment) fiCmdClass() cmdClass { return cmdClassComment } 37 func (c CmdComment) fiCmdWrite(fiw fiWriter) error { 38 return fiw.WriteLine("#" + c.Comment) 39 } 40 func init() { parser_registerCmd("#", CmdComment{}) } 41 func (CmdComment) fiCmdRead(fir fiReader) (cmd Cmd, err error) { 42 line, err := fir.ReadLine() 43 if err != nil { 44 return nil, err 45 } 46 return CmdComment{Comment: trimLinePrefix(line, "#")}, nil 47 } 48 49 // get-mark //////////////////////////////////////////////////////////////////// 50 51 // CmdGetMark requests that the Backend to report back (over the 52 // auxiliary cat-blob stream) with the SHA-1 corresponding to the 53 // given Mark. 54 type CmdGetMark struct { 55 Mark int 56 } 57 58 func (c CmdGetMark) fiCmdClass() cmdClass { 59 // Prior to git v2.22.0 this was 'cmdClassComment', but in 60 // v2.22.0 it was changed to a stricter 61 // 'cmdClassCommand|cmdClassInCommit'. I want to have better 62 // backward compatibility, so I'm keeping it as 63 // 'cmdClassComment'. 64 return cmdClassComment 65 } 66 func (c CmdGetMark) fiCmdWrite(fiw fiWriter) error { 67 return fiw.WriteLine("get-mark", ":"+strconv.Itoa(c.Mark)) 68 } 69 func init() { parser_registerCmd("get-mark :", CmdGetMark{}) } 70 func (CmdGetMark) fiCmdRead(fir fiReader) (cmd Cmd, err error) { 71 line, err := fir.ReadLine() 72 if err != nil { 73 return nil, err 74 } 75 c := CmdGetMark{} 76 c.Mark, err = strconv.Atoi(trimLinePrefix(line, "get-mark :")) 77 if err != nil { 78 return nil, errors.Wrap(err, "get-mark") 79 } 80 return c, nil 81 } 82 83 // cat-blob //////////////////////////////////////////////////////////////////// 84 85 // CmdCatBlob requests that the Backend to report back (over the 86 // auxiliary cat-blob stream) with the SHA-1 and content of the 87 // requested blob. The blob can be specified either by a mark 88 // reference (":<idnum>") or by a full 40-byte SHA-1. 89 type CmdCatBlob struct { 90 DataRef string 91 } 92 93 func (c CmdCatBlob) fiCmdClass() cmdClass { 94 // Prior to git v2.22.0 this was 'cmdClassComment', but in 95 // v2.22.0 it was changed to a stricter 96 // 'cmdClassCommand|cmdClassInCommit|cmdClassInFileModify'. I 97 // don't want to implement cmdClassInFileModify for just this 98 // one command, and also I want to have better backward 99 // compatibility; so I'm keeping it as 'cmdClassComment'. 100 return cmdClassComment 101 } 102 func (c CmdCatBlob) fiCmdWrite(fiw fiWriter) error { 103 return fiw.WriteLine("cat-blob", c.DataRef) 104 } 105 func init() { parser_registerCmd("cat-blob ", CmdCatBlob{}) } 106 func (CmdCatBlob) fiCmdRead(fir fiReader) (cmd Cmd, err error) { 107 line, err := fir.ReadLine() 108 if err != nil { 109 return nil, err 110 } 111 return CmdCatBlob{DataRef: trimLinePrefix(line, "cat-blob ")}, nil 112 } 113 114 // ls ////////////////////////////////////////////////////////////////////////// 115 116 // CmdLs requests that the Backend to report back (over the auxiliary 117 // cat-blob stream) with information about the object at a path in the 118 // specified commit. If inside of a commit, specifying the commit is 119 // optional, and the ongoing commit is used. The commit can be 120 // specified either by a mark reference (":<idnum>") or by a full 121 // 40-byte SHA-1. 122 type CmdLs struct { 123 DataRef string // optional if inside of a commit 124 Path Path 125 } 126 127 func (c CmdLs) fiCmdClass() cmdClass { 128 // Prior to git v2.22.0 the docs said 'ls' was allowed 129 // anywhere a comment was allowed, but that was never really 130 // true, and in v2.22.0 the docs were updated to match the 131 // code. 132 if c.DataRef == "" { 133 // Yeah, this will give slightly misleading info to 134 // parser_registerCmd(), but that's OK, 135 // parser_registerCmd() only really cares about the 136 // cmdClassInCommand bit. 137 return cmdClassInCommit 138 } 139 return cmdClassCommand | cmdClassInCommit 140 } 141 func (c CmdLs) fiCmdWrite(fiw fiWriter) error { 142 if c.DataRef == "" { 143 return fiw.WriteLine("ls", c.Path) 144 } else { 145 return fiw.WriteLine("ls", c.DataRef, c.Path) 146 } 147 } 148 func init() { parser_registerCmd("ls ", CmdLs{}) } 149 func (CmdLs) fiCmdRead(fir fiReader) (cmd Cmd, err error) { 150 // 'ls' SP <dataref> SP <path> LF 151 line, err := fir.ReadLine() 152 if err != nil { 153 return nil, err 154 } 155 str := trimLinePrefix(line, "ls ") 156 sp := -1 157 if !strings.HasPrefix(str, "\"") { 158 sp = strings.IndexByte(line, ' ') 159 } 160 c := CmdLs{} 161 c.Path = PathUnescape(str[sp+1:]) 162 if sp >= 0 { 163 c.DataRef = str[:sp] 164 } 165 return c, nil 166 }