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  }