[geany/geany-plugins] 51b4e3: git-ui: Monitor changes to the Git directory
Colomban Wendling
git-noreply at xxxxx
Wed Feb 18 08:38:04 UTC 2015
Branch: refs/heads/master
Author: Colomban Wendling <ban at herbesfolles.org>
Committer: Colomban Wendling <ban at herbesfolles.org>
Date: Sat, 04 Oct 2014 18:17:50 UTC
Commit: 51b4e3313037eccd0bfb8271cf65d1cc2fc4d7c2
https://github.com/geany/geany-plugins/commit/51b4e3313037eccd0bfb8271cf65d1cc2fc4d7c2
Log Message:
-----------
git-ui: Monitor changes to the Git directory
This allows to automatically update the diff bar when e.g. changes are
committed.
Modified Paths:
--------------
git-ui/src/ggu-plugin.c
Modified: git-ui/src/ggu-plugin.c
112 lines changed, 81 insertions(+), 31 deletions(-)
===================================================================
@@ -23,6 +23,7 @@
#include <glib.h>
#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
#include <gtk/gtk.h>
#include <git2.h>
@@ -62,6 +63,7 @@ enum {
static git_repository *G_repo = NULL;
static git_blob *G_file_blob = NULL;
/* global state */
+static GFileMonitor *G_monitor = NULL;
static gulong G_source_id = 0;
static struct {
gint num;
@@ -73,6 +75,13 @@ static struct {
};
+static void on_git_dir_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data);
+
+
/* get the file blob for @relpath at HEAD */
static git_blob *
repo_get_file_blob (git_repository *repo,
@@ -106,19 +115,40 @@ repo_get_file_blob (git_repository *repo,
/* FIXME: allow to do this in a separate thread because it can be slow */
static const git_blob *
-get_cached_blob (const gchar *path)
+get_cached_blob (GeanyDocument *doc)
{
- if (! G_file_blob) {
+ g_return_if_fail (DOC_VALID (doc));
+
+ if (! G_file_blob && doc->real_path) {
+ const gchar *path = doc->real_path;
+
if (G_repo && ! g_str_has_prefix (path, git_repository_workdir (G_repo))) {
/* FIXME: this can fail with nested repositories */
git_repository_free (G_repo);
G_repo = NULL;
+ if (G_monitor) {
+ g_object_unref (G_monitor);
+ G_monitor = NULL;
+ }
}
- if (! G_repo) {
- if (git_repository_open_ext (&G_repo, path, 0, NULL) == 0 &&
- git_repository_is_bare (G_repo)) {
+ if (! G_repo && git_repository_open_ext (&G_repo, path, 0, NULL) == 0) {
+ if (git_repository_is_bare (G_repo)) {
git_repository_free (G_repo);
G_repo = NULL;
+ } else {
+ GFile *file = g_file_new_for_path (git_repository_path (G_repo));
+ GError *err = NULL;
+
+ G_monitor = g_file_monitor_directory (file, 0, NULL, &err);
+ if (err) {
+ g_warning ("Failed to monitor Git directory: %s", err->message);
+ g_error_free (err);
+ } else {
+ g_signal_connect (G_monitor, "changed",
+ G_CALLBACK (on_git_dir_changed),
+ GUINT_TO_POINTER (doc->id));
+ }
+ g_object_unref (file);
}
}
@@ -244,35 +274,35 @@ diff_hunk_cb (const git_diff_delta *delta,
static void
update_diff (GeanyDocument *doc)
{
+ ScintillaObject *sci;
+ const git_blob *blob;
+
g_return_if_fail (DOC_VALID (doc));
- if (doc->real_path) {
- ScintillaObject *sci = doc->editor->sci;
- const git_blob *blob = get_cached_blob (doc->real_path);
+ sci = doc->editor->sci;
+ blob = get_cached_blob (doc);
+ if (blob && allocate_markers (sci)) {
+ git_diff_options opts;
+ const gchar *buf;
+ size_t len;
- if (blob && allocate_markers (sci)) {
- git_diff_options opts;
- const gchar *buf;
- size_t len;
-
- /* clear previous markers */
- scintilla_send_message (sci, SCI_MARKERDELETEALL,
- G_markers[MARKER_LINE_ADDED].num, 0);
- scintilla_send_message (sci, SCI_MARKERDELETEALL,
- G_markers[MARKER_LINE_CHANGED].num, 0);
-
- buf = (const gchar *) scintilla_send_message (sci, SCI_GETCHARACTERPOINTER,
- 0, 0);
- len = sci_get_length (sci);
-
- /* no context lines, and no need to bother about binary checks */
- git_diff_init_options (&opts, GIT_DIFF_OPTIONS_VERSION);
- opts.context_lines = 0;
- opts.flags = GIT_DIFF_FORCE_TEXT;
-
- git_diff_blob_to_buffer (blob, NULL, buf, len, NULL, &opts,
- NULL, diff_hunk_cb, NULL, sci);
- }
+ /* clear previous markers */
+ scintilla_send_message (sci, SCI_MARKERDELETEALL,
+ G_markers[MARKER_LINE_ADDED].num, 0);
+ scintilla_send_message (sci, SCI_MARKERDELETEALL,
+ G_markers[MARKER_LINE_CHANGED].num, 0);
+
+ buf = (const gchar *) scintilla_send_message (sci, SCI_GETCHARACTERPOINTER,
+ 0, 0);
+ len = sci_get_length (sci);
+
+ /* no context lines, and no need to bother about binary checks */
+ git_diff_init_options (&opts, GIT_DIFF_OPTIONS_VERSION);
+ opts.context_lines = 0;
+ opts.flags = GIT_DIFF_FORCE_TEXT;
+
+ git_diff_blob_to_buffer (blob, NULL, buf, len, NULL, &opts,
+ NULL, diff_hunk_cb, NULL, sci);
}
}
@@ -335,6 +365,21 @@ on_document_reload (GObject *obj,
update_diff_push (doc);
}
+static void
+on_git_dir_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ GeanyDocument *doc = document_find_by_id (GPOINTER_TO_UINT (user_data));
+
+ if (doc) {
+ clear_cached_blob ();
+ update_diff_push (doc);
+ }
+}
+
void
plugin_init (GeanyData *data)
{
@@ -342,6 +387,7 @@ plugin_init (GeanyData *data)
G_file_blob = NULL;
G_repo = NULL;
+ G_monitor = NULL;
G_source_id = 0;
if (git_threads_init () != 0) {
@@ -372,6 +418,10 @@ plugin_cleanup (void)
{
guint i;
+ if (G_monitor) {
+ g_object_unref (G_monitor);
+ G_monitor = NULL;
+ }
if (G_source_id) {
g_source_remove (G_source_id);
G_source_id = 0;
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list