v0.1.1 de06cbd

stat.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package git
4
5import (
6	"errors"
7	"io"
8	"syscall"
9	"time"
10)
11
12// fileStat is the part of a stat result that change detection uses.
13type fileStat struct {
14	exists bool
15	isDir  bool
16	size   int64
17	mtime  int64 // unix nanoseconds
18	ino    uint64
19}
20
21// statPath is a path prepared once, so that stat-ing it again and again (what
22// Refresh does) does not build a string, nor the NUL-terminated copy of it
23// that the system call takes, at each call.
24type statPath struct {
25	nul []byte // the path and a NUL byte
26}
27
28func newStatPath(path string) statPath {
29	return statPath{nul: append([]byte(path), 0)}
30}
31
32func (p *statPath) path() string { return string(p.nul[:len(p.nul)-1]) }
33
34// stat returns the stat data of the path, following symbolic links unless
35// lstat. A path that is absent, or has a file in place of a directory on the
36// way, is not an error: exists is false.
37func (p *statPath) stat(lstat bool) (fileStat, error) {
38	var st fileStat
39	err := statNul(p.nul, lstat, &st)
40	return st, err
41}
42
43// sig returns the signature of the file. The time of the read is taken
44// before the stat, see sigOf.
45func (p *statPath) sig() (fileSig, error) {
46	read := time.Now().UnixNano()
47	st, err := p.stat(false)
48	if err != nil {
49		return fileSig{}, err
50	}
51	if !st.exists {
52		return fileSig{read: read}, nil
53	}
54	return fileSig{exists: true, size: st.size, mtime: st.mtime, ino: st.ino, read: read}, nil
55}
56
57// readFull reads the file into buf until buf is full or the file ends, and
58// returns the number of bytes. A directory reads as an empty, missing file:
59// dir is true.
60func (f rawFile) readFull(buf []byte) (n int, dir bool, err error) {
61	for n < len(buf) {
62		m, err := f.read(buf[n:])
63		n += m
64		if err != nil {
65			if errors.Is(err, io.EOF) {
66				break
67			}
68			if errors.Is(err, syscall.EISDIR) {
69				return 0, true, nil
70			}
71			return n, false, err
72		}
73	}
74	return n, false, nil
75}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 2

↑↓ moveenter openesc close