diff --git a/repo_tree.go b/repo_tree.go index d1a3f466..fe01ea48 100644 --- a/repo_tree.go +++ b/repo_tree.go @@ -7,6 +7,7 @@ package git import ( "bytes" "fmt" + "strings" "time" ) @@ -31,7 +32,7 @@ var ( // parseTree parses tree information from the (uncompressed) raw data of the // tree object. -func parseTree(t *Tree, data []byte) ([]*TreeEntry, error) { +func parseTree(t *Tree, data []byte, lineTerminator byte) ([]*TreeEntry, error) { entries := make([]*TreeEntry, 0, 10) l := len(data) pos := 0 @@ -70,7 +71,7 @@ func parseTree(t *Tree, data []byte) ([]*TreeEntry, error) { entry.id = id pos += step + 1 // Skip half of SHA1. - step = bytes.IndexByte(data[pos:], '\n') + step = bytes.IndexByte(data[pos:], lineTerminator) // In case entry name is surrounded by double quotes(it happens only in git-shell). if data[pos] == '"' { @@ -129,7 +130,19 @@ func (r *Repository) LsTree(treeID string, opts ...LsTreeOptions) (*Tree, error) return nil, err } - t.entries, err = parseTree(t, stdout) + outputVerbatim := false + for _, arg := range opt.CommandOptions.Args { + if strings.TrimSpace(arg) == "-z" { + outputVerbatim = true + break + } + } + var lineTerminator byte = '\n' + if outputVerbatim { + lineTerminator = '\u0000' + } + + t.entries, err = parseTree(t, stdout, lineTerminator) if err != nil { return nil, err } diff --git a/repo_tree_test.go b/repo_tree_test.go index bf398046..c23929f4 100644 --- a/repo_tree_test.go +++ b/repo_tree_test.go @@ -11,17 +11,36 @@ import ( ) func TestRepository_LsTree(t *testing.T) { - // Make sure it does not blow up - tree, err := testrepo.LsTree("master", LsTreeOptions{}) - if err != nil { - t.Fatal(err) + tests := []struct { + options LsTreeOptions + }{ + { + options: LsTreeOptions{}, + }, + { + options: LsTreeOptions{ + CommandOptions: CommandOptions{ + Args: []string{"-z"}, + }, + }, + }, } - assert.NotNil(t, tree) - // Tree ID for "gogs/" directory - tree, err = testrepo.LsTree("fcf7087e732bfe3c25328248a9bf8c3ccd85bed4", LsTreeOptions{}) - if err != nil { - t.Fatal(err) + for _, test := range tests { + t.Run("", func(t *testing.T) { + // Make sure it does not blow up + tree, err := testrepo.LsTree("master", test.options) + if err != nil { + t.Fatal(err) + } + assert.NotNil(t, tree) + + // Tree ID for "gogs/" directory + tree, err = testrepo.LsTree("fcf7087e732bfe3c25328248a9bf8c3ccd85bed4", test.options) + if err != nil { + t.Fatal(err) + } + assert.NotNil(t, tree) + }) } - assert.NotNil(t, tree) }