[gitg] Add push support



commit d172282bfaca22713d77a8a9384c1d98176bf53a
Author: Ignazio Sgalmuzzo <ignaker gmail com>
Date:   Tue Apr 23 21:26:05 2019 +0200

    Add push support

 gitg/gitg-ref-action-push.vala | 178 +++++++++++++++++++++++++++++++++++++++++
 gitg/history/gitg-history.vala |   9 +++
 gitg/meson.build               |   1 +
 libgitg/gitg-remote.vala       |  41 ++++++++++
 po/POTFILES.in                 |   1 +
 po/POTFILES.skip               |   1 +
 6 files changed, 231 insertions(+)
---
diff --git a/gitg/gitg-ref-action-push.vala b/gitg/gitg-ref-action-push.vala
new file mode 100644
index 00000000..0d5e7b2a
--- /dev/null
+++ b/gitg/gitg-ref-action-push.vala
@@ -0,0 +1,178 @@
+/*
+ * 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
diff --git a/gitg/history/gitg-history.vala b/gitg/history/gitg-history.vala
index df15767f..95833869 100644
--- a/gitg/history/gitg-history.vala
+++ b/gitg/history/gitg-history.vala
@@ -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)
diff --git a/gitg/meson.build b/gitg/meson.build
index 3ccd68ed..618053f9 100644
--- a/gitg/meson.build
+++ b/gitg/meson.build
@@ -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',
diff --git a/libgitg/gitg-remote.vala b/libgitg/gitg-remote.vala
index 979c58ce..e016f3c7 100644
--- a/libgitg/gitg-remote.vala
+++ b/libgitg/gitg-remote.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;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b977d566..7ad53b44 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -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
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 3a637232..479f0627 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]