summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/globals.ml13
-rw-r--r--src/recon.ml3
-rw-r--r--src/stasher.ml11
-rw-r--r--src/ubase/prefs.ml19
-rw-r--r--src/ubase/trace.ml5
-rw-r--r--src/ubase/uarg.ml13
-rw-r--r--src/ubase/util.ml13
-rw-r--r--src/ubase/util.mli2
-rw-r--r--src/uitext.ml440
9 files changed, 372 insertions, 147 deletions
diff --git a/src/globals.ml b/src/globals.ml
index d96fb63..009339a 100644
--- a/src/globals.ml
+++ b/src/globals.ml
@@ -260,8 +260,11 @@ let ignorenotPred =
preference to choose particular paths to synchronize.")
let atomic = Pred.create "atomic" ~advanced:true
- ("This preference specifies paths for directories whose \
- contents will be considered as a group rather than individually.")
+ ("This preference specifies paths for directories whose "
+ ^ "contents will be considered as a group rather than individually when "
+ ^ "they are both modified. "
+ ^ "The backups are also made atomically in this case. The option "
+ ^ "\\texttt{backupcurr} however has no effect on atomic directories.")
let shouldIgnore p =
let p = Path.toString p in
@@ -276,10 +279,8 @@ let merge =
Pred.create "merge" ~advanced:true
("This preference can be used to run a merge program which will create "
^ "a new version for each of the files and the backup, "
- ^ "with the last backup and the both replicas. Setting the {\\tt merge} "
- ^ "preference for a path will also cause this path to be backed up, "
- ^ "just like {\tt backup}. "
- ^ "The syntax of \\ARG{pathspec>cmd} is "
+ ^ "with the last backup and both replicas. "
+ ^ "The syntax of \\ARG{pathspec -> cmd} is "
^ "described in \\sectionref{pathspec}{Path Specification}, and further "
^ "details on Merging functions are present in "
^ "\\sectionref{merge}{Merging Conflicting Versions}.")
diff --git a/src/recon.ml b/src/recon.ml
index 2c619bb..490baf1 100644
--- a/src/recon.ml
+++ b/src/recon.ml
@@ -116,7 +116,8 @@ let preferRoot: string Prefs.t =
"!choose this replica's version for conflicting changes"
("Including the preference \\texttt{-prefer \\ARG{root}} causes Unison always to "
^ "resolve conflicts in favor of \\ARG{root}, rather than asking for "
- ^ "guidance from the user. (The syntax of \\ARG{root} is the same as "
+ ^ "guidance from the user, except for paths marked by the preference "
+ ^ "\\texttt{merge}. (The syntax of \\ARG{root} is the same as "
^ "for the \\verb|root| preference, plus the special values "
^ "\\verb|newer| and \\verb|older|.) \n\n"
^ "This preference is overridden by the \\verb|preferpartial| preference.\n\n"
diff --git a/src/stasher.ml b/src/stasher.ml
index f306f89..201c9b2 100644
--- a/src/stasher.ml
+++ b/src/stasher.ml
@@ -39,7 +39,8 @@ let backup =
Pred.create "backup" ~advanced:true
("Including the preference \\texttt{-backup \\ARG{pathspec}} "
^ "causes Unison to keep backup files for each path that matches "
- ^ "\\ARG{pathspec}. These backup files are kept in the "
+ ^ "\\ARG{pathspec}; directories (nor their permissions or any other "
+ ^ " metadata) are not backed up. These backup files are kept in the "
^ "directory specified by the \\verb|backuplocation| preference. The backups are named "
^ "according to the \\verb|backupprefix| and \\verb|backupsuffix| preferences."
^ " The number of versions that are kept is determined by the "
@@ -54,9 +55,7 @@ let backupnot =
("The values of this preference specify paths or individual files or"
^ " regular expressions that should {\\em not} "
^ "be backed up, even if the {\\tt backup} preference selects "
- ^ "them---i.e., "
- ^ "it selectively overrides {\\tt backup}. The same caveats apply here "
- ^ "as with {\\tt ignore} and {\\tt ignorenot}.")
+ ^ "them---i.e., it selectively overrides {\\tt backup}.")
let _ = Pred.alias backupnot "mirrornot"
@@ -159,10 +158,6 @@ let backupcurrentnot =
"Exceptions to \\verb|backupcurr|, like the \\verb|ignorenot| preference."
let shouldBackupCurrent p =
- (* BCP: removed next line [Apr 2007]: causes ALL mergeable files to be backed
- up, which is probably not what users want -- the backupcurrent
- switch should be used instead.
- Globals.shouldMerge p || *)
(let s = Path.toString p in
Pred.test backupcurrent s && not (Pred.test backupcurrentnot s))
diff --git a/src/ubase/prefs.ml b/src/ubase/prefs.ml
index 44df052..7049719 100644
--- a/src/ubase/prefs.ml
+++ b/src/ubase/prefs.ml
@@ -392,16 +392,15 @@ and parseLines filename lines =
| _ -> raise (Util.Fatal(Printf.sprintf
"File \"%s\", line %d:\nGarbled 'include' directive: %s"
filename lineNum theLine))
- else try
- let pos = String.index theLine '=' in
- let varName = Util.trimWhitespace (String.sub theLine 0 pos) in
- let theResult =
- Util.trimWhitespace (String.sub theLine (pos+1)
- (String.length theLine - pos - 1)) in
- loop rest (lineNum+1) ((filename, lineNum, varName, theResult)::res)
- with Not_found -> (* theLine does not contain '=' *)
- raise(Util.Fatal(Printf.sprintf
- "File \"%s\", line %d:\nGarbled line (no '='):\n%s" filename lineNum theLine)) in
+ else
+ let l = Util.splitAtFirstChar theLine '=' in
+ match Safelist.map Util.trimWhitespace l with
+ [varName;theResult] ->
+ loop rest (lineNum+1) ((filename, lineNum, varName, theResult)::res)
+ | _ -> (* theLine does not contain '=' *)
+ raise (Util.Fatal(Printf.sprintf
+ "File \"%s\", line %d:\nGarbled line (no '='):\n%s"
+ filename lineNum theLine)) in
loop lines 1 []
let processLines lines =
diff --git a/src/ubase/trace.ml b/src/ubase/trace.ml
index 08caddf..d47054a 100644
--- a/src/ubase/trace.ml
+++ b/src/ubase/trace.ml
@@ -117,7 +117,7 @@ let logfile =
"!logfile name"
"By default, logging messages will be appended to the file
\\verb|unison.log| in your HOME directory. Set this preference if
- you prefer another file."
+ you prefer another file. It can be a path relative to your HOME directory."
let logch = ref None
@@ -125,7 +125,8 @@ let rec getLogch() =
Util.convertUnixErrorsToFatal "getLogch" (fun() ->
match !logch with
None ->
- let file = Prefs.read logfile in
+ let prefstr = System.fspathToString (Prefs.read logfile) in
+ let file = Util.fileMaybeRelToHomeDir prefstr in
let ch =
System.open_out_gen [Open_wronly; Open_creat; Open_append] 0o600 file in
logch := Some (ch, file);
diff --git a/src/ubase/uarg.ml b/src/ubase/uarg.ml
index 5ffd924..2d9e55e 100644
--- a/src/ubase/uarg.ml
+++ b/src/ubase/uarg.ml
@@ -69,7 +69,7 @@ let parse speclist anonfun errmsg =
while !current < l do
let ss = argv.(!current) in
if String.length ss >= 1 & String.get ss 0 = '-' then begin
- let args = Util.splitIntoWords ss '=' in
+ let args = Util.splitAtFirstChar ss '=' in
let s = Safelist.nth args 0 in
let arg conv mesg =
match args with
@@ -79,10 +79,13 @@ let parse speclist anonfun errmsg =
incr current;
(try conv a with Failure _ -> stop (Wrong (s, a, mesg)))
| [_;a] -> (try conv a with Failure _ -> stop (Wrong (s, a, mesg)))
- | _ -> stop (Message (sprintf "Garbled argument %s" s)) in
+ | _ -> assert false in
let action =
try assoc3 s speclist
with Not_found -> stop (Unknown s)
+ and catch f a =
+ try f a
+ with Invalid_argument s -> raise (Failure s)
in
begin try
match action with
@@ -92,11 +95,11 @@ let parse speclist anonfun errmsg =
| Bool f ->
begin match args with
[_] -> f true
- | _ -> f (arg bool_of_string "a boolean")
+ | _ -> f (arg (catch bool_of_string) "a boolean")
end
| String f -> f (arg (fun s-> s) "")
- | Int f -> f (arg int_of_string "an integer")
- | Float f -> f (arg float_of_string "a float")
+ | Int f -> f (arg (catch int_of_string) "an integer")
+ | Float f -> f (arg (catch float_of_string) "a float")
| Rest f ->
while !current < l-1 do
f argv.(!current+1);
diff --git a/src/ubase/util.ml b/src/ubase/util.ml
index 8af4714..9634a85 100644
--- a/src/ubase/util.ml
+++ b/src/ubase/util.ml
@@ -401,6 +401,14 @@ let trimWhitespace s =
in
loop 0 (l-1)
+let splitAtFirstChar (s:string) (c:char) =
+ try
+ let i = String.index s c
+ and l= String.length s in
+ (* rest is possibly the empty string *)
+ [String.sub s 0 i; String.sub s (i+1) (l-i-1)]
+ with Not_found -> [s]
+
let splitIntoWords ?esc:(e='\\') (s:string) (c:char) =
let rec inword acc eacc start pos =
if pos >= String.length s || s.[pos] = c then
@@ -460,6 +468,11 @@ let homeDir () =
let fileInHomeDir n = System.fspathConcat (homeDir ()) n
+let fileMaybeRelToHomeDir n =
+ if Filename.is_relative n
+ then fileInHomeDir n
+ else System.fspathFromString n
+
(*****************************************************************************)
(* "Upcall" for building pathnames in the .unison dir *)
(*****************************************************************************)
diff --git a/src/ubase/util.mli b/src/ubase/util.mli
index b213560..24bdb9d 100644
--- a/src/ubase/util.mli
+++ b/src/ubase/util.mli
@@ -55,6 +55,7 @@ val replacesubstrings : string -> (string * string) list -> string
val concatmap : string -> ('a -> string) -> 'a list -> string
val removeTrailingCR : string -> string
val trimWhitespace : string -> string
+val splitAtFirstChar : string -> char -> string list
val splitIntoWords : ?esc:char -> string -> char -> string list
val splitIntoWordsByString : string -> string -> string list
val padto : int -> string -> string
@@ -79,6 +80,7 @@ val percentageOfTotal :
val monthname : int -> string
val percent2string : float -> string
val fileInHomeDir : string -> System.fspath
+val fileMaybeRelToHomeDir : string -> System.fspath
val homeDirStr : string
(* Just like the versions in the Unix module, but raising Transient
diff --git a/src/uitext.ml b/src/uitext.ml
index 0b50628..fc5e8eb 100644
--- a/src/uitext.ml
+++ b/src/uitext.ml
@@ -135,6 +135,8 @@ let rec selectAction batch actions tryagain =
let formatname = function
"" -> "<ret>"
| " " -> "<spc>"
+ | "\x7f" -> "<del>"
+ | "\b" -> "<bsp>"
| n -> n in
let summarizeChoices() =
display "[";
@@ -247,6 +249,61 @@ let interact prilist rilist =
if not (Prefs.read Globals.batch) then display ("\n" ^ Uicommon.roots2string() ^ "\n");
let (r1,r2) = Globals.roots() in
let (host1, host2) = root2hostname r1, root2hostname r2 in
+ let showdiffs ri =
+ Uicommon.showDiffs ri
+ (fun title text ->
+ try
+ let pager = System.getenv "PAGER" in
+ restoreTerminal ();
+ let out = System.open_process_out pager in
+ Printf.fprintf out "\n%s\n\n%s\n\n" title text;
+ let _ = System.close_process_out out in
+ setupTerminal ()
+ with Not_found ->
+ Printf.printf "\n%s\n\n%s\n\n" title text)
+ (fun s -> Printf.printf "%s\n" s)
+ Uutil.File.dummy;
+ true
+ and ispropschanged = function
+ {replicas = Different {rc1 = rc1; rc2 = rc2}}
+ when rc1.status = `PropsChanged &&
+ (rc2.status = `PropsChanged || rc2.status = `Unchanged) -> true
+ | {replicas = Different {rc1 = rc1; rc2 = rc2}}
+ when rc1.status = `Unchanged && rc2.status = `PropsChanged -> true
+ | _ -> false
+ and setdirchanged = function
+ {replicas = Different ({rc1 = rc1; rc2 = rc2} as diff)}
+ when rc1.status = `Modified && rc2.status = `PropsChanged ->
+ diff.direction <- Replica1ToReplica2; true
+ | {replicas = Different ({rc1 = rc1; rc2 = rc2} as diff)}
+ when rc1.status = `PropsChanged && rc2.status = `Modified ->
+ diff.direction <- Replica2ToReplica1; true
+ | {replicas = Different _} -> false
+ | _ -> true
+ and setskip = function
+ {replicas = Different ({direction = Conflict _})} -> true
+ | {replicas = Different diff} ->
+ begin diff.direction <- Conflict "skip requested"; true end
+ | _ -> true
+ and setdir dir = function
+ {replicas = Different diff} -> begin diff.direction <- dir; true end
+ | _ -> true
+ and invertdir = function
+ {replicas = Different ({direction = Replica1ToReplica2} as diff)}
+ -> diff.direction <- Replica2ToReplica1; true
+ | {replicas = Different ({direction = Replica2ToReplica1} as diff)}
+ -> diff.direction <- Replica1ToReplica2; true
+ | {replicas = Different _} -> false
+ | _ -> true
+ and setDirectionIfConflict dir = function
+ {replicas = Different ({direction = Conflict _})} as ri ->
+ begin Recon.setDirection ri dir `Force; true end
+ | ri -> begin Recon.setDirection ri dir `Prefer; true end
+ in
+ let ripred = ref [] in
+ let ritest ri = match !ripred with
+ [] -> true
+ | test::_ -> test ri in
let rec loop prev =
let rec previous prev ril =
match prev with
@@ -255,13 +312,21 @@ let interact prilist rilist =
previous pril (pri::ril)
| pri::pril -> loop pril (pri::ril)
| [] -> display ("\n" ^ Uicommon.roots2string() ^ "\n"); loop prev ril in
+ let rec forward n prev ril =
+ match n, prev, ril with
+ 0, prev, ril -> loop prev ril
+ | n, [], ril when n < 0 -> loop [] ril
+ | n, pri::pril, ril when n < 0 -> forward (n+1) pril (pri::ril)
+ | _, [], [] -> loop [] []
+ | n, pri::pril, [] when n > 0 -> loop pril [pri]
+ | n, prev, ri::rest when n > 0 -> forward (n-1) (ri::prev) rest
+ | _ -> assert false (* to silence the compiler *) in
function
[] -> (ConfirmBeforeProceeding, Safelist.rev prev)
| ri::rest as ril ->
let next() = loop (ri::prev) rest in
let repeat() = loop prev ril in
let ignore pat rest what =
- if !cbreakMode <> None then display "\n";
display " ";
Uicommon.addIgnorePattern pat;
display (" Permanently ignoring " ^ what ^ "\n");
@@ -275,6 +340,43 @@ let interact prilist rilist =
loop (nukeIgnoredRis (ri::prev)) (nukeIgnoredRis ril) in
(* This should work on most terminals: *)
let redisplayri() = overwrite (); displayri ri; display "\n" in
+ let setripred cmd =
+ ripred := match cmd, !ripred with
+ `Unset, [] -> display "Matching condition already disabled\n"; []
+ | `Unset, _ | `Pop, [_] -> display " Disabling matching condition\n"; []
+ | `Pop, p::pp::t -> pp::t
+ | `Push rp, [] -> display " Enabling matching condition\n"; [rp]
+ | `Push rp, p -> rp::p
+ | _, [] -> display "Matching condition not enabled\n"; []
+ | `Op1 op, p::t -> (fun ri -> op (p ri))::t
+ | `Op2 op, [p] -> display "Missing previous matching condition\n"; [p]
+ | `Op2 op, p::pp::t -> (fun ri -> op (p ri) (pp ri))::t
+ | _ -> assert false in
+ let actOnMatching ?(change=true) ?(fail=Some(fun()->())) f =
+ (* [f] can have effects on the ri and return false to discard it *)
+ (* Disabling [change] avoids to redisplay the item, allows [f] to
+ print a message (info or error) on a separate line and repeats
+ instead of going to the next item *)
+ (* When [fail] is [None] if [f] returns false then instead of
+ executing [fail] and repeating we discard the item and go to the next *)
+ let discard, err =
+ match fail with Some e -> false, e | None -> true, fun()->() in
+ match !ripred with
+ | [] -> if not change then newLine();
+ let t = f ri in
+ if t || not discard
+ then begin
+ if change then redisplayri();
+ if not t then err();
+ if t && change then next() else repeat()
+ end else begin
+ if change then newLine();
+ loop prev rest
+ end
+ | test::_ -> newLine();
+ let filt = fun ri -> if test ri then f ri || not discard else true in
+ loop prev (ri::Safelist.filter filt rest)
+ in
displayri ri;
match ri.replicas with
Problem s -> display "\n"; display s; display "\n"; next()
@@ -297,112 +399,220 @@ let interact prilist rilist =
selectAction
(if Prefs.read Globals.batch then Some " " else None)
[((if (isConflict dir) && not (Prefs.read Globals.batch)
- then ["f"] (* Offer no default behavior if we've got
- a conflict and we're in interactive mode *)
- else ["";"f";" "]),
+ then ["f"] (* Offer no default behavior if we've got a
+ conflict and we're in interactive mode *)
+ else ["";"f";" "]),
("follow " ^ Uutil.myName ^ "'s recommendation (if any)"),
- fun ()->
- newLine ();
- if (isConflict dir) && not (Prefs.read Globals.batch)
- then begin
- display "No default action [type '?' for help]\n";
- repeat()
- end else
- next());
- (["I"],
- ("ignore this path permanently"),
- (fun () ->
- ignore (Uicommon.ignorePath ri.path1) rest
- "this path"));
- (["E"],
- ("permanently ignore files with this extension"),
- (fun () ->
- ignore (Uicommon.ignoreExt ri.path1) rest
- "files with this extension"));
- (["N"],
- ("permanently ignore paths ending with this name"),
- (fun () ->
- ignore (Uicommon.ignoreName ri.path1) rest
- "files with this name"));
- (["m"],
- ("merge the versions"),
+ (fun () -> newLine();
+ if (isConflict dir) && not (Prefs.read Globals.batch)
+ then begin
+ display "No default action [type '?' for help]\n";
+ repeat()
+ end else
+ next()));
+ (["n";"j"],
+ ("go to the next item"),
+ (fun () -> newLine();
+ next()));
+ (["p";"b";"k"],
+ ("go back to previous item"),
+ (fun () -> newLine();
+ previous prev ril));
+ (["\x7f";"\b"],
+ ("revert then go back to previous item"),
(fun () ->
- diff.direction <- Merge;
- redisplayri();
- next()));
+ Recon.revertToDefaultDirection ri; redisplayri();
+ previous prev ril));
+ (["0"],
+ ("go to the start of the list"),
+ (fun () -> newLine();
+ loop [] (Safelist.rev_append prev ril)));
+ (["9"],
+ ("go to the end of the list"),
+ (fun () -> newLine();
+ match Safelist.rev_append ril prev with
+ [] -> loop [] []
+ | lri::prev -> loop prev [lri]));
+ (["5"],
+ ("go forward to the middle of the following items"),
+ (fun () -> newLine();
+ forward ((Safelist.length ril)/2) prev ril));
+ (["6"],
+ ("go backward to the middle of the preceding items"),
+ (fun () -> newLine();
+ forward (-((Safelist.length prev)+1)/2) prev ril));
+ (["R"],
+ ("reverse the list"),
+ (fun () -> newLine();
+ loop rest (ri::prev)));
(["d"],
- ("show differences"),
+ ("show differences (curr or match)"),
(fun () ->
- newLine ();
- Uicommon.showDiffs ri
- (fun title text ->
- try
- let pager = System.getenv "PAGER" in
- restoreTerminal ();
- let out = System.open_process_out pager in
- Printf.fprintf out "\n%s\n\n%s\n\n" title text;
- let _ = System.close_process_out out in
- setupTerminal ()
- with Not_found ->
- Printf.printf "\n%s\n\n%s\n\n" title text)
- (fun s -> Printf.printf "%s\n" s)
- Uutil.File.dummy;
- repeat()));
+ actOnMatching ~change:false showdiffs));
(["x"],
- ("show details"),
- (fun () -> newLine(); displayDetails ri; repeat()));
+ ("show details (curr or match)"),
+ (fun () ->
+ actOnMatching ~change:false
+ (fun ri -> displayDetails ri; true)));
(["L"],
- ("list all suggested changes tersely"),
+ ("list all (or matching) following changes tersely"),
(fun () -> newLine();
Safelist.iter
- (fun ri -> displayri ri; display "\n ")
- ril;
- display "\n";
+ (fun ri -> display " "; displayri ri; display "\n")
+ (Safelist.filter ritest ril);
repeat()));
(["l"],
- ("list all suggested changes with details"),
+ ("list all (or matching) following changes with details"),
(fun () -> newLine();
Safelist.iter
- (fun ri -> displayri ri; display "\n ";
+ (fun ri -> display " "; displayri ri; display "\n";
alwaysDisplayDetails ri)
- ril;
- display "\n";
+ (Safelist.filter ritest ril);
repeat()));
- (["p";"b"],
- ("go back to previous item"),
+ (["A";"*"],
+ ("match all the following"),
+ (fun () -> newLine();
+ setripred (`Push (fun _ -> true));
+ repeat()));
+ (["1"],
+ ("match all the following that propagate " ^ descr),
+ (fun () -> newLine();
+ setripred (`Push (function
+ {replicas = Different ({direction = Replica1ToReplica2})} -> true
+ | _ -> false));
+ repeat()));
+ (["2"],
+ ("match all the following that propagate " ^ descl),
+ (fun () -> newLine();
+ setripred (`Push (function
+ {replicas = Different ({direction = Replica2ToReplica1})} -> true
+ | _ -> false));
+ repeat()));
+ (["C"],
+ ("match all the following conflicts"),
+ (fun () -> newLine();
+ setripred (`Push (function
+ {replicas = Different ({direction = Conflict _})} -> true
+ | _ -> false));
+ repeat()));
+ (["P";"="],
+ ("match all the following with only props changes"),
+ (fun () -> newLine();
+ setripred (`Push ispropschanged);
+ repeat()));
+ (["M"],
+ ("match all the following merges"),
+ (fun () -> newLine();
+ setripred (`Push (function
+ {replicas = Different ({direction = Merge})} -> true
+ | _ -> false));
+ repeat()));
+ (["X";"!"],
+ ("invert the matching condition"),
+ (fun () -> newLine();
+ setripred (`Op1 not);
+ repeat()));
+ (["&"],
+ ("and the last two matching conditions"),
+ (fun () -> newLine();
+ setripred (`Op2 (&&));
+ repeat()));
+ (["|"],
+ ("or the last two matching conditions"),
+ (fun () -> newLine();
+ setripred (`Op2 (||));
+ repeat()));
+ (["D";"_"],
+ ("delete/pop the active matching condition"),
+ (fun () -> newLine();
+ setripred `Pop;
+ repeat()));
+ (["U";"$"],
+ ("unmatch (select current)"),
+ (fun () -> newLine();
+ setripred `Unset;
+ repeat()));
+ (["r";"u"],
+ ("revert to " ^ Uutil.myName ^ "'s default recommendation (curr or match)"),
(fun () ->
- newLine();
- previous prev ril));
- (["s";"n"],
- ("stop the selection"),
- (fun() ->
- newLine();
+ actOnMatching
+ (fun ri->Recon.revertToDefaultDirection ri; true)));
+ (["m"],
+ ("merge the versions (curr or match)"),
+ (fun () ->
+ actOnMatching (setdir Merge)));
+ ([">";"."],
+ ("propagate from " ^ descr ^ " (curr or match)"),
+ (fun () ->
+ actOnMatching (setdir Replica1ToReplica2)));
+ (["<";","],
+ ("propagate from " ^ descl ^ " (curr or match)"),
+ (fun () ->
+ actOnMatching (setdir Replica2ToReplica1)));
+ (["]";"\""],
+ ("resolve conflicts in favor of the newer (curr or match)"),
+ (fun () ->
+ actOnMatching (setDirectionIfConflict `Newer)));
+ (["[";"'"],
+ ("resolve conflicts in favor of the older (curr or match)"),
+ (fun () ->
+ actOnMatching (setDirectionIfConflict `Older)));
+ (["c"],
+ ("resolve conflicts in favor of changed (curr or match)"),
+ (fun () ->
+ actOnMatching
+ ~fail:(Some (fun()->display "Cannot set direction\n"))
+ setdirchanged));
+ (["i"],
+ ("invert direction of propagation and go to next item"),
+ (fun () ->
+ actOnMatching
+ ~fail:(Some (fun()->display "Cannot invert direction\n"))
+ invertdir));
+ (["/";":"],
+ ("skip"),
+ (fun () ->
+ actOnMatching setskip));
+ (["%"],
+ ("skip all the following"),
+ (fun () -> newLine();
+ Safelist.iter (fun ri -> setskip ri; ()) rest;
+ repeat()));
+ (["-"],
+ ("skip and discard for this session (curr or match)"),
+ (fun () ->
+ actOnMatching ~fail:None (fun _->false)));
+ (["+"],
+ ("skip and discard all the following"),
+ (fun () -> newLine();
+ loop prev [ri]));
+ (["I"],
+ ("ignore this path permanently"),
+ (fun () -> newLine();
+ ignore (Uicommon.ignorePath ri.path1) rest
+ "this path"));
+ (["E"],
+ ("permanently ignore files with this extension"),
+ (fun () -> newLine();
+ ignore (Uicommon.ignoreExt ri.path1) rest
+ "files with this extension"));
+ (["N"],
+ ("permanently ignore paths ending with this name"),
+ (fun () -> newLine();
+ ignore (Uicommon.ignoreName ri.path1) rest
+ "files with this name"));
+ (["s"],
+ ("stop reconciling and go to the proceed menu"),
+ (fun () -> newLine();
(ConfirmBeforeProceeding, Safelist.rev_append prev ril)));
(["g"],
("proceed immediately to propagating changes"),
- (fun() ->
+ (fun () -> newLine();
(ProceedImmediately, Safelist.rev_append prev ril)));
(["q"],
("exit " ^ Uutil.myName ^ " without propagating any changes"),
- fun () -> raise Sys.Break);
- (["/"],
- ("skip"),
- (fun () ->
- if not (isConflict dir) then diff.direction <- Conflict "skip requested";
- redisplayri();
- next()));
- ([">";"."],
- ("propagate from " ^ descr),
- (fun () ->
- diff.direction <- Replica1ToReplica2;
- redisplayri();
- next()));
- (["<";","],
- ("propagate from " ^ descl),
- (fun () ->
- diff.direction <- Replica2ToReplica1;
- redisplayri();
- next()))
+ (fun () -> newLine();
+ raise Sys.Break))
]
(fun () -> displayri ri)
in loop prilist rilist
@@ -537,24 +747,24 @@ let setWarnPrinterForInitialization()=
let setWarnPrinter() =
Util.warnPrinter :=
- Some(fun s ->
- alwaysDisplay "Warning: ";
- alwaysDisplay s;
- if not (Prefs.read Globals.batch) then begin
- display "Press return to continue.";
- selectAction None
- [(["";" ";"y"],
- ("Continue"),
- fun()->());
- (["n";"q";"x"],
- ("Exit"),
- fun()->
- alwaysDisplay "\n";
- restoreTerminal ();
- Lwt_unix.run (Update.unlockArchives ());
- exit Uicommon.fatalExit)]
- (fun()-> display "Press return to continue.")
- end)
+ Some(fun s ->
+ alwaysDisplay "Warning: ";
+ alwaysDisplay s;
+ if not (Prefs.read Globals.batch) then begin
+ display "Press return to continue.";
+ selectAction None
+ [(["";" ";"y"],
+ ("Continue"),
+ (fun () -> ()));
+ (["n";"q";"x"],
+ ("Exit"),
+ (fun () ->
+ alwaysDisplay "\n";
+ restoreTerminal ();
+ Lwt_unix.run (Update.unlockArchives ());
+ exit Uicommon.fatalExit))]
+ (fun () -> display "Press return to continue.")
+ end)
let lastMajor = ref ""
@@ -669,16 +879,14 @@ let rec interactAndPropagateChanges prevItemList reconItemList
"Yes: proceed with updates as selected above",
doit);
(["n"],
- "No: go through selections again",
- (fun () ->
+ "No: go through reconciliation process again",
+ (fun () -> newLine();
Prefs.set Uicommon.auto false;
- newLine();
interactAndPropagateChanges [] newReconItemList));
(["p";"b"],
- "go back to the last item of the selection",
- (fun () ->
+ "go back to the last item of the reconciliation",
+ (fun () -> newLine();
Prefs.set Uicommon.auto false;
- newLine();
match Safelist.rev newReconItemList with
[] -> interactAndPropagateChanges [] []
| lastri::prev -> interactAndPropagateChanges prev [lastri]));
@@ -707,7 +915,8 @@ let rec interactAndPropagateChanges prevItemList reconItemList
(fun () -> askagain (Safelist.rev newReconItemList)));
(["q"],
("exit " ^ Uutil.myName ^ " without propagating any changes"),
- fun () -> raise Sys.Break)
+ (fun () -> newLine();
+ raise Sys.Break))
]
(fun () -> display "Proceed with propagating updates? ")
in askagain newReconItemList
@@ -725,11 +934,12 @@ let checkForDangerousPath dangerousPaths =
None
[(["y"],
"Continue",
- (fun() -> ()));
- (["n"; "q"; "x"; ""],
+ (fun () -> ()));
+ (["n";"q";"x";""],
"Exit",
- (fun () -> alwaysDisplay "\n"; restoreTerminal ();
- exit Uicommon.fatalExit))]
+ (fun () -> alwaysDisplay "\n";
+ restoreTerminal ();
+ exit Uicommon.fatalExit))]
(fun () -> display "Do you really want to proceed? ")
end
end