gitech

Форк
0
/
parse_gogit.go 
96 строк · 2.8 Кб
1
// Copyright 2018 The Gitea Authors. All rights reserved.
2
// SPDX-License-Identifier: MIT
3

4
//go:build gogit
5

6
package git
7

8
import (
9
	"bytes"
10
	"fmt"
11
	"strconv"
12
	"strings"
13

14
	"github.com/go-git/go-git/v5/plumbing"
15
	"github.com/go-git/go-git/v5/plumbing/filemode"
16
	"github.com/go-git/go-git/v5/plumbing/hash"
17
	"github.com/go-git/go-git/v5/plumbing/object"
18
)
19

20
// ParseTreeEntries parses the output of a `git ls-tree -l` command.
21
func ParseTreeEntries(h ObjectFormat, data []byte) ([]*TreeEntry, error) {
22
	return parseTreeEntries(data, nil)
23
}
24

25
func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
26
	entries := make([]*TreeEntry, 0, 10)
27
	for pos := 0; pos < len(data); {
28
		// expect line to be of the form "<mode> <type> <sha> <space-padded-size>\t<filename>"
29
		entry := new(TreeEntry)
30
		entry.gogitTreeEntry = &object.TreeEntry{}
31
		entry.ptree = ptree
32
		if pos+6 > len(data) {
33
			return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data))
34
		}
35
		switch string(data[pos : pos+6]) {
36
		case "100644":
37
			entry.gogitTreeEntry.Mode = filemode.Regular
38
			pos += 12 // skip over "100644 blob "
39
		case "100755":
40
			entry.gogitTreeEntry.Mode = filemode.Executable
41
			pos += 12 // skip over "100755 blob "
42
		case "120000":
43
			entry.gogitTreeEntry.Mode = filemode.Symlink
44
			pos += 12 // skip over "120000 blob "
45
		case "160000":
46
			entry.gogitTreeEntry.Mode = filemode.Submodule
47
			pos += 14 // skip over "160000 object "
48
		case "040000":
49
			entry.gogitTreeEntry.Mode = filemode.Dir
50
			pos += 12 // skip over "040000 tree "
51
		default:
52
			return nil, fmt.Errorf("unknown type: %v", string(data[pos:pos+6]))
53
		}
54

55
		// in hex format, not byte format ....
56
		if pos+hash.Size*2 > len(data) {
57
			return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data))
58
		}
59
		var err error
60
		entry.ID, err = NewIDFromString(string(data[pos : pos+hash.Size*2]))
61
		if err != nil {
62
			return nil, fmt.Errorf("invalid ls-tree output: %w", err)
63
		}
64
		entry.gogitTreeEntry.Hash = plumbing.Hash(entry.ID.RawValue())
65
		pos += 41 // skip over sha and trailing space
66

67
		end := pos + bytes.IndexByte(data[pos:], '\t')
68
		if end < pos {
69
			return nil, fmt.Errorf("Invalid ls-tree -l output: %s", string(data))
70
		}
71
		entry.size, _ = strconv.ParseInt(strings.TrimSpace(string(data[pos:end])), 10, 64)
72
		entry.sized = true
73

74
		pos = end + 1
75

76
		end = pos + bytes.IndexByte(data[pos:], '\n')
77
		if end < pos {
78
			return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data))
79
		}
80

81
		// In case entry name is surrounded by double quotes(it happens only in git-shell).
82
		if data[pos] == '"' {
83
			var err error
84
			entry.gogitTreeEntry.Name, err = strconv.Unquote(string(data[pos:end]))
85
			if err != nil {
86
				return nil, fmt.Errorf("Invalid ls-tree output: %w", err)
87
			}
88
		} else {
89
			entry.gogitTreeEntry.Name = string(data[pos:end])
90
		}
91

92
		pos = end + 1
93
		entries = append(entries, entry)
94
	}
95
	return entries, nil
96
}
97

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.