@@ -2,7 +2,7 @@ use gix_merge::blob::Platform;
22use gix_worktree:: stack:: state:: attributes;
33
44mod merge {
5- use std:: { convert:: Infallible , process:: Stdio } ;
5+ use std:: { convert:: Infallible , path :: Path , process:: Stdio } ;
66
77 use bstr:: { BStr , ByteSlice } ;
88 use gix_merge:: blob:: {
@@ -361,6 +361,98 @@ theirs
361361 Ok ( ( ) )
362362 }
363363
364+ #[ test]
365+ #[ cfg( not( windows) ) ] // assertions aren't handling Windows paths, and there is no need.
366+ /// This test is a complex behavioural test for an external merge driver similar to `mergiraf`.
367+ fn with_external_mergiraf_like_driver_uses_worktree_tempfiles_from_context ( ) -> crate :: Result {
368+ let mut platform = new_platform (
369+ [ gix_merge:: blob:: Driver {
370+ name : "b" . into ( ) ,
371+ command : r#"for input in "%O" "%A" "%B"; do
372+ case "$input" in
373+ "$GIT_WORK_TREE"/*) ;;
374+ *)
375+ echo "$input is outside of $GIT_WORK_TREE" >&2
376+ exit 1
377+ ;;
378+ esac
379+ done
380+ meta="%A.mergiraf"
381+ printf '%s\n' "$GIT_DIR" "$GIT_WORK_TREE" "%O" "%A" "%B" "%P" "%S" "%X" "%Y" "%L" > "$meta"
382+ cat "$meta" > "%A"
383+ printf '%s\n' "--base--" >> "%A"
384+ cat "%O" >> "%A"
385+ printf '%s\n' "--theirs--" >> "%A"
386+ cat "%B" >> "%A""#
387+ . into ( ) ,
388+ ..Default :: default ( )
389+ } ] ,
390+ pipeline:: Mode :: ToGit ,
391+ ) ;
392+
393+ let mut db = ObjectDb :: default ( ) ;
394+ for ( content, kind) in [
395+ ( "base" , ResourceKind :: CommonAncestorOrBase ) ,
396+ ( "ours" , ResourceKind :: CurrentOrOurs ) ,
397+ ( "theirs" , ResourceKind :: OtherOrTheirs ) ,
398+ ] {
399+ let id = db. insert ( content) ?;
400+ platform. set_resource ( id, EntryKind :: Blob , "b" . into ( ) , kind, & db) ?;
401+ }
402+
403+ let platform_ref = platform. prepare_merge ( & db, Default :: default ( ) ) ?;
404+ let worktree = gix_testtools:: tempfile:: TempDir :: new ( ) ?;
405+ let git_dir = worktree. path ( ) . join ( ".git" ) ;
406+ std:: fs:: create_dir ( & git_dir) ?;
407+
408+ let mut buf = Vec :: new ( ) ;
409+ let res = platform_ref. merge (
410+ & mut buf,
411+ default_labels ( ) ,
412+ & gix_command:: Context {
413+ git_dir : Some ( git_dir. clone ( ) ) ,
414+ worktree_dir : Some ( worktree. path ( ) . to_owned ( ) ) ,
415+ ..Default :: default ( )
416+ } ,
417+ ) ?;
418+ assert_eq ! ( res, ( Pick :: Buffer , Resolution :: Complete ) ) ;
419+
420+ let mut lines = buf. lines ( ) ;
421+ assert_eq ! ( Path :: new( lines. next( ) . expect( "git dir" ) . to_str( ) ?) , git_dir. as_path( ) ) ;
422+ assert_eq ! (
423+ Path :: new( lines. next( ) . expect( "worktree dir" ) . to_str( ) ?) ,
424+ worktree. path( )
425+ ) ;
426+ for tmp_path in lines. by_ref ( ) . take ( 3 ) {
427+ assert ! (
428+ Path :: new( tmp_path. to_str( ) ?) . starts_with( worktree. path( ) ) ,
429+ "{:?}" ,
430+ tmp_path. as_bstr( )
431+ ) ;
432+ }
433+
434+ let lines: Vec < _ > = lines
435+ . map ( |line| line. to_str ( ) . expect ( "driver output is valid UTF-8" ) )
436+ . collect ( ) ;
437+ assert_eq ! (
438+ lines,
439+ [
440+ "'b'" ,
441+ "'ancestor label'" ,
442+ "'current label'" ,
443+ "'other label'" ,
444+ "7" ,
445+ "--base--" ,
446+ "b" ,
447+ "--theirs--" ,
448+ "theirs"
449+ ] ,
450+ "a mergiraf-like driver can create sidecar files next to %A and gets tempfiles inside GIT_WORK_TREE"
451+ ) ;
452+
453+ Ok ( ( ) )
454+ }
455+
364456 #[ test]
365457 fn missing_buffers_are_empty_buffers ( ) -> crate :: Result {
366458 let mut platform = new_platform ( None , pipeline:: Mode :: ToGit ) ;
0 commit comments