Commit d172282b authored by Ignazio Sgalmuzzo's avatar Ignazio Sgalmuzzo Committed by Alberto Fanjul

Add push support

parent 1f516e9b
Pipeline #77292 passed with stages
in 19 minutes and 11 seconds
/*
* This file is part of gitg
*
* Copyright (C) 2017 - Ignazio Sgalmuzzo
*
* 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 RefActionPush : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Object
{
// Do this to pull in config.h before glib.h (for gettext...)
private const string version = Gitg.Config.VERSION;
public GitgExt.Application? application { owned get; construct set; }
public GitgExt.RefActionInterface action_interface { get; construct set; }
public Gitg.Ref reference { get; construct set; }
private Gitg.Ref? d_remote_ref;
private Gitg.Remote? d_remote;
public RefActionPush(GitgExt.Application application,
GitgExt.RefActionInterface action_interface,
Gitg.Ref reference)
{
Object(application: application,
action_interface: action_interface,
reference: reference);
var branch = reference as Ggit.Branch;
if (branch != null)
{
try
{
d_remote_ref = branch.get_upstream() as Gitg.Ref;
} catch {}
}
else if (reference.parsed_name.remote_name != null)
{
d_remote_ref = reference;
}
if (d_remote_ref != null)
{
d_remote = application.remote_lookup.lookup(d_remote_ref.parsed_name.remote_name);
}
if (d_remote == null)
{
d_remote = application.remote_lookup.lookup("origin");
}
}
public string id
{
owned get { return "/org/gnome/gitg/ref-actions/push"; }
}
public string display_name
{
owned get
{
if (d_remote != null)
{
return _("Push to %s").printf(d_remote.get_name());
}
else
{
return "";
}
}
}
public string description
{
owned get { return _("Push branch to %s").printf(d_remote.get_name()); }
}
public bool available
{
get
{
return (d_remote != null) && reference.is_branch();
}
}
public async bool push(string branch)
{
var notification = new RemoteNotification(d_remote);
application.notifications.add(notification);
notification.text = _("Pushing to %s").printf(d_remote.get_url());
try
{
yield d_remote.push(branch, null);
}
catch (Error e)
{
notification.error(_("Failed to push to %s: %s").printf(d_remote.get_url(), e.message));
stderr.printf("Failed to push: %s\n", e.message);
return false;
}
/* Translators: the %s will get replaced with the remote url, */
notification.success(_("Pushed to %s").printf(d_remote.get_url()));
return true;
}
public void activate()
{
var query = new GitgExt.UserQuery();
var branch_name = reference.get_shorthand();
query.title = (_("Push branch %s")).printf(branch_name);
query.message = (_("Are you sure that you want to push the branch %s?")).printf(branch_name);
query.responses = new GitgExt.UserQueryResponse[] {
new GitgExt.UserQueryResponse(_("Cancel"), Gtk.ResponseType.CANCEL),
new GitgExt.UserQueryResponse(_("Push"), Gtk.ResponseType.OK)
};
query.default_response = Gtk.ResponseType.OK;
query.response.connect(on_response);
action_interface.application.user_query(query);
}
private bool on_response(Gtk.ResponseType response)
{
if (response != Gtk.ResponseType.OK)
{
return true;
}
var branch_name = reference.get_shorthand();
var branch = (reference as Gitg.Branch);
try
{
if (branch.get_upstream() == null)
{
branch.set_upstream(branch_name);
}
}
catch (Error e)
{}
push.begin(branch_name, (obj, res) => {
push.end(res);
});
return true;
}
}
}
// ex:set ts=4 noet
......@@ -852,6 +852,15 @@ namespace GitgHistory
add_ref_action(actions, fetch);
var push = new Gitg.RefActionPush(application, af, reference);
if (push.available)
{
actions.add(null);
}
add_ref_action(actions, push);
var merge = new Gitg.RefActionMerge(application, af, reference);
if (merge.available)
......
......@@ -43,6 +43,7 @@ sources = gitg_sources + files(
'gitg-ref-action-copy-name.vala',
'gitg-ref-action-delete.vala',
'gitg-ref-action-fetch.vala',
'gitg-ref-action-push.vala',
'gitg-ref-action-rename.vala',
'gitg-remote-manager.vala',
'gitg-remote-notification.vala',
......
......@@ -309,6 +309,42 @@ public class Remote : Ggit.Remote
reset_transfer_progress(true);
}
private async void push_intern(string branch, Ggit.RemoteCallbacks? callbacks) throws Error
{
bool dis = false;
if (!get_connected())
{
dis = true;
yield connect(Ggit.Direction.PUSH, callbacks);
}
state = RemoteState.TRANSFERRING;
reset_transfer_progress(false);
try
{
yield Async.thread(() => {
var options = new Ggit.PushOptions();
options.set_remote_callbacks(d_callbacks);
string [] push_refs = { "refs/heads/%s:refs/heads/%s".printf(branch, branch) };
if (!base.push(push_refs, options))
throw new Error(0,0,"push");
});
}
catch (Error e)
{
update_state(dis);
reset_transfer_progress(true);
throw e;
}
update_state(dis);
reset_transfer_progress(true);
}
private async void download_intern(string? message, Ggit.RemoteCallbacks? callbacks) throws Error
{
bool dis = false;
......@@ -352,6 +388,11 @@ public class Remote : Ggit.Remote
yield download_intern(null, callbacks);
}
public new async void push(string branch, Ggit.RemoteCallbacks? callbacks = null) throws Error
{
yield push_intern(branch, callbacks);
}
public new async void fetch(string? message, Ggit.RemoteCallbacks? callbacks = null) throws Error
{
var msg = message;
......
......@@ -20,6 +20,7 @@ gitg/gitg-ref-action-checkout.vala
gitg/gitg-ref-action-copy-name.vala
gitg/gitg-ref-action-delete.vala
gitg/gitg-ref-action-fetch.vala
gitg/gitg-ref-action-push.vala
gitg/gitg-ref-action-merge.vala
gitg/gitg-ref-action-rename.vala
gitg/gitg-remote-notification.vala
......
......@@ -17,6 +17,7 @@ gitg/gitg-ref-action-checkout.c
gitg/gitg-ref-action-copy-name.c
gitg/gitg-ref-action-delete.c
gitg/gitg-ref-action-fetch.c
gitg/gitg-ref-action-push.c
gitg/gitg-ref-action-merge.c
gitg/gitg-ref-action-rename.c
gitg/gitg-remote-notification.c
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment