github.com/driusan/dgit@v0.0.0-20221118233547-f39f0c15edbb/git/mergefile.go (about) 1 package git 2 3 import ( 4 "bytes" 5 "io" 6 "os" 7 "os/exec" 8 ) 9 10 type MergeFileFile struct { 11 Filename File 12 Label string 13 } 14 15 type MergeFileOptions struct { 16 Current, Base, Other MergeFileFile 17 18 Quiet bool 19 Stdout bool 20 Diff3 bool 21 } 22 23 // MergeFile merges changes that lead from opt.Base to opt.Other into opt.Current, 24 // flagging conflictsas appropriate. 25 // 26 // This will return an io.Reader of the merged state rather than directly Current. 27 // 28 // BUG(driusan): this currently invokes an external diff3 tool, which needs to be 29 // installed in order to work. 30 func MergeFile(c *Client, opt MergeFileOptions) (io.Reader, error) { 31 var args []string 32 if opt.Current.Label != "" { 33 args = append(args, "-L", opt.Current.Label) 34 } else { 35 // Ensure there's the right amount of -L specified if base or other happen 36 // to have specified a label but current didn't. 37 args = append(args, "-L", opt.Current.Label) 38 } 39 40 if opt.Base.Label != "" { 41 args = append(args, "-L", opt.Base.Label) 42 } else { 43 args = append(args, "-L", opt.Base.Label) 44 } 45 46 if opt.Other.Label != "" { 47 args = append(args, "-L", opt.Other.Label) 48 } else { 49 // Ensure there's the right amount of -L specified if base or other happen 50 // to have specified a label but current didn't. 51 args = append(args, "-L", opt.Other.Label) 52 } 53 54 // FIXME: There should be a way to get output similar to -A for -X, but 55 // -X doesn't seem to include non-conflicting lines. So for now, this always 56 // uses diff3 output. 57 args = append(args, "-m", "-A") 58 args = append(args, opt.Current.Filename.String(), opt.Base.Filename.String(), opt.Other.Filename.String()) 59 var output bytes.Buffer 60 diff3cmd := exec.Command(posixDiff3, args...) 61 diff3cmd.Stderr = os.Stderr 62 diff3cmd.Stdout = &output 63 err := diff3cmd.Run() 64 return &output, err 65 }