Documentation
¶
Index ¶
- func ChangeLineIndexByIdentity(parsed *Patch) map[LineIdentity]int
- func ChangeLineIndicesForLines(parsed *Patch, lines []LineIdentity) []int
- func ExpandRange(start int, end int) []int
- type FormatViewOpts
- type Hunk
- type LineIdentity
- type Patch
- func (self *Patch) AdjustLineNumber(lineNumber int) int
- func (self *Patch) ContainsChanges() bool
- func (self *Patch) FormatPlain() string
- func (self *Patch) FormatRangePlain(startIdx int, endIdx int) string
- func (self *Patch) FormatView(opts FormatViewOpts) string
- func (self *Patch) GetNextChangeIdx(idx int) int
- func (self *Patch) GetNextChangeIdxOfSameIncludedState(idx int, includedLines []int, included bool) (int, bool)
- func (self *Patch) HunkContainingLine(idx int) int
- func (self *Patch) HunkCount() int
- func (self *Patch) HunkEndIdx(hunkIndex int) int
- func (self *Patch) HunkOldStartForLine(idx int) int
- func (self *Patch) HunkStartIdx(hunkIndex int) int
- func (self *Patch) IsWellFormed() bool
- func (self *Patch) IsWellFormedSoFar() bool
- func (self *Patch) LineCount() int
- func (self *Patch) LineNumberOfLine(idx int) int
- func (self *Patch) Lines() []*PatchLine
- func (self *Patch) OldLineNumberOfLine(idx int) int
- func (self *Patch) Transform(opts TransformOpts) *Patch
- type PatchBuilder
- func (p *PatchBuilder) Active() bool
- func (p *PatchBuilder) AddFileLineRange(filename string, previousPath string, lineIndices []int) error
- func (p *PatchBuilder) AddFileWhole(filename string, previousPath string) error
- func (p *PatchBuilder) AllFilesInPatch() []string
- func (p *PatchBuilder) FilesInPatch() []PatchFile
- func (p *PatchBuilder) Generation() int
- func (p *PatchBuilder) GetFileIncLineIndices(filename string, previousPath string) ([]int, error)
- func (p *PatchBuilder) GetFileStatus(filename string, parent string) PatchStatus
- func (p *PatchBuilder) IncludedChangeLineIndices(filename string) []int
- func (p *PatchBuilder) IncludedLineIdentities(filename string) []LineIdentity
- func (p *PatchBuilder) IsEmpty() bool
- func (p *PatchBuilder) NewPatchRequired(from string, to string, reverse bool) bool
- func (p *PatchBuilder) PatchLineIndicesForLines(filename string, previousPath string, lines []LineIdentity) (indices []int, everyChange bool, err error)
- func (p *PatchBuilder) PatchToApply(reverse bool, turnAddedFilesIntoDiffAgainstEmptyFile bool) string
- func (p *PatchBuilder) RemoveFile(filename string, previousPath string) error
- func (p *PatchBuilder) RemoveFileLineRange(filename string, previousPath string, lineIndices []int) error
- func (p *PatchBuilder) RenderAggregatedPatch(plain bool) string
- func (p *PatchBuilder) RenderPatchForFile(opts RenderPatchForFileOpts) string
- func (p *PatchBuilder) Reset()
- func (p *PatchBuilder) Start(from, to string, reverse bool, canRebase bool)
- func (p *PatchBuilder) TempDir() string
- type PatchFile
- type PatchLine
- type PatchLineKind
- type PatchStatus
- type RenderPatchForFileOpts
- type TransformOpts
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ChangeLineIndexByIdentity ¶ added in v0.66.0
func ChangeLineIndexByIdentity(parsed *Patch) map[LineIdentity]int
ChangeLineIndexByIdentity indexes a parsed diff's change lines by their identity. An addition is numbered in the new file and a deletion in the old one. Two consecutive deletions share the one new-file position between them, and numbering them in the old file keeps them apart.
func ChangeLineIndicesForLines ¶ added in v0.66.0
func ChangeLineIndicesForLines(parsed *Patch, lines []LineIdentity) []int
ChangeLineIndicesForLines maps the given change lines of a parsed diff to their indices in it. A line that names no change line of the diff — a context line, or a line that isn't in the diff at all — contributes nothing.
func ExpandRange ¶ added in v0.38.0
helper function that takes a start and end index and returns a slice of all indexes inbetween (inclusive)
Types ¶
type FormatViewOpts ¶ added in v0.38.0
type LineIdentity ¶ added in v0.66.0
LineIdentity says which change line of a file is meant — the line number it has on the side it belongs to, and whether it is a deletion — without reference to where that line sits in the file's parsed diff.
It is how a diff shown in the main view speaks about its lines: what a rendered row resolves to is a line of a file, while the index of that line in the diff depends on how much of the diff is being shown and in what order a renderer laid it out.
type Patch ¶ added in v0.38.0
type Patch struct {
// contains filtered or unexported fields
}
func (*Patch) AdjustLineNumber ¶ added in v0.45.0
Adjust the given line number (one-based) according to the current patch. The patch is supposed to be a diff of an old file state against the working directory; the line number is a line number in that old file, and the function returns the corresponding line number in the working directory file.
func (*Patch) ContainsChanges ¶ added in v0.38.0
func (*Patch) FormatPlain ¶ added in v0.38.0
Returns the patch as a plain string
func (*Patch) FormatRangePlain ¶ added in v0.38.0
Returns a range of lines from the patch as a plain string (range is inclusive)
func (*Patch) FormatView ¶ added in v0.38.0
func (self *Patch) FormatView(opts FormatViewOpts) string
Returns the patch as a string with ANSI color codes for displaying in a view
func (*Patch) GetNextChangeIdx ¶ added in v0.38.0
Returns the patch line index of the next change (i.e. addition or deletion).
func (*Patch) GetNextChangeIdxOfSameIncludedState ¶ added in v0.53.0
func (self *Patch) GetNextChangeIdxOfSameIncludedState(idx int, includedLines []int, included bool) (int, bool)
Returns the patch line index of the next change (i.e. addition or deletion) that matches the same "included" state, given the includedLines. If you don't care about included states, pass nil for includedLines and false for included.
func (*Patch) HunkContainingLine ¶ added in v0.38.0
Returns hunk index containing the line at the given patch line index
func (*Patch) HunkEndIdx ¶ added in v0.38.0
Returns the patch line index of the last line in the given hunk
func (*Patch) HunkOldStartForLine ¶ added in v0.61.0
Returns the old-file starting line number of the hunk containing the given patch line index. Returns 0 if the line is not inside any hunk.
func (*Patch) HunkStartIdx ¶ added in v0.38.0
Returns the patch line index of the first line in the given hunk
func (*Patch) IsWellFormed ¶ added in v0.66.0
IsWellFormed reports whether every hunk's body matches the lengths declared in its header. A faithful unified diff always satisfies this; a rendering that restructured the diff body does not — a diff renderer that puts line numbers in a gutter, say, shifts the +/- marker off the start of each line, so every body line reads as context and the computed lengths no longer match the header. That makes this the test for whether a rendered diff can be parsed as a unified diff at all, rather than trusting a mis-parse. Only meaningful for patches produced by Parse, which is where the declared lengths come from.
func (*Patch) IsWellFormedSoFar ¶ added in v0.66.0
IsWellFormedSoFar is IsWellFormed for a patch parsed from a diff we have only the beginning of. Its last hunk holds the first lines of a body that hasn't all arrived, so every hunk but the last has to match its header exactly, as before, while the last one only has to fit within what its header declares.
The check exists to tell a faithful rendering from a restructured one, and it still does that. A rendering that moves the +/- marker off the start of the line makes us read a change as context, and a context line counts towards both lengths, so such a hunk comes out longer than its header declares rather than shorter.
func (*Patch) LineNumberOfLine ¶ added in v0.38.0
Takes a line index in the patch and returns the line number in the new file. If the line is a header line, returns 1. If the line is a hunk header line, returns the first file line number in that hunk. If the line is out of range below, returns the last file line number in the last hunk.
func (*Patch) OldLineNumberOfLine ¶ added in v0.66.0
Takes a line index in the patch and returns the line number in the old file. This is the old-file counterpart of LineNumberOfLine; for a deletion it gives the line's position in the old file (additions get the position they sit at). If the line is a header line, returns 1. If the line is a hunk header line, returns the first old-file line number in that hunk. If the line is out of range below, returns the last old-file line number in the last hunk.
func (*Patch) Transform ¶ added in v0.38.0
func (self *Patch) Transform(opts TransformOpts) *Patch
Returns a new patch with the specified transformation applied (e.g. only selecting a subset of changes). Leaves the original patch unchanged.
type PatchBuilder ¶ added in v0.38.0
type PatchBuilder struct {
// To is the commit hash if we're dealing with files of a commit, or a stash ref for a stash
To string
From string
// CanRebase tells us whether we're allowed to modify our commits. CanRebase should be true for commits of the currently checked out branch and false for everything else
// TODO: move this out into a proper mode struct in the gui package: it doesn't really belong here
CanRebase bool
Log *logrus.Entry
// contains filtered or unexported fields
}
PatchBuilder manages the building of a patch for a commit to be applied to another commit (or the working tree, or removed from the current commit). We also support building patches from things like stashes, for which there is less flexibility
func NewPatchBuilder ¶ added in v0.38.0
func NewPatchBuilder( log *logrus.Entry, loadFileDiff loadFileDiffFunc, newTempDir func() (string, error), ) *PatchBuilder
func (*PatchBuilder) Active ¶ added in v0.38.0
func (p *PatchBuilder) Active() bool
func (*PatchBuilder) AddFileLineRange ¶ added in v0.38.0
func (p *PatchBuilder) AddFileLineRange(filename string, previousPath string, lineIndices []int) error
func (*PatchBuilder) AddFileWhole ¶ added in v0.38.0
func (p *PatchBuilder) AddFileWhole(filename string, previousPath string) error
func (*PatchBuilder) AllFilesInPatch ¶ added in v0.38.0
func (p *PatchBuilder) AllFilesInPatch() []string
func (*PatchBuilder) FilesInPatch ¶ added in v0.66.0
func (p *PatchBuilder) FilesInPatch() []PatchFile
FilesInPatch says which files the patch touches, in a stable order, and where each of them comes from.
func (*PatchBuilder) Generation ¶ added in v0.66.0
func (p *PatchBuilder) Generation() int
Generation says which version of the patch this is; see the field.
func (*PatchBuilder) GetFileIncLineIndices ¶ added in v0.38.0
func (p *PatchBuilder) GetFileIncLineIndices(filename string, previousPath string) ([]int, error)
func (*PatchBuilder) GetFileStatus ¶ added in v0.38.0
func (p *PatchBuilder) GetFileStatus(filename string, parent string) PatchStatus
func (*PatchBuilder) IncludedChangeLineIndices ¶ added in v0.66.0
func (p *PatchBuilder) IncludedChangeLineIndices(filename string) []int
IncludedChangeLineIndices says which of filename's change lines are in the patch, as their indices in the file's diff and in the order the file has them.
It is how a line of the patch as it is shown names the line of the diff it came from: all that can be said about a line of the patch is which of the file's changes it is, its line numbers being the patch's own — a patch that leaves an earlier addition out numbers everything after it differently from the diff it was built from.
func (*PatchBuilder) IncludedLineIdentities ¶ added in v0.66.0
func (p *PatchBuilder) IncludedLineIdentities(filename string) []LineIdentity
IncludedLineIdentities says which change lines of filename are in the patch, as the identities a diff of that file shown anywhere can be compared against. Empty for a file that is no part of the patch.
func (*PatchBuilder) IsEmpty ¶ added in v0.38.0
func (p *PatchBuilder) IsEmpty() bool
func (*PatchBuilder) NewPatchRequired ¶ added in v0.38.0
func (p *PatchBuilder) NewPatchRequired(from string, to string, reverse bool) bool
if any of these things change we'll need to reset and start a new patch
func (*PatchBuilder) PatchLineIndicesForLines ¶ added in v0.66.0
func (p *PatchBuilder) PatchLineIndicesForLines( filename string, previousPath string, lines []LineIdentity, ) (indices []int, everyChange bool, err error)
PatchLineIndicesForLines maps change lines of filename to their indices in that file's diff; the patch is built in terms of those indices. everyChange reports whether the given lines cover all of the file's changes; this distinguishes acting on some of a file's lines from acting on the file itself.
func (*PatchBuilder) PatchToApply ¶ added in v0.39.0
func (p *PatchBuilder) PatchToApply(reverse bool, turnAddedFilesIntoDiffAgainstEmptyFile bool) string
func (*PatchBuilder) RemoveFile ¶ added in v0.38.0
func (p *PatchBuilder) RemoveFile(filename string, previousPath string) error
func (*PatchBuilder) RemoveFileLineRange ¶ added in v0.38.0
func (p *PatchBuilder) RemoveFileLineRange(filename string, previousPath string, lineIndices []int) error
func (*PatchBuilder) RenderAggregatedPatch ¶ added in v0.38.0
func (p *PatchBuilder) RenderAggregatedPatch(plain bool) string
func (*PatchBuilder) RenderPatchForFile ¶ added in v0.38.0
func (p *PatchBuilder) RenderPatchForFile(opts RenderPatchForFileOpts) string
func (*PatchBuilder) Start ¶ added in v0.38.0
func (p *PatchBuilder) Start(from, to string, reverse bool, canRebase bool)
func (*PatchBuilder) TempDir ¶ added in v0.66.0
func (p *PatchBuilder) TempDir() string
TempDir is the directory the patch is materialized into for rendering, and "" when there is none — no patch, or a directory we failed to make.
type PatchFile ¶ added in v0.66.0
type PatchFile struct {
// Path is the name the patch knows the file by: for a renamed file, the name it had
// before where the patch carries the rename, and the name it was renamed to where the
// patch keeps only a content change and leaves the rename behind.
Path string
// ContentPath is where the file's content before the patch is to be found in the
// commit the patch is built from — for a renamed file always the name it had there,
// whatever the patch calls it.
ContentPath string
}
PatchFile records what materializing the patch needs to know about one of its files: where the patch expects to find it, and where its content before the patch comes from.
type PatchLine ¶
type PatchLine struct {
Kind PatchLineKind
Content string // something like '+ hello' (note the first character is not removed)
}
func (*PatchLine) IsAddition ¶ added in v0.61.0
func (*PatchLine) IsDeletion ¶ added in v0.61.0
type PatchLineKind ¶ added in v0.27.1
type PatchLineKind int
const ( PATCH_HEADER PatchLineKind = iota HUNK_HEADER ADDITION DELETION CONTEXT NEWLINE_MESSAGE )
type PatchStatus ¶ added in v0.27.1
type PatchStatus int
const ( // UNSELECTED is for when the commit file has not been added to the patch in any way UNSELECTED PatchStatus = iota // WHOLE is for when you want to add the whole diff of a file to the patch, // including e.g. if it was deleted WHOLE // PART is for when you're only talking about specific lines that have been modified PART )
type RenderPatchForFileOpts ¶ added in v0.43.0
type TransformOpts ¶ added in v0.38.0
type TransformOpts struct {
// Create a patch that will applied in reverse with `git apply --reverse`.
// This affects how unselected lines are treated when only parts of a hunk
// are selected: usually, for unselected lines we change '-' lines to
// context lines and remove '+' lines, but when Reverse is true we need to
// turn '+' lines into context lines and remove '-' lines.
Reverse bool
// If set, we will replace the original header with one referring to this file name.
// For staging/unstaging lines we don't want the original header because
// it makes git confused e.g. when dealing with deleted/added files
// but with building and applying patches the original header gives git
// information it needs to cleanly apply patches
FileNameOverride string
// Custom patches tend to work better when treating new files as diffs
// against an empty file. The only case where we need this to be false is
// when moving a custom patch to an earlier commit; in that case the patch
// command would fail with the error "file does not exist in index" if we
// treat it as a diff against an empty file.
TurnAddedFilesIntoDiffAgainstEmptyFile bool
// When building a partial patch for a renamed file, strip the rename
// metadata from the header and point it at the new path. Applying the
// resulting patch then only changes the file's contents and leaves the
// rename itself in place. (For a whole-file selection we keep the rename
// so that it moves or is discarded together with the contents.)
StripRename bool
// The indices of lines that should be included in the patch.
IncludedLineIndices []int
}