Remote branches can be checked out using double-click.

This commit is contained in:
Armandas Jarušauskas 2020-06-09 20:50:31 +09:00 committed by Alberto Fanjul
parent c556f99fd6
commit 754cde5e82
8 changed files with 424 additions and 5 deletions

View file

@ -0,0 +1,141 @@
/*
* This file is part of gitg
*
* Copyright (C) 2020 - Armandas Jarušauskas
*
* 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
{
[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-checkout-remote-branch-dialog.ui")]
class CheckoutRemoteBranchDialog : Gtk.Dialog
{
[GtkChild]
private Gtk.Button d_button_create;
[GtkChild]
private Gtk.Entry d_branch_name;
[GtkChild]
private Gtk.ComboBoxText d_remote_branch_name;
[GtkChild]
private Gtk.CheckButton d_track_remote;
private Gitg.Repository d_repository;
private Gitg.Ref d_remote_reference;
construct
{
d_branch_name.changed.connect(() => {
d_button_create.sensitive = entries_valid();
});
d_remote_branch_name.changed.connect(() => {
d_button_create.sensitive = entries_valid();
});
set_default(d_button_create);
set_default_response(Gtk.ResponseType.OK);
}
public CheckoutRemoteBranchDialog(Gtk.Window? parent, Gitg.Repository? repository, Gitg.Ref reference)
{
Object(use_header_bar : 1);
if (parent != null)
{
set_transient_for(parent);
}
if (repository != null)
{
d_repository = repository;
}
if (reference.is_remote())
{
d_remote_reference = reference;
}
}
public string new_branch_name
{
owned get
{
return d_branch_name.text.strip();
}
}
public string remote_branch_name
{
owned get
{
return d_remote_branch_name.get_active_text();
}
}
public bool track_remote
{
get
{
return d_track_remote.active;
}
}
public override void show()
{
base.show();
update_entries();
}
private bool entries_valid()
{
return (new_branch_name.length != 0) && (d_remote_branch_name.get_active_text() != null);
}
private void update_entries()
{
d_branch_name.set_text(d_remote_reference.parsed_name.remote_branch);
try
{
d_repository.references_foreach_name((name) => {
Gitg.Ref? reference;
try
{
reference = d_repository.lookup_reference(name);
} catch { return 0; }
if (!reference.is_remote() || (reference.get_reference_type() == Ggit.RefType.SYMBOLIC))
{
return 0;
}
d_remote_branch_name.append(reference.parsed_name.shortname, reference.parsed_name.shortname);
return 0;
});
} catch {}
d_remote_branch_name.set_active_id(d_remote_reference.parsed_name.shortname);
}
}
}
// ex: ts=4 noet

View file

@ -59,7 +59,7 @@ class RefActionCheckout : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction,
{
try
{
return reference.is_branch() && !((Ggit.Branch)reference).is_head();
return (reference.is_branch() && !((Ggit.Branch)reference).is_head()) || reference.is_remote();
} catch {}
return false;
@ -127,9 +127,80 @@ class RefActionCheckout : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction,
public void activate()
{
checkout.begin((obj, res) => {
checkout.end(res);
});
if (reference.is_branch())
{
checkout.begin();
}
else if (reference.is_remote())
{
var dlg = new CheckoutRemoteBranchDialog((Gtk.Window)application, application.repository, reference);
dlg.response.connect((d, resp) => {
on_checkout_remote_branch_dialog_response(dlg, resp);
});
dlg.show();
}
}
private void on_checkout_remote_branch_dialog_response(Gitg.CheckoutRemoteBranchDialog dialog, int response_id) {
if (response_id == Gtk.ResponseType.OK)
{
string? remote_branch_name = dialog.track_remote ? dialog.remote_branch_name : null;
create_branch.begin(reference, dialog.new_branch_name, remote_branch_name, (obj, res) => {
var branch_ref = create_branch.end(res) as Gitg.Ref;
if (branch_ref != null)
{
action_interface.add_ref(branch_ref);
reference = branch_ref;
checkout.begin();
}
});
}
dialog.destroy();
}
private async Ggit.Branch? create_branch(Ggit.Ref reference, string new_branch_name, string? remote_branch_name)
{
Ggit.Branch? branch = null;
var repo = application.repository;
try
{
Gitg.Commit commit = reference.lookup() as Gitg.Commit;
branch = repo.create_branch(new_branch_name,
commit,
Ggit.CreateFlags.NONE);
}
catch (Error e)
{
application.show_infobar(_("Failed to create branch"),
e.message,
Gtk.MessageType.ERROR);
}
if (branch != null)
{
if (remote_branch_name != null) {
try
{
branch.set_upstream(remote_branch_name);
}
catch (Error e)
{
application.show_infobar(
_("Failed to set the upstream branch %s for %s").printf(remote_branch_name,
new_branch_name),
e.message,
Gtk.MessageType.ERROR);
}
}
}
return branch;
}
}

View file

@ -1123,7 +1123,7 @@ namespace GitgHistory
return;
}
if (ref_row.reference.is_branch()) {
if (ref_row.reference.is_branch() || ref_row.reference.is_remote()) {
var af = new ActionInterface(application, d_main.refs_list);
var checkout = new Gitg.RefActionCheckout(application, af, ref_row.reference);
checkout.activate();

View file

@ -33,6 +33,7 @@ sources = gitg_sources + files(
'gitg-convert.vala',
'gitg-create-branch-dialog.vala',
'gitg-create-tag-dialog.vala',
'gitg-checkout-remote-branch-dialog.vala',
'gitg-dash-view.vala',
'gitg-dirs.vala',
'gitg-notifications.vala',
@ -109,6 +110,7 @@ resource_data = files(
'resources/ui/gitg-shortcuts.ui',
'resources/ui/gitg-simple-notification.ui',
'resources/ui/gitg-window.ui',
'resources/ui/gitg-checkout-remote-branch-dialog.ui',
'resources/ui/style.css',
'resources/ui/style-@0@.css'.format(platform_name),
)

View file

@ -23,6 +23,7 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-simple-notification.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-remote-notification.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-shortcuts.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-checkout-remote-branch-dialog.ui</file>
<file compressed="true">ui/style.css</file>
<file compressed="true">ui/style-@PLATFORM_NAME@.css</file>

View file

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<template class="GitgCheckoutRemoteBranchDialog" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="title" translatable="yes">Checkout Remote Branch</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="type_hint">dialog</property>
<child internal-child="headerbar">
<object class="GtkHeaderBar" id="dialog-header_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">False</property>
<child>
<object class="GtkButton" id="button_cancel">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
<style>
<class name="text-button"/>
</style>
</object>
<packing>
<property name="pack_type">start</property>
</packing>
</child>
<child>
<object class="GtkButton" id="d_button_create">
<property name="label" translatable="yes">C_heckout</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<style>
<class name="text-button"/>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Local branch _name:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">d_branch_name</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="d_branch_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Remote branch:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">d_remote_branch_name</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="d_remote_branch_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="d_track_remote">
<property name="label" translatable="yes">_Track remote branch</property>
<property name="use_underline">True</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<property name="active">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button_cancel</action-widget>
<action-widget response="-5">d_button_create</action-widget>
</action-widgets>
</template>
</interface>

View file

@ -0,0 +1,51 @@
/*
* This file is part of gitg
*
* Copyright (C) 2020 - Armandas Jarušauskas
*
* 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
{
class CheckoutRemoteBranchDialog : Gtk.Dialog
{
public CheckoutRemoteBranchDialog(Gtk.Window? parent, Gitg.Repository? repository, Gitg.Ref reference)
{
}
public string new_branch_name {get; set; default = "test_branch"; }
public string remote_branch_name {get; set; default = "origin/test_branch"; }
public bool track_remote {get; set; default = true; }
public override void show()
{
}
private bool entries_valid()
{
return (new_branch_name.len() != 0) && (remote_branch_name.len() != 0);
}
private void update_entries()
{
}
}
}
// ex: ts=4 noet

View file

@ -4,6 +4,7 @@ sources = gitg_sources + support_sources + files(
'notifications-mock.vala',
'ref-action-interface-mock.vala',
'simple-notification-mock.vala',
'checkout-remote-branch-dialog-mock.vala',
'test-checkout-ref.vala',
'test-cherry-pick-commit.vala',
'test-merge-ref.vala',