#
#
# patch "lib/perl/Annotate.pm"
# from [9a778d09c5f605b1795e81b05eb21f8feb4b1fb0]
# to [91b47ddd78719db24155c0802848e2d1d63e3838]
#
# patch "lib/perl/Common.pm"
# from [d6df7409384166de94c655c2a24103ebdd33d4e2]
# to [57dd6913d5e258aff37e2bb9601aa81e0572e950]
#
# patch "lib/perl/History.pm"
# from [7b9c9357c231510a04bb673b076cfbffc4fbb7a0]
# to [8b821d263a1376c0b81ca75e31651494f4eb3fd4]
#
# patch "lib/ui/mtn-browse.glade"
# from [fba49e593b91f655d1edcbe681f8bdfe406cff19]
# to [969d7bc6d90ed297737fa7c5fbf027a3c5200b34]
#
============================================================
--- lib/perl/Annotate.pm 9a778d09c5f605b1795e81b05eb21f8feb4b1fb0
+++ lib/perl/Annotate.pm 91b47ddd78719db24155c0802848e2d1d63e3838
@@ -810,7 +810,8 @@ sub mtn_annotate($$$$)
my($buffer,
@cmd,
$cwd,
- $exception);
+ $exception,
+ $ret_val);
# Run mtn annotate in the root directory so as to avoid any workspace
# conflicts.
@@ -826,7 +827,7 @@ sub mtn_annotate($$$$)
eval
{
die("chdir failed: " . $!) unless (chdir(File::Spec->rootdir()));
- return unless (run_command(\$buffer, @cmd));
+ $ret_val = run_command(\$buffer, undef, @cmd);
};
$exception = $@;
chdir($cwd);
@@ -850,7 +851,7 @@ sub mtn_annotate($$$$)
@$list = split(/\n/, $buffer);
- return 1;
+ return $ret_val;
}
============================================================
--- lib/perl/Common.pm d6df7409384166de94c655c2a24103ebdd33d4e2
+++ lib/perl/Common.pm 57dd6913d5e258aff37e2bb9601aa81e0572e950
@@ -89,7 +89,7 @@ sub register_help_callbacks($@);
sub open_database($$$);
sub program_valid($;$);
sub register_help_callbacks($@);
-sub run_command($@);
+sub run_command($$@);
sub save_as_file($$$);
sub set_label_value($$);
sub treeview_column_searcher($$$$);
@@ -154,6 +154,9 @@ sub generate_tmp_path($)
#
# Data - $buffer : A reference to the buffer that is to contain
# the output from the command.
+# $abort : Either a reference to a boolean that is set
+# to true if the command is to be aborted or
+# undef if no abort checking is required.
# $args : A list containing the command to run and its
# arguments.
# Return Value : True if the command worked, otherwise false
@@ -163,12 +166,13 @@ sub generate_tmp_path($)
-sub run_command($@)
+sub run_command($$@)
{
- my($buffer, @args) = @_;
+ my($buffer, $abort, @args) = @_;
- my(@err,
+ my($dummy_flag,
+ @err,
$fd_err,
$fd_in,
$fd_out,
@@ -178,6 +182,8 @@ sub run_command($@)
$total_bytes,
$watcher);
+ $abort = \$dummy_flag unless (defined($abort));
+
# Run the command.
$fd_err = gensym();
@@ -225,7 +231,7 @@ sub run_command($@)
# Setup a watch handler to read our data and handle GTK2 events whilst the
# command is running.
- $stop = $total_bytes = 0;
+ $total_bytes = 0;
$$buffer = "";
$watcher = Gtk2::Helper->add_watch
(fileno($fd_out), "in",
@@ -235,7 +241,8 @@ sub run_command($@)
$$buffer,
32768,
$total_bytes))
- == 0)
+ == 0
+ || ! defined($bytes_read))
{
$stop = 1;
}
@@ -245,15 +252,23 @@ sub run_command($@)
}
return TRUE;
});
- while (! $stop)
+ while (! $stop && ! $$abort)
{
Gtk2->main_iteration();
}
Gtk2::Helper->remove_watch($watcher);
- # Get any error output.
+ # If we have been asked to abort then terminate the subprocess, otherwise
+ # get any error output as the subprocess has just exited of its own accord.
- @err = readline($fd_err);
+ if ($$abort)
+ {
+ kill("TERM", $pid);
+ }
+ else
+ {
+ @err = readline($fd_err) unless ($$abort);
+ }
close($fd_in);
close($fd_out);
@@ -288,43 +303,47 @@ sub run_command($@)
if ($wait_status == $pid)
{
- my $exit_status = $?;
- if (WIFEXITED($exit_status) && WEXITSTATUS($exit_status) != 0)
+ if (! $$abort)
{
- my $dialog = Gtk2::MessageDialog->new_with_markup
- (undef,
- ["modal"],
- "warning",
- "close",
- __x("The {name} subprocess failed with an exit status\n"
- . "of {exit_code} and printed the following on "
- . "stderr:\n"
- . "{error_message}",
- name => Glib::Markup::escape_text($args[0]),
- exit_code => WEXITSTATUS($exit_status),
- error_message => Glib::Markup::escape_text
- (join("", @err))));
- WindowManager->instance()->allow_input
- (sub { $dialog->run(); });
- $dialog->destroy();
- return;
+ my $exit_status = $?;
+ if (WIFEXITED($exit_status) && WEXITSTATUS($exit_status) != 0)
+ {
+ my $dialog = Gtk2::MessageDialog->new_with_markup
+ (undef,
+ ["modal"],
+ "warning",
+ "close",
+ __x("The {name} subprocess failed with an exit "
+ . "status\n"
+ . "of {exit_code} and printed the following "
+ . "on stderr:\n"
+ . "{error_message}",
+ name => Glib::Markup::escape_text($args[0]),
+ exit_code => WEXITSTATUS($exit_status),
+ error_message => Glib::Markup::escape_text
+ (join("", @err))));
+ WindowManager->instance()->allow_input
+ (sub { $dialog->run(); });
+ $dialog->destroy();
+ return;
+ }
+ elsif (WIFSIGNALED($exit_status))
+ {
+ my $dialog = Gtk2::MessageDialog->new
+ (undef,
+ ["modal"],
+ "warning",
+ "close",
+ __x("The {name} subprocess was terminated by signal "
+ . "{number}.",
+ name => Glib::Markup::escape_text($args[0]),
+ number => WTERMSIG($exit_status)));
+ WindowManager->instance()->allow_input
+ (sub { $dialog->run(); });
+ $dialog->destroy();
+ return;
+ }
}
- elsif (WIFSIGNALED($exit_status))
- {
- my $dialog = Gtk2::MessageDialog->new
- (undef,
- ["modal"],
- "warning",
- "close",
- __x("The {name} subprocess was terminated by signal "
- . "{number}.",
- name => Glib::Markup::escape_text($args[0]),
- number => WTERMSIG($exit_status)));
- WindowManager->instance()->allow_input
- (sub { $dialog->run(); });
- $dialog->destroy();
- return;
- }
last;
}
============================================================
--- lib/perl/History.pm 7b9c9357c231510a04bb673b076cfbffc4fbb7a0
+++ lib/perl/History.pm 8b821d263a1376c0b81ca75e31651494f4eb3fd4
@@ -94,10 +94,10 @@ sub get_history_window();
sub file_comparison_combobox_changed_cb($$);
sub get_file_history_helper($$$);
sub get_history_window();
-sub get_revision_comparison_window();
+sub get_revision_comparison_window($);
sub get_revision_history_helper($$);
sub history_list_button_clicked_cb($$);
-sub mtn_diff($$$$;$);
+sub mtn_diff($$$$$;$);
sub save_differences_button_clicked_cb($$);
#
##############################################################################
@@ -538,7 +538,7 @@ sub display_revision_comparison($$$;$)
$iter);
my $wm = WindowManager->instance();
- $instance = get_revision_comparison_window();
+ $instance = get_revision_comparison_window($mtn);
local $instance->{in_cb} = 1;
$instance->{window}->
@@ -560,37 +560,77 @@ sub display_revision_comparison($$$;$)
$wm->make_busy($instance, 1);
$instance->{appbar}->push($instance->{appbar}->get_status()->get_text());
+ $instance->{stop_button}->set_sensitive(TRUE);
$wm->update_gui();
$instance->{mtn} = $mtn;
$instance->{revision_id_1} = $revision_id_1;
$instance->{revision_id_2} = $revision_id_2;
- # Get Monotone to do the comparison.
+ # Get Monotone to do the comparison, later versions can do this via
+ # automate stdio.
$instance->{appbar}->set_status(__("Calculating differences"));
$wm->update_gui();
if ($mtn->supports(MTN_CONTENT_DIFF_EXTRA_OPTIONS))
{
+
+ my $exception;
+
+ local $instance->{kill_mtn_subprocess} = 1;
+
+ # The stop button callback will kill off the mtn subprocess so suppress
+ # any resultant errors.
+
$mtn->suppress_utf8_conversion(1);
- $mtn->content_diff($instance->{diff_output},
- ["with-header"],
- $revision_id_1,
- $revision_id_2,
- $file_name);
+ CachingAutomateStdio->register_error_handler
+ (MTN_SEVERITY_ALL,
+ sub {
+ my($severity, $message, $instance) = @_;
+ mtn_error_handler($severity, $message)
+ if ($severity == MTN_SEVERITY_WARNING
+ || ! $instance->{stop});
+ },
+ $instance);
+ eval
+ {
+ $mtn->content_diff($instance->{diff_output},
+ ["with-header"],
+ $revision_id_1,
+ $revision_id_2,
+ $file_name);
+ };
+ $exception = $@;
+ CachingAutomateStdio->register_error_handler(MTN_SEVERITY_ALL,
+ \&mtn_error_handler);
$mtn->suppress_utf8_conversion(0);
+
+ # If we have aborted the comparison by killing off the mtn subprocess
+ # then cleanly closedown and restart it, otherwise rethrow any raised
+ # exceptions.
+
+ if ($instance->{stop})
+ {
+ my $dummy;
+ $mtn->closedown();
+ $mtn->interface_version(\$dummy);
+ }
+ elsif ($exception)
+ {
+ die($exception);
+ }
+
}
else
{
mtn_diff($instance->{diff_output},
+ \$instance->{stop},
$mtn->get_db_name(),
$revision_id_1,
$revision_id_2,
$file_name);
}
- $instance->{stop_button}->set_sensitive(TRUE);
-
# Does the user want pretty printed differences output?
if ($user_preferences->{coloured_diffs})
@@ -1751,16 +1791,20 @@ sub get_revision_history_helper($$)
# Description - Creates or prepares an existing revision comparison window
# for use.
#
-# Data - Return Value : A reference to the newly created or unused
+# Data - $mtn : The Monotone::AutomateStdio object that is
+# to be used to do the comparison.
+# Return Value : A reference to the newly created or unused
# change log instance record.
#
##############################################################################
-sub get_revision_comparison_window()
+sub get_revision_comparison_window($)
{
+ my $mtn = $_[0];
+
my($height,
$instance,
$renderer,
@@ -1821,8 +1865,24 @@ sub get_revision_comparison_window()
return TRUE;
},
$instance);
- $instance->{stop_button}->signal_connect
- ("clicked", sub { $_[1]->{stop} = 1; }, $instance);
+ if ($mtn->supports(MTN_CONTENT_DIFF_EXTRA_OPTIONS))
+ {
+ $instance->{kill_mtn_subprocess} = 0;
+ $instance->{stop_button}->signal_connect
+ ("clicked",
+ sub {
+ my($widget, $instance) = @_;
+ $instance->{stop} = 1;
+ kill("TERM", $instance->{mtn}->get_pid())
+ if ($instance->{kill_mtn_subprocess});
+ },
+ $instance);
+ }
+ else
+ {
+ $instance->{stop_button}->signal_connect
+ ("clicked", sub { $_[1]->{stop} = 1; }, $instance);
+ }
# Setup the file combobox.
@@ -2045,6 +2105,9 @@ sub external_diffs($$$$$$)
#
# Data - $list : A reference to the list that is to contain
# the output from the diff command.
+# $abort : A reference to an abort flag that when
+# true will cause the mtn diff process to
+# stop.
# $mtn_db : The Monotone database that is to be used
# or undef if the database associated with
# the current workspace is to be used.
@@ -2063,15 +2126,21 @@ sub external_diffs($$$$$$)
-sub mtn_diff($$$$;$)
+sub mtn_diff($$$$$;$)
{
- my($list, $mtn_db, $revision_id_1, $revision_id_2, $file_name) = @_;
+ my($list,
+ $abort,
+ $mtn_db,
+ $revision_id_1,
+ $revision_id_2,
+ $file_name) = @_;
my($buffer,
@cmd,
$cwd,
- $exception);
+ $exception,
+ $ret_val);
# Run mtn diff in the root directory so as to avoid any workspace
# conflicts.
@@ -2089,32 +2158,40 @@ sub mtn_diff($$$$;$)
eval
{
die("chdir failed: " . $!) unless (chdir(File::Spec->rootdir()));
- return unless (run_command(\$buffer, @cmd));
+ $ret_val = run_command(\$buffer, $abort, @cmd);
};
$exception = $@;
chdir($cwd);
- if ($exception)
+ if (! $$abort)
{
- my $dialog = Gtk2::MessageDialog->new_with_markup
- (undef,
- ["modal"],
- "warning",
- "close",
- __x("Problem running mtn diff, got:\n"
- . "{error_message}\n"
- . "This should not be happening!",
- error_message => Glib::Markup::escape_text($exception)));
- WindowManager->instance()->allow_input(sub { $dialog->run(); });
- $dialog->destroy();
- return;
- }
+ if ($exception)
+ {
+ my $dialog = Gtk2::MessageDialog->new_with_markup
+ (undef,
+ ["modal"],
+ "warning",
+ "close",
+ __x("Problem running mtn diff, got:\n"
+ . "{error_message}\n"
+ . "This should not be happening!",
+ error_message => Glib::Markup::escape_text($exception)));
+ WindowManager->instance()->allow_input(sub { $dialog->run(); });
+ $dialog->destroy();
+ return;
+ }
- # Break up the input into a list of lines.
+ # Break up the input into a list of lines.
- @$list = split(/\n/, $buffer);
+ @$list = split(/\n/, $buffer);
- return 1;
+ }
+ else
+ {
+ @$list = ();
+ }
+ return $ret_val;
+
}
1;
============================================================
--- lib/ui/mtn-browse.glade fba49e593b91f655d1edcbe681f8bdfe406cff19
+++ lib/ui/mtn-browse.glade 969d7bc6d90ed297737fa7c5fbf027a3c5200b34
@@ -3690,8 +3690,8 @@ Tag
True
- Revision id of the first selected
-file version that is to be compared
+ The first of two revision ids
+selected for comparison
True
False
@@ -3724,8 +3724,8 @@ file version that is to be compared
True
- Revision id of the second selected
-file version that is to be compared
+ The second of two revision
+ids selected for comparison
True
False
@@ -4038,7 +4038,7 @@ selected file in an external viewer
True
False
- Stop formatting the comparison results
+ Stop the comparison
True
GTK_RELIEF_NONE
False