Compare commits

...

12 Commits

Author SHA1 Message Date
Mahmoud Khalil
479ab0b9f9 Merge branch 'wip/mahmoudkhalil11/compare-two-non-consecutive-commits' into 'master'
WIP: Compare Two Non-Consecutive Commits

See merge request GNOME/gitg!153
2024-06-19 14:34:46 +00:00
Sabri Ünal
afa7724628 ui: Add tooltips to search buttons
- Add tooltips to the previous result and next result buttons.
2024-06-19 10:40:33 +00:00
MahmoudKhalil
c11411a992 Refactor DiffView, and Diff Plugin to support comparing multiple commits
This should extend the `DiffView` and `Diff` plugin to support adding multiple commits to be compare.
2020-07-08 11:12:00 +02:00
MahmoudKhalil
b921968bd7 append_commit method now returns bool
To help indicate whether the `commit` has been appended to the `commits_holder` the
`append_commit` method has been modified to return a bool
2020-07-07 12:27:50 +02:00
MahmoudKhalil
ca07a21850 A Holder Class for DiffView Commits
Currently, the `DiffView` contained only one reference to the selected `commit, which is the
the `commit` to be compared with its parent.

So this Holder Class will manage inserting new commits, and getting the `diff` from the
inserted commits
2020-07-07 11:43:40 +02:00
MahmoudKhalil
8a2206ad4a Emitting the selection_changed signal only after checking the selection count
We only allow the user to only select two commits at a time, this is handled inside the
callback function for changing the selection of the TreeSelection, So we only need
to emit our signal `selection_changed` after we made sure that the selection doesn't
exceed the allowed number

Signed-off-by: MahmoudKhalil <mahmoudkhalil11@gmail.com>
2020-07-05 12:23:26 +02:00
MahmoudKhalil
0286ec88d7 Extending The Commit Class with A .get_diff_with_commit Method To Get The Difference With Another Commit
Currently in gitg, the `Commit` Class only has a `.get_diff` method which get
the difference between it and it's parent(which is usually the commit directly before it),
this extends it with a new method `.get_diff_with_commit` to compare with any commit
and not necessarily the parent

Signed-off-by: MahmoudKhalil <mahmoudkhalil11@gmail.com>
2020-07-04 07:15:07 +02:00
MahmoudKhalil
04a4bd4c2c History View Refactoring for Multiple Selection Support
Signed-off-by: MahmoudKhalil <mahmoudkhalil11@gmail.com>
2020-07-02 06:28:43 +02:00
MahmoudKhalil
30dd1292b7 Handle Popup Menu Bug Introduced After Enabling The Multiple Selection in The Commit List View
This should handle the bug introduced after my last commit for enabling multiple
selections. The Popup Menu now should behave as expected when right click is pressed on a
particular commit

Signed-off-by: MahmoudKhalil <mahmoudkhalil11@gmail.com>
2020-06-30 16:32:03 +02:00
MahmoudKhalil
b87e34813d Merge branch 'wip/mahmoudkhalil11/compare-two-non-consecutive-commits' of gitlab.gnome.org:mahmoudkhalil11/gitg into wip/mahmoudkhalil11/compare-two-non-consecutive-commits 2020-06-30 14:42:13 +02:00
MahmoudKhalil
dfd3f3b61e Add Support For Multiple Selections in The Commit List View
We can now easily select multiple commits in the commit list view, considering
that we only can select at maximum 2 commits at a time.

Signed-off-by: MahmoudKhalil <mahmoudkhalil11@gmail.com>
2020-06-30 14:41:26 +02:00
MahmoudKhalil
e9835559bd Add Support For Multiple Selections in The Commit List View
We can now easily select multiple commits in the commit list view, considering
that we only can select at maximum 2 commits at a time.

Signed-off-by: MahmoudKhalil <mahmoudkhalil11@gmail.com>
2020-06-27 22:51:56 +02:00
9 changed files with 246 additions and 70 deletions

View File

@ -591,7 +591,17 @@ namespace GitgHistory
d_main.commit_list_view.model = d_commit_list_model;
d_main.commit_list_view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE);
d_main.commit_list_view.get_selection().changed.connect((sel) => {
Gtk.TreePath commit_cursor_path;
d_main.commit_list_view.get_cursor(out commit_cursor_path, null);
var selected_commits_count = sel.count_selected_rows();
if(selected_commits_count > 2)
{
sel.unselect_all();
sel.select_path(commit_cursor_path);
}
selection_changed();
// Set primary selection to sha1 of first selected commit
@ -721,17 +731,19 @@ namespace GitgHistory
private Gdk.Rectangle? on_commit_list_request_menu_position()
{
var selection = d_main.commit_list_view.get_selection();
Gtk.TreeModel model;
Gtk.TreeIter iter;
Gtk.TreePath path;
if (!selection.get_selected(out model, out iter))
path = d_main.commit_list_view.get_path_at_focused();
if(path == null)
{
return null;
}
var path = model.get_path(iter);
if (!d_commit_list_model.get_iter(out iter, path))
{
return null;
}
Gdk.Rectangle rect = { 0 };
@ -814,11 +826,16 @@ namespace GitgHistory
private Gtk.Menu? popup_menu_for_selection()
{
var selection = d_main.commit_list_view.get_selection();
Gtk.TreeIter iter;
Gtk.TreePath path;
if (!selection.get_selected(null, out iter))
path = d_main.commit_list_view.get_path_at_focused();
if(path == null)
{
return null;
}
if (!d_commit_list_model.get_iter(out iter, path))
{
return null;
}
@ -862,7 +879,19 @@ namespace GitgHistory
return null;
}
d_main.commit_list_view.get_selection().select_path(path);
var selection = d_main.commit_list_view.get_selection();
// Only unselect the selected paths, instead of unselecting all commits
var selected_paths = selection.get_selected_rows(null);
foreach(var selected_path in selected_paths)
{
if(selected_path != null)
{
selection.unselect_path(selected_path);
}
}
selection.select_path(path);
return populate_menu_for_commit(commit);
}

View File

@ -263,6 +263,7 @@
</child>
<child>
<object class="GtkButton" id="d_search_up_button">
<property name="tooltip-text" translatable="yes">Previous result</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="clicked" handler="search_up_clicked" swapped="no"/>
@ -278,6 +279,7 @@
</child>
<child>
<object class="GtkButton" id="d_search_down_button">
<property name="tooltip-text" translatable="yes">Next result</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="clicked" handler="search_down_clicked" swapped="no"/>

View File

@ -120,6 +120,31 @@ namespace Gitg
}
}
}
public Gtk.TreePath? get_path_at_focused()
{
var selection = get_selection();
if(selection.count_selected_rows() == 0)
{
return null;
}
Gtk.TreePath path;
get_cursor(out path, null);
if(!selection.path_is_selected(path))
{
path = (Gtk.TreePath) selection.get_selected_rows(null).nth_data(0);
if(path == null)
{
return null;
}
}
return path;
}
}
}

View File

@ -158,6 +158,37 @@ public class Commit : Ggit.Commit
return diff;
}
public Ggit.Diff get_diff_with_commit(Ggit.DiffOptions? options, Commit commit)
{
var repo = get_owner();
Ggit.Diff? diff = null;
try
{
diff = new Ggit.Diff.tree_to_tree(repo,
commit.get_tree(),
get_tree(),
options);
}
catch(Error e)
{
stderr.printf("Error when getting diff:%s\n", e.message);
}
if(diff != null)
{
try
{
diff.find_similar(null);
}
catch
{
}
}
return diff;
}
public Ggit.Note get_note()
{
Ggit.Note note = null;

View File

@ -0,0 +1,107 @@
/*
* This file is part of gitg
*
* Copyright (C) 2020 - Mahmoud Ahmed Khalil
*
* gitg is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* gitg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with gitg. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Gitg
{
public class DiffViewCommitsHolder : Object
{
private Commit? d_first_commit;
private Commit? d_second_commit;
private uint d_commits_counter;
public uint commits_counter
{
get { return d_commits_counter; }
}
public Commit? first_commit
{
get { return d_first_commit; }
}
public Commit? second_commit
{
get { return d_second_commit; }
}
construct
{
clear_commits();
}
public void clear_commits()
{
d_first_commit = null;
d_second_commit = null;
d_commits_counter = 0;
}
public bool append_commit(Commit c)
{
if(d_commits_counter >= 2 || c == null)
return false;
if(d_commits_counter == 0)
{
d_first_commit = c;
}
else if(d_commits_counter == 1)
{
d_second_commit = c;
}
d_commits_counter++;
return true;
}
public Ggit.Diff? get_diff(Ggit.DiffOptions? options, Ggit.Commit parent_commit)
{
Ggit.Diff? diff = null;
if(d_commits_counter == 1)
{
int parent = 0;
var parents = d_first_commit.get_parents();
if (parent_commit != null)
{
for (var i = 0; i < parents.size; i++)
{
var id = parents.get_id(i);
if (id.equal(parent_commit.get_id()))
{
parent = i;
break;
}
}
}
diff = d_first_commit.get_diff(options, parent);
}
else if(d_commits_counter == 2)
{
diff = d_first_commit.get_diff_with_commit(options, d_second_commit);
}
return diff;
}
}
}

View File

@ -41,8 +41,10 @@ public class Gitg.DiffView : Gtk.Grid
[GtkChild( name = "text_view_message" )]
private unowned Gtk.TextView d_text_view_message;
public delegate void UpdateCommitsCallback(Gitg.DiffViewCommitsHolder holder);
private Ggit.Diff? d_diff;
private Commit? d_commit;
private Gitg.DiffViewCommitsHolder d_commits_holder;
private Ggit.DiffOptions? d_options;
private Cancellable d_cancellable;
private ulong d_expanded_notify;
@ -85,31 +87,21 @@ public class Gitg.DiffView : Gtk.Grid
if (d_diff != value)
{
d_diff = value;
d_commit = null;
d_commits_holder.clear_commits();
}
update(false);
}
}
public Commit? commit
public Gitg.Commit? commit
{
get { return d_commit; }
set
{
if (d_commit != value)
{
d_commit = value;
d_diff = null;
}
update(false);
}
get { return d_commits_holder.first_commit; }
}
public virtual signal void options_changed()
{
if (d_commit != null)
if (d_commits_holder.commits_counter != 0)
{
update(true);
}
@ -234,6 +226,19 @@ public class Gitg.DiffView : Gtk.Grid
base.dispose();
}
public void update_diff_view(UpdateCommitsCallback func)
{
d_commits_holder.clear_commits();
if(func != null)
{
func(d_commits_holder);
}
d_diff = null;
update(false);
}
private void parent_commit_changed()
{
update(false);
@ -272,6 +277,7 @@ public class Gitg.DiffView : Gtk.Grid
construct
{
context_lines = 3;
d_commits_holder = new DiffViewCommitsHolder();
}
private string message_without_subject(Commit commit)
@ -525,9 +531,9 @@ public class Gitg.DiffView : Gtk.Grid
private void update(bool preserve_expanded)
{
// If both `d_diff` and `d_commit` are null, clear
// If `d_diff` is null, and `d_commits_holder.commits_counter` is zero, clear
// the diff content
if (d_diff == null && d_commit == null)
if (d_diff == null && d_commits_holder.commits_counter == 0)
{
d_commit_details.hide();
d_scrolledwindow.hide();
@ -541,35 +547,16 @@ public class Gitg.DiffView : Gtk.Grid
d_cancellable.cancel();
d_cancellable = new Cancellable();
if (d_commit != null)
if (d_commits_holder.commits_counter != 0)
{
SignalHandler.block(d_commit_details, d_parent_commit_notify);
d_commit_details.commit = d_commit;
d_commit_details.commit = d_commits_holder.first_commit;
SignalHandler.unblock(d_commit_details, d_parent_commit_notify);
int parent = 0;
var parents = d_commit.get_parents();
var parent_commit = d_commit_details.parent_commit;
if (parent_commit != null)
{
for (var i = 0; i < parents.size; i++)
{
var id = parents.get_id(i);
if (id.equal(parent_commit.get_id()))
{
parent = i;
break;
}
}
}
d_diff = d_commit.get_diff(options, parent);
d_diff = d_commits_holder.get_diff(options, d_commit_details.parent_commit);
d_commit_details.show();
var message = message_without_subject(d_commit);
var message = message_without_subject(d_commits_holder.first_commit);
d_text_view_message.buffer.set_text(message);
var buffer = d_text_view_message.get_buffer();

View File

@ -40,6 +40,7 @@ sources = files(
'gitg-diff-selectable.vala',
'gitg-diff-stat.vala',
'gitg-diff-view-commit-details.vala',
'gitg-diff-view-commits-holder.vala',
'gitg-diff-view-file-info.vala',
'gitg-diff-view-file-renderer-binary.vala',
'gitg-diff-view-file-renderer-image.vala',

View File

@ -132,28 +132,20 @@ namespace GitgDiff
private void on_selection_changed(GitgExt.History history)
{
var hasset = false;
d_whenMapped.update(() => {
d_diff.update_diff_view((holder) => {
history.foreach_selected((commit) => {
var c = commit as Gitg.Commit;
history.foreach_selected((commit) => {
var c = commit as Gitg.Commit;
if(c != null)
{
return holder.append_commit(c);
}
if (c != null)
{
d_whenMapped.update(() => {
d_diff.commit = c;
hasset = true;
}, this);
return false;
}
return true;
});
if (!hasset)
{
d_diff.commit = null;
}
return true;
});
});
}, this);
}
public Gtk.Widget? widget

View File

@ -115,7 +115,9 @@ class TestDiffView
v.show();
sw.add(v);
v.commit = commit;
v.update_diff_view((holder) => {
holder.append_commit(commit);
});
wnd.delete_event.connect((w, ev) => {
Gtk.main_quit();