Module: Amp::Merges::MergeUI
- Included in:
- UI
- Defined in:
- lib/amp/merges/merge_ui.rb
Overview
This module handles figuring out how to merge files using the user’s preferences. It is mixed into the UI class. The UI class must implement the “config” method.
Instance Method Summary collapse
-
#file_merge(repo, parent_node, original_fn, vf_local, vf_other, vf_ancestor) ⇒ Boolean
Performs a 3-way merge in the working directory from vf_local to vf_other, using the common ancestor vf_ancestor.
Instance Method Details
#file_merge(repo, parent_node, original_fn, vf_local, vf_other, vf_ancestor) ⇒ Boolean
TODO:
change 1s and 0s to bools
TODO:
consistent return type
Performs a 3-way merge in the working directory from vf_local to vf_other, using the common ancestor vf_ancestor.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/amp/merges/merge_ui.rb', line 26 def file_merge(repo, parent_node, original_fn, vf_local, vf_other, vf_ancestor) is_binary = proc {|ctx| ctx.data.binary? rescue false} return nil if !(vf_other.cmp vf_local.data) path = vf_local.path binary = is_binary[vf_local] || is_binary[vf_other] || is_binary[vf_ancestor] symlink = (vf_local.flags + vf_other.flags).include? "l" tool, tool_path = pick_tool(repo, path, binary, symlink) UI.status("Picked tool #{tool} for #{path} (binary #{binary} symlink #{symlink})") unless tool tool = "internal:local" if UI.ask("no tool found to merge #{path}\n"+ "keep (l)ocal or take (o)ther?") != "l" tool = "internal:other" end end case tool when "internal:local" return 0 when "internal:other" repo.working_write(path, vf_other.data, vf_other.flags) return 0 when "internal:fail" return 1 end a = repo.working_join(path) b_file = save_versioned_file_temp("base", vf_ancestor) c_file = save_versioned_file_temp("other", vf_other) b, c = b_file.path, c_file.path out = "" back = a + ".orig" + File.extname(a) File.copy(a, back) if original_fn != vf_other.path UI.status("merging #{original_fn} and #{vf_other.path} to #{path}") else UI.status("merging #{path}") end if tool_setting(tool, "premerge", !(binary || symlink)) ret = ThreeWayMerger.three_way_merge(a, b, c, :quiet => true) unless ret UI.debug("premerge successful") File.unlink(back) File.safe_unlink(b) File.safe_unlink(c) return false end File.copy(back, a) # restore frmo backup and try again end environment = {"HG_FILE" => path, "HG_MY_NODE" => parent_node.hexlify[0..11], "HG_OTHER_NODE" => vf_other.changeset.to_s, "HG_MY_ISLINK" => vf_local.flags.include?("l"), "HG_OTHER_ISLINK" => vf_other.flags.include?("l"), "HG_BASE_ISLINK" => vf_ancestor.flags.include?("l")} if tool == "internal:merge" ret = ThreeWayMerger.three_way_merge(a, b, c, :label => ['local', 'other']) else args = tool_setting_string(tool, "args", "$local $base $other") if args.include?("$output") out, a = a, back # read input from backup, write to original end replace = {"local" => a, "base" => b, "other" => c, "output" => out} args.gsub!(/\$(local|base|other|output)/) { replace[$1]} # shelling out ret = Amp::Support::system(tool_path+" "+args, :chdir => repo.root, :environ => environment) end ret = (ret == true ? 1 : (ret == false ? 0 : ret)) if ret == 0 && tool_setting(tool, "checkconflicts") if vf_local.data =~ /^(<<<<<<< .*|=======|>>>>>>> .*)$/ ret = 1 end end if ret == 0 && tool_setting(tool, "checkchanged") if File.stat(repo.working_join(path)) === File.stat(back) if UI::yes_or_no "output file #{path} appears unchanged\nwas merge successful?" r = 1 end end end fix_end_of_lines(repo.working_join(path), back) if tool_setting(tool, "fixeol") if ret == 1 UI::warn "merging #{path} failed!" else File.unlink back end File.unlink b File.unlink c !ret.zero? # return end |