Use git log name-status in get last commit (#16059)
* Improve get last commit using git log --name-status git log --name-status -c provides information about the diff between a commit and its parents. Using this and adjusting the algorithm to use the first change to a path allows for a much faster generation of commit info. There is a subtle change in the results generated but this will cause the results to more closely match those from elsewhere. Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
parent
8fa3bbc424
commit
23358bc55d
40 changed files with 2540 additions and 297 deletions
185
vendor/github.com/djherbis/buffer/multi.go
generated
vendored
Normal file
185
vendor/github.com/djherbis/buffer/multi.go
generated
vendored
Normal file
|
@ -0,0 +1,185 @@
|
|||
package buffer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"io"
|
||||
"math"
|
||||
)
|
||||
|
||||
type chain struct {
|
||||
Buf BufferAt
|
||||
Next BufferAt
|
||||
}
|
||||
|
||||
type nopBufferAt struct {
|
||||
Buffer
|
||||
}
|
||||
|
||||
func (buf *nopBufferAt) ReadAt(p []byte, off int64) (int, error) {
|
||||
panic("ReadAt not implemented")
|
||||
}
|
||||
|
||||
func (buf *nopBufferAt) WriteAt(p []byte, off int64) (int, error) {
|
||||
panic("WriteAt not implemented")
|
||||
}
|
||||
|
||||
// toBufferAt converts a Buffer to a BufferAt with nop ReadAt and WriteAt funcs
|
||||
func toBufferAt(buf Buffer) BufferAt {
|
||||
return &nopBufferAt{Buffer: buf}
|
||||
}
|
||||
|
||||
// NewMultiAt returns a BufferAt which is the logical concatenation of the passed BufferAts.
|
||||
// The data in the buffers is shifted such that there is no non-empty buffer following
|
||||
// a non-full buffer, this process is also run after every Read.
|
||||
// If no buffers are passed, the returned Buffer is nil.
|
||||
func NewMultiAt(buffers ...BufferAt) BufferAt {
|
||||
if len(buffers) == 0 {
|
||||
return nil
|
||||
} else if len(buffers) == 1 {
|
||||
return buffers[0]
|
||||
}
|
||||
|
||||
buf := &chain{
|
||||
Buf: buffers[0],
|
||||
Next: NewMultiAt(buffers[1:]...),
|
||||
}
|
||||
|
||||
buf.Defrag()
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// NewMulti returns a Buffer which is the logical concatenation of the passed buffers.
|
||||
// The data in the buffers is shifted such that there is no non-empty buffer following
|
||||
// a non-full buffer, this process is also run after every Read.
|
||||
// If no buffers are passed, the returned Buffer is nil.
|
||||
func NewMulti(buffers ...Buffer) Buffer {
|
||||
bufAt := make([]BufferAt, len(buffers))
|
||||
for i, buf := range buffers {
|
||||
bufAt[i] = toBufferAt(buf)
|
||||
}
|
||||
return NewMultiAt(bufAt...)
|
||||
}
|
||||
|
||||
func (buf *chain) Reset() {
|
||||
buf.Next.Reset()
|
||||
buf.Buf.Reset()
|
||||
}
|
||||
|
||||
func (buf *chain) Cap() (n int64) {
|
||||
Next := buf.Next.Cap()
|
||||
if buf.Buf.Cap() > math.MaxInt64-Next {
|
||||
return math.MaxInt64
|
||||
}
|
||||
return buf.Buf.Cap() + Next
|
||||
}
|
||||
|
||||
func (buf *chain) Len() (n int64) {
|
||||
Next := buf.Next.Len()
|
||||
if buf.Buf.Len() > math.MaxInt64-Next {
|
||||
return math.MaxInt64
|
||||
}
|
||||
return buf.Buf.Len() + Next
|
||||
}
|
||||
|
||||
func (buf *chain) Defrag() {
|
||||
for !Full(buf.Buf) && !Empty(buf.Next) {
|
||||
r := io.LimitReader(buf.Next, Gap(buf.Buf))
|
||||
if _, err := io.Copy(buf.Buf, r); err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (buf *chain) Read(p []byte) (n int, err error) {
|
||||
n, err = buf.Buf.Read(p)
|
||||
if len(p[n:]) > 0 && (err == nil || err == io.EOF) {
|
||||
m, err := buf.Next.Read(p[n:])
|
||||
n += m
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
buf.Defrag()
|
||||
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (buf *chain) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
if buf.Buf.Len() < off {
|
||||
return buf.Next.ReadAt(p, off-buf.Buf.Len())
|
||||
}
|
||||
|
||||
n, err = buf.Buf.ReadAt(p, off)
|
||||
if len(p[n:]) > 0 && (err == nil || err == io.EOF) {
|
||||
var m int
|
||||
m, err = buf.Next.ReadAt(p[n:], 0)
|
||||
n += m
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (buf *chain) Write(p []byte) (n int, err error) {
|
||||
if n, err = buf.Buf.Write(p); err == io.ErrShortWrite {
|
||||
err = nil
|
||||
}
|
||||
p = p[n:]
|
||||
if len(p) > 0 && err == nil {
|
||||
m, err := buf.Next.Write(p)
|
||||
n += m
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (buf *chain) WriteAt(p []byte, off int64) (n int, err error) {
|
||||
switch {
|
||||
case buf.Buf.Cap() <= off: // past the end
|
||||
return buf.Next.WriteAt(p, off-buf.Buf.Cap())
|
||||
|
||||
case buf.Buf.Cap() >= off+int64(len(p)): // fits in
|
||||
return buf.Buf.WriteAt(p, off)
|
||||
|
||||
default: // partial fit
|
||||
n, err = buf.Buf.WriteAt(p, off)
|
||||
if len(p[n:]) > 0 && (err == nil || err == io.ErrShortWrite) {
|
||||
var m int
|
||||
m, err = buf.Next.WriteAt(p[n:], 0)
|
||||
n += m
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
gob.Register(&chain{})
|
||||
gob.Register(&nopBufferAt{})
|
||||
}
|
||||
|
||||
func (buf *chain) MarshalBinary() ([]byte, error) {
|
||||
b := bytes.NewBuffer(nil)
|
||||
enc := gob.NewEncoder(b)
|
||||
if err := enc.Encode(&buf.Buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := enc.Encode(&buf.Next); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (buf *chain) UnmarshalBinary(data []byte) error {
|
||||
b := bytes.NewBuffer(data)
|
||||
dec := gob.NewDecoder(b)
|
||||
if err := dec.Decode(&buf.Buf); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := dec.Decode(&buf.Next); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue