Skip to content

Commit

Permalink
Add support for diff3 conflict styling
Browse files Browse the repository at this point in the history
  • Loading branch information
mkchoi212 committed May 12, 2018
1 parent b0d661b commit a04cfa0
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 21 deletions.
44 changes: 44 additions & 0 deletions conflict/conflict.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package conflict

import (
"sort"
"strings"

"github.com/mkchoi212/fac/color"
Expand All @@ -14,8 +15,10 @@ type Conflict struct {
Start int
Middle int
End int
Diff3 []int

LocalLines []string
LocalPureLines []string
IncomingLines []string
ColoredLocalLines []string
ColoredIncomingLines []string
Expand All @@ -28,6 +31,39 @@ type Conflict struct {
DisplayDiff bool
}

// Supported git conflict styles
const (
text = iota
start
diff3
separator
end
)

// IdentifyStyle identifies the conflict marker style of provided text
func IdentifyStyle(line string) (style int) {
line = strings.TrimSpace(line)

if strings.Contains(line, "<<<<<<<") {
style = start
} else if strings.Contains(line, ">>>>>>>") {
style = end
} else if line == "||||||| merged common ancestors" {
style = diff3
} else if line == "=======" {
style = separator
} else {
style = text
}
return
}

// Valid checks if the parsed conflict has corresponding begin, separator,
// and middle line numbers
func (c *Conflict) Valid() bool {
return c.Middle != 0 && c.End != 0
}

func (c *Conflict) Equal(c2 *Conflict) bool {
return c.AbsolutePath == c2.AbsolutePath && c.Start == c2.Start
}
Expand All @@ -37,8 +73,16 @@ func (c *Conflict) ToggleDiff() {
}

// Extract extracts lines where conflicts exist
// and corresponding branch names
func (c *Conflict) Extract(lines []string) error {
c.LocalLines = lines[c.Start : c.Middle-1]
if len(c.Diff3) != 0 {
sort.Ints(c.Diff3)
diff3Barrier := c.Diff3[0]
c.LocalPureLines = lines[c.Start : diff3Barrier-1]
} else {
c.LocalPureLines = c.LocalLines
}
c.IncomingLines = lines[c.Middle : c.End-1]
c.CurrentName = strings.Split(lines[c.Start-1], " ")[1]
c.ForeignName = strings.Split(lines[c.End-1], " ")[1]
Expand Down
42 changes: 29 additions & 13 deletions conflict/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,39 @@ func parseGitMarkerInfo(diff string, dict map[string][]int) error {
return nil
}

func newConflicts(absPath string, fname string, lines []int) ([]Conflict, error) {
func newConflicts(absPath string, fname string, markerLocations []int) ([]Conflict, error) {
parsedConflicts := []Conflict{}

if len(lines)%3 != 0 {
return nil, errors.New("Invalid number of remaining conflict markers")
lines := FileLines[absPath]

var conf Conflict

for _, lineNum := range markerLocations {
line := lines[lineNum-1]

switch IdentifyStyle(line) {
case start:
conf = Conflict{}
conf.AbsolutePath = absPath
conf.FileName = fname
conf.Start = lineNum
case separator:
conf.Middle = lineNum
case diff3:
conf.Diff3 = append(conf.Diff3, lineNum)
case end:
conf.End = lineNum
parsedConflicts = append(parsedConflicts, conf)
default:
continue
}
}

conf := Conflict{}
for i := 0; i < len(lines); i++ {
conf.Start = lines[i]
conf.Middle = lines[i+1]
conf.End = lines[i+2]
conf.AbsolutePath = absPath
conf.FileName = fname
parsedConflicts = append(parsedConflicts, conf)
// Verify all markers are properly parsed/paired
for _, c := range parsedConflicts {
if !(c.Valid()) {
return nil, errors.New("Invalid number of remaining conflict markers")
}
}

return parsedConflicts, nil
}

Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func parseInput(g *gocui.Gui, v *gocui.View) error {

func main() {
//cwd, _ := os.Getwd()
cwd := "./test"
cwd := "./assets/dummy_repo"
conflicts, err := conflict.Find(cwd)
if err != nil {
fmt.Println(color.Red(color.Regular, err.Error()))
Expand Down
15 changes: 8 additions & 7 deletions summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ func printSummary() {
fmt.Println(buf.String())
}

func writeChanges(absPath string) (err error) {
func writeChanges(absPath string, lines []string) (err error) {
f, err := os.Create(absPath)
if err != nil {
return
}
defer f.Close()

w := bufio.NewWriter(f)
for _, line := range conflict.FileLines[absPath] {
for _, line := range lines {
if _, err = w.WriteString(line); err != nil {
return
}
Expand All @@ -74,29 +74,30 @@ func writeChanges(absPath string) (err error) {
return
}

// FinalizeChanges writes the changes the user selected
// FinalizeChanges writes the changes the user selected to file
func FinalizeChanges(absPath string) (err error) {
targetConflicts := conflict.In(all, absPath)

var replacementLines []string
fileLines := conflict.FileLines[absPath]

for _, c := range targetConflicts {
if c.Choice == Local {
replacementLines = append([]string{}, c.LocalLines...)
replacementLines = append([]string{}, c.LocalPureLines...)
} else {
replacementLines = append([]string{}, c.IncomingLines...)
}

i := 0
for ; i < len(replacementLines); i++ {
conflict.FileLines[absPath][c.Start+i-1] = replacementLines[i]
fileLines[c.Start+i-1] = replacementLines[i]
}
for ; c.End-c.Start >= i; i++ {
conflict.FileLines[absPath][c.Start+i-1] = ""
fileLines[c.Start+i-1] = ""
}
}

if err = writeChanges(absPath); err != nil {
if err = writeChanges(absPath, fileLines); err != nil {
return
}
return
Expand Down

0 comments on commit a04cfa0

Please sign in to comment.