mirror of
https://gitlab.gnome.org/GNOME/gitg
synced 2024-07-16 10:38:22 +00:00
Improved GitgRunner/GitgCommand/GitgShell
This commit is contained in:
parent
c974834cb2
commit
f9ef65b59d
|
@ -1,6 +1,6 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = libgitg gitg data po
|
||||
SUBDIRS = libgitg gitg data po tests tools
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libgitg-1.0.pc
|
||||
|
|
|
@ -144,6 +144,8 @@ data/Makefile
|
|||
data/gitg.desktop.in
|
||||
data/icons/Makefile
|
||||
po/Makefile.in
|
||||
tests/Makefile
|
||||
tools/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef void (*ProgressCallback) (GitgWindow *window, GitgProgress progress, gpo
|
|||
typedef struct
|
||||
{
|
||||
GitgWindow *window;
|
||||
GitgRunner *runner;
|
||||
GitgShell *shell;
|
||||
|
||||
ProgressCallback callback;
|
||||
gpointer callback_data;
|
||||
|
@ -59,7 +59,7 @@ free_progress_info (ProgressInfo *info)
|
|||
|
||||
gtk_widget_destroy (GTK_WIDGET (info->dialog));
|
||||
|
||||
g_object_unref (info->runner);
|
||||
g_object_unref (info->shell);
|
||||
g_slice_free (ProgressInfo, info);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ parse_valist (va_list ap)
|
|||
}
|
||||
|
||||
static void
|
||||
on_progress_end (GitgRunner *runner, gboolean cancelled, ProgressInfo *info)
|
||||
on_progress_end (GitgShell *shell, gboolean cancelled, ProgressInfo *info)
|
||||
{
|
||||
GitgProgress progress;
|
||||
|
||||
|
@ -89,7 +89,7 @@ on_progress_end (GitgRunner *runner, gboolean cancelled, ProgressInfo *info)
|
|||
{
|
||||
progress = GITG_PROGRESS_CANCELLED;
|
||||
}
|
||||
else if (gitg_runner_get_exit_status (runner) != 0)
|
||||
else if (gitg_io_get_exit_status (GITG_IO (shell)) != 0)
|
||||
{
|
||||
progress = GITG_PROGRESS_ERROR;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ on_progress_end (GitgRunner *runner, gboolean cancelled, ProgressInfo *info)
|
|||
static void
|
||||
on_progress_response (GtkDialog *dialog, GtkResponseType response, ProgressInfo *info)
|
||||
{
|
||||
gitg_runner_cancel (info->runner);
|
||||
gitg_io_cancel (GITG_IO (info->shell));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -119,7 +119,7 @@ on_progress_timeout (ProgressInfo *info)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static GitgRunner *
|
||||
static GitgShell *
|
||||
run_progress (GitgWindow *window,
|
||||
gchar const *title,
|
||||
gchar const *message,
|
||||
|
@ -129,19 +129,18 @@ run_progress (GitgWindow *window,
|
|||
{
|
||||
va_list ap;
|
||||
|
||||
// Create runner
|
||||
va_start (ap, callback_data);
|
||||
|
||||
GitgRunner *runner = gitg_runner_new (1000);
|
||||
GitgShell *shell = gitg_shell_new (1000);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
|
||||
if (!gitg_repository_run_command (gitg_window_get_repository (window),
|
||||
runner,
|
||||
argv,
|
||||
NULL))
|
||||
GitgCommand *cmd = gitg_command_new (gitg_window_get_repository (window),
|
||||
(gchar const * const *)argv);
|
||||
|
||||
if (!gitg_shell_run (shell, cmd, NULL))
|
||||
{
|
||||
g_free (argv);
|
||||
g_object_unref (runner);
|
||||
g_object_unref (shell);
|
||||
|
||||
callback (window, GITG_PROGRESS_ERROR, callback_data);
|
||||
|
||||
|
@ -183,14 +182,14 @@ run_progress (GitgWindow *window,
|
|||
info->callback = callback;
|
||||
info->callback_data = callback_data;
|
||||
info->window = window;
|
||||
info->runner = g_object_ref (runner);
|
||||
info->shell = g_object_ref (shell);
|
||||
|
||||
info->timeout_id = g_timeout_add (100, (GSourceFunc)on_progress_timeout, info);
|
||||
|
||||
g_signal_connect (dlg, "response", G_CALLBACK (on_progress_response), info);
|
||||
g_signal_connect (runner, "end-loading", G_CALLBACK (on_progress_end), info);
|
||||
g_signal_connect (shell, "end", G_CALLBACK (on_progress_end), info);
|
||||
|
||||
return runner;
|
||||
return shell;
|
||||
}
|
||||
|
||||
static gint
|
||||
|
@ -257,14 +256,19 @@ message_dialog (GitgWindow *window,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static GitgRunner *
|
||||
static GitgShell *
|
||||
remove_local_branch (GitgWindow *window,
|
||||
GitgRef *ref)
|
||||
{
|
||||
gchar const *name = gitg_ref_get_shortname (ref);
|
||||
GitgRepository *repository = gitg_window_get_repository (window);
|
||||
|
||||
if (!gitg_repository_commandv (repository, NULL, "branch", "-d", name, NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"branch",
|
||||
"-d",
|
||||
name,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
gint ret = message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -275,7 +279,12 @@ remove_local_branch (GitgWindow *window,
|
|||
|
||||
if (ret == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
if (!gitg_repository_commandv (repository, NULL, "branch", "-D", name, NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"branch",
|
||||
"-D",
|
||||
name,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -325,7 +334,7 @@ on_remove_remote_result (GitgWindow *window, GitgProgress progress, gpointer dat
|
|||
gitg_ref_free (ref);
|
||||
}
|
||||
|
||||
static GitgRunner *
|
||||
static GitgShell *
|
||||
remove_remote_branch (GitgWindow *window,
|
||||
GitgRef *ref)
|
||||
{
|
||||
|
@ -346,7 +355,7 @@ remove_remote_branch (GitgWindow *window,
|
|||
gchar const *local = gitg_ref_get_local_name (ref);
|
||||
gchar *rm = g_strconcat (":", local, NULL);
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
gchar *message = g_strdup_printf ("Removing remote branch `%s'", name);
|
||||
|
||||
ret = run_progress (window,
|
||||
|
@ -368,14 +377,15 @@ get_stash_refspec (GitgRepository *repository, GitgRef *stash)
|
|||
{
|
||||
gchar **out;
|
||||
|
||||
out = gitg_repository_command_with_outputv (repository,
|
||||
NULL,
|
||||
"log",
|
||||
"--no-color",
|
||||
"--pretty=oneline",
|
||||
"-g",
|
||||
"refs/stash",
|
||||
NULL);
|
||||
out = gitg_shell_run_sync_with_output (gitg_command_newv (repository,
|
||||
"log",
|
||||
"--no-color",
|
||||
"--pretty=oneline",
|
||||
"-g",
|
||||
"refs/stash",
|
||||
NULL),
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
gchar **ptr = out;
|
||||
gchar *sha1 = gitg_hash_hash_to_sha1_new (gitg_ref_get_hash (stash));
|
||||
|
@ -403,7 +413,7 @@ get_stash_refspec (GitgRepository *repository, GitgRef *stash)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static GitgRunner *
|
||||
static GitgShell *
|
||||
remove_stash (GitgWindow *window, GitgRef *ref)
|
||||
{
|
||||
gint r = message_dialog (window,
|
||||
|
@ -425,14 +435,14 @@ remove_stash (GitgWindow *window, GitgRef *ref)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"reflog",
|
||||
"delete",
|
||||
"--updateref",
|
||||
"--rewrite",
|
||||
spec,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"reflog",
|
||||
"delete",
|
||||
"--updateref",
|
||||
"--rewrite",
|
||||
spec,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -442,19 +452,19 @@ remove_stash (GitgWindow *window, GitgRef *ref)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"rev-parse",
|
||||
"--verify",
|
||||
"refs/stash@{0}",
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"rev-parse",
|
||||
"--verify",
|
||||
"refs/stash@{0}",
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"update-ref",
|
||||
"-d",
|
||||
"refs/stash",
|
||||
NULL);
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"update-ref",
|
||||
"-d",
|
||||
"refs/stash",
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
gitg_repository_reload (repository);
|
||||
|
@ -464,7 +474,7 @@ remove_stash (GitgWindow *window, GitgRef *ref)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GitgRunner *
|
||||
static GitgShell *
|
||||
remove_tag (GitgWindow *window, GitgRef *ref)
|
||||
{
|
||||
gchar const *name = gitg_ref_get_shortname (ref);
|
||||
|
@ -484,12 +494,12 @@ remove_tag (GitgWindow *window, GitgRef *ref)
|
|||
|
||||
GitgRepository *repository = gitg_window_get_repository (window);
|
||||
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"tag",
|
||||
"-d",
|
||||
name,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"tag",
|
||||
"-d",
|
||||
name,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message = g_strdup_printf (_ ("The tag <%s> could not be successfully removed"),
|
||||
name);
|
||||
|
@ -508,7 +518,7 @@ remove_tag (GitgWindow *window, GitgRef *ref)
|
|||
}
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_remove (GitgWindow *window,
|
||||
GitgRef *ref)
|
||||
{
|
||||
|
@ -516,7 +526,7 @@ gitg_branch_actions_remove (GitgWindow *window,
|
|||
g_return_val_if_fail (ref != NULL, NULL);
|
||||
|
||||
GitgRef *cp = gitg_ref_copy (ref);
|
||||
GitgRunner *ret = NULL;
|
||||
GitgShell *ret = NULL;
|
||||
|
||||
switch (gitg_ref_get_ref_type (cp))
|
||||
{
|
||||
|
@ -540,7 +550,7 @@ gitg_branch_actions_remove (GitgWindow *window,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static GitgRunner *
|
||||
static GitgShell *
|
||||
rename_branch (GitgWindow *window,
|
||||
GitgRef *ref,
|
||||
const gchar *newname)
|
||||
|
@ -548,7 +558,13 @@ rename_branch (GitgWindow *window,
|
|||
gchar const *oldname = gitg_ref_get_shortname (ref);
|
||||
GitgRepository *repository = gitg_window_get_repository (window);
|
||||
|
||||
if (!gitg_repository_commandv (repository, NULL, "branch", "-m", oldname, newname, NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"branch",
|
||||
"-m",
|
||||
oldname,
|
||||
newname,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
gint ret = message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -559,7 +575,13 @@ rename_branch (GitgWindow *window,
|
|||
|
||||
if (ret == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
if (!gitg_repository_commandv (repository, NULL, "branch", "-M", oldname, newname, NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"branch",
|
||||
"-M",
|
||||
oldname,
|
||||
newname,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -635,7 +657,7 @@ rename_dialog (GitgWindow *window, const gchar *oldname)
|
|||
return newname;
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_rename (GitgWindow *window,
|
||||
GitgRef *ref)
|
||||
{
|
||||
|
@ -649,7 +671,7 @@ gitg_branch_actions_rename (GitgWindow *window,
|
|||
if (newname)
|
||||
{
|
||||
GitgRef *cp = gitg_ref_copy (ref);
|
||||
GitgRunner *ret = NULL;
|
||||
GitgShell *ret = NULL;
|
||||
ret = rename_branch (window, cp, newname);
|
||||
gitg_ref_free (cp);
|
||||
g_free (newname);
|
||||
|
@ -661,13 +683,13 @@ gitg_branch_actions_rename (GitgWindow *window,
|
|||
}
|
||||
|
||||
static void
|
||||
reset_buffer (GitgRunner *runner, GString *buffer)
|
||||
reset_buffer (GitgShell *shell, GString *buffer)
|
||||
{
|
||||
g_string_erase (buffer, 0, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
update_buffer (GitgRunner *runner, gchar **lines, GString *buffer)
|
||||
update_buffer (GitgShell *shell, gchar **lines, GString *buffer)
|
||||
{
|
||||
gchar **ptr = lines;
|
||||
|
||||
|
@ -686,12 +708,26 @@ update_buffer (GitgRunner *runner, gchar **lines, GString *buffer)
|
|||
static gboolean
|
||||
no_changes (GitgRepository *repository)
|
||||
{
|
||||
return gitg_repository_commandv (repository, NULL,
|
||||
"update-index", "--refresh", NULL) &&
|
||||
gitg_repository_commandv (repository, NULL,
|
||||
"diff-files", "--quiet", NULL) &&
|
||||
gitg_repository_commandv (repository, NULL,
|
||||
"diff-index", "--cached", "--quiet", "HEAD", "--", NULL);
|
||||
return gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"update-index",
|
||||
"--refresh",
|
||||
NULL),
|
||||
NULL) &&
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"diff-files",
|
||||
"--no-ext-diff",
|
||||
"--quiet",
|
||||
NULL),
|
||||
NULL) &&
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"diff-index",
|
||||
"--no-ext-diff",
|
||||
"--cached",
|
||||
"--quiet",
|
||||
"HEAD",
|
||||
"--",
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -705,11 +741,11 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
gchar *msg = NULL;
|
||||
gboolean showerror = FALSE;
|
||||
|
||||
GitgRunner *runner = gitg_runner_new_synchronized (1000);
|
||||
GitgShell *shell = gitg_shell_new_synchronized (1000);
|
||||
GString *buffer = g_string_new ("");
|
||||
|
||||
g_signal_connect (runner, "begin-loading", G_CALLBACK (reset_buffer), buffer);
|
||||
g_signal_connect (runner, "update", G_CALLBACK (update_buffer), buffer);
|
||||
g_signal_connect (shell, "begin", G_CALLBACK (reset_buffer), buffer);
|
||||
g_signal_connect (shell, "update", G_CALLBACK (update_buffer), buffer);
|
||||
|
||||
gchar const *secondary;
|
||||
|
||||
|
@ -734,9 +770,17 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"log", "--no-color", "--abbrev-commit",
|
||||
"--pretty=oneline", "-n", "1", "HEAD", NULL);
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (repository,
|
||||
"log",
|
||||
"--no-color",
|
||||
"--abbrev-commit",
|
||||
"--pretty=oneline",
|
||||
"-n",
|
||||
"1",
|
||||
"HEAD",
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
GitgRef *working = gitg_repository_get_current_working_ref (repository);
|
||||
|
||||
|
@ -750,8 +794,11 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
}
|
||||
|
||||
// Create tree object of the current index
|
||||
gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"write-tree", NULL);
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (repository,
|
||||
"write-tree",
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
if (buffer->len == 0)
|
||||
{
|
||||
|
@ -765,10 +812,22 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
head = gitg_repository_parse_head (repository);
|
||||
|
||||
gchar *idxmsg = g_strconcat ("index on ", msg, NULL);
|
||||
gitg_repository_run_command_with_inputv (repository, runner, idxmsg, NULL,
|
||||
"commit-tree", tree, "-p", head, NULL);
|
||||
|
||||
GInputStream *inp = g_memory_input_stream_new_from_data (idxmsg, -1, NULL);
|
||||
gitg_io_set_input (GITG_IO (shell), inp);
|
||||
g_object_unref (inp);
|
||||
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (repository,
|
||||
"commit-tree",
|
||||
tree,
|
||||
"-p",
|
||||
head,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (idxmsg);
|
||||
gitg_io_set_input (GITG_IO (shell), NULL);
|
||||
|
||||
if (buffer->len == 0)
|
||||
{
|
||||
|
@ -814,23 +873,48 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
}
|
||||
|
||||
tmpname = g_file_get_path (customindex);
|
||||
gitg_runner_add_environment (runner, "GIT_INDEX_FILE", tmpname);
|
||||
|
||||
GitgCommand *cmd_read_tree = gitg_command_newv (repository,
|
||||
"read-tree",
|
||||
"-m",
|
||||
tree,
|
||||
NULL);
|
||||
|
||||
gitg_command_add_environmentv (cmd_read_tree,
|
||||
"GIT_INDEX_FILE",
|
||||
tmpname,
|
||||
NULL);
|
||||
|
||||
GitgCommand *cmd_add = gitg_command_newv (repository,
|
||||
"add",
|
||||
"-u",
|
||||
NULL);
|
||||
|
||||
gitg_command_add_environmentv (cmd_add,
|
||||
"GIT_INDEX_FILE",
|
||||
tmpname,
|
||||
NULL);
|
||||
|
||||
GitgCommand *cmd_write_tree = gitg_command_newv (repository,
|
||||
"write-tree",
|
||||
NULL);
|
||||
|
||||
gitg_command_add_environmentv (cmd_write_tree,
|
||||
"GIT_INDEX_FILE",
|
||||
tmpname,
|
||||
NULL);
|
||||
|
||||
g_free (tmpname);
|
||||
|
||||
gboolean writestash;
|
||||
|
||||
writestash = gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"read-tree", "-m", tree, NULL) &&
|
||||
gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"add", "-u", NULL) &&
|
||||
gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"write-tree", NULL);
|
||||
writestash = gitg_shell_run (shell, cmd_read_tree, NULL) &&
|
||||
gitg_shell_run (shell, cmd_add, NULL) &&
|
||||
gitg_shell_run (shell, cmd_write_tree, NULL);
|
||||
|
||||
g_file_delete (customindex, NULL, NULL);
|
||||
g_object_unref (customindex);
|
||||
|
||||
gitg_runner_set_environment (runner, NULL);
|
||||
|
||||
if (!writestash)
|
||||
{
|
||||
ret = FALSE;
|
||||
|
@ -842,10 +926,23 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
gchar *stashtree = g_strndup (buffer->str, buffer->len);
|
||||
gchar *reason = g_strconcat ("gitg auto stash: ", msg, NULL);
|
||||
|
||||
gitg_repository_run_command_with_inputv (repository, runner, reason, NULL,
|
||||
"commit-tree", stashtree,
|
||||
"-p", head,
|
||||
"-p", commit, NULL);
|
||||
inp = g_memory_input_stream_new_from_data (reason, -1, NULL);
|
||||
gitg_io_set_input (GITG_IO (shell), inp);
|
||||
g_object_unref (inp);
|
||||
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (repository,
|
||||
"commit-tree",
|
||||
stashtree,
|
||||
"-p",
|
||||
head,
|
||||
"-p",
|
||||
commit,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
gitg_io_set_input (GITG_IO (shell), NULL);
|
||||
|
||||
g_free (stashtree);
|
||||
|
||||
if (buffer->len == 0)
|
||||
|
@ -887,19 +984,30 @@ stash_changes_real (GitgWindow *window, gchar **ref, gboolean storeref)
|
|||
|
||||
g_free (path);
|
||||
|
||||
gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"update-ref", "-m", reason,
|
||||
"refs/stash", rref, NULL);
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (repository,
|
||||
"update-ref",
|
||||
"-m",
|
||||
reason,
|
||||
"refs/stash",
|
||||
rref,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (rref);
|
||||
|
||||
gitg_repository_run_commandv (repository, runner, NULL,
|
||||
"reset", "--hard", NULL);
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (repository,
|
||||
"reset",
|
||||
"--hard",
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
cleanup:
|
||||
g_string_free (buffer, TRUE);
|
||||
g_object_unref (runner);
|
||||
g_object_unref (shell);
|
||||
g_free (commit);
|
||||
g_free (tree);
|
||||
g_free (head);
|
||||
|
@ -938,14 +1046,11 @@ checkout_local_branch_real (GitgWindow *window, GitgRef *ref)
|
|||
{
|
||||
GitgRepository *repository = gitg_window_get_repository (window);
|
||||
|
||||
if (!gitg_repository_commandv (repository, NULL, "checkout", gitg_ref_get_shortname (ref), NULL))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"checkout",
|
||||
gitg_ref_get_shortname (ref),
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -990,14 +1095,14 @@ checkout_remote_branch (GitgWindow *window,
|
|||
gchar const *local = gitg_ref_get_local_name (ref);
|
||||
gboolean ret;
|
||||
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"checkout",
|
||||
"--track",
|
||||
"-b",
|
||||
local,
|
||||
name,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"checkout",
|
||||
"--track",
|
||||
"-b",
|
||||
local,
|
||||
name,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -1030,13 +1135,13 @@ checkout_tag (GitgWindow *window,
|
|||
gchar const *name = gitg_ref_get_shortname (ref);
|
||||
gboolean ret;
|
||||
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"checkout",
|
||||
"-b",
|
||||
name,
|
||||
name,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"checkout",
|
||||
"-b",
|
||||
name,
|
||||
name,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -1139,14 +1244,14 @@ on_merge_rebase_result (GitgWindow *window,
|
|||
}
|
||||
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
message,
|
||||
NULL,
|
||||
NULL,
|
||||
gitg_ref_get_ref_type (info->source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
|
||||
gitg_ref_get_shortname (info->source),
|
||||
gitg_ref_get_ref_type (info->dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
|
||||
gitg_ref_get_shortname (info->dest));
|
||||
GTK_MESSAGE_ERROR,
|
||||
message,
|
||||
NULL,
|
||||
NULL,
|
||||
gitg_ref_get_ref_type (info->source) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
|
||||
gitg_ref_get_shortname (info->source),
|
||||
gitg_ref_get_ref_type (info->dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
|
||||
gitg_ref_get_shortname (info->dest));
|
||||
}
|
||||
else if (progress == GITG_PROGRESS_SUCCESS)
|
||||
{
|
||||
|
@ -1159,32 +1264,43 @@ on_merge_rebase_result (GitgWindow *window,
|
|||
|
||||
if (info->stashcommit)
|
||||
{
|
||||
gitg_repository_commandv (repository, NULL,
|
||||
"update-ref", "-m", "gitg autosave stash",
|
||||
"refs/stash", info->stashcommit, NULL);
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"update-ref",
|
||||
"-m",
|
||||
"gitg autosave stash",
|
||||
"refs/stash",
|
||||
info->stashcommit,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
message = _ ("The stashed changes have been stored to be reapplied manually");
|
||||
}
|
||||
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
_ ("Failed to checkout previously checked out branch"),
|
||||
message,
|
||||
NULL);
|
||||
GTK_MESSAGE_ERROR,
|
||||
_ ("Failed to checkout previously checked out branch"),
|
||||
message,
|
||||
NULL);
|
||||
}
|
||||
else if (info->stashcommit)
|
||||
{
|
||||
// Reapply stash
|
||||
if (!gitg_repository_commandv (gitg_window_get_repository (window),
|
||||
NULL,
|
||||
"stash",
|
||||
"apply",
|
||||
"--index",
|
||||
info->stashcommit,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (gitg_window_get_repository (window),
|
||||
"stash",
|
||||
"apply",
|
||||
"--index",
|
||||
info->stashcommit,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
gitg_repository_commandv (repository, NULL,
|
||||
"update-ref", "-m", "gitg autosave stash",
|
||||
"refs/stash", info->stashcommit, NULL);
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"update-ref",
|
||||
"-m",
|
||||
"gitg autosave stash",
|
||||
"refs/stash",
|
||||
info->stashcommit,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -1200,7 +1316,7 @@ on_merge_rebase_result (GitgWindow *window,
|
|||
ref_info_free (info);
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_merge (GitgWindow *window,
|
||||
GitgRef *source,
|
||||
GitgRef *dest)
|
||||
|
@ -1238,7 +1354,11 @@ gitg_branch_actions_merge (GitgWindow *window,
|
|||
GitgRef *head = gitg_repository_get_current_working_ref (repository);
|
||||
|
||||
// First checkout the correct branch on which to merge, e.g. dest
|
||||
if (!gitg_repository_commandv (repository, NULL, "checkout", gitg_ref_get_shortname (dest), NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"checkout",
|
||||
gitg_ref_get_shortname (dest),
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
g_free (stashcommit);
|
||||
|
||||
|
@ -1257,7 +1377,7 @@ gitg_branch_actions_merge (GitgWindow *window,
|
|||
gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
|
||||
gitg_ref_get_shortname (dest));
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
RefInfo *info = ref_info_new (source, dest);
|
||||
info->stashcommit = stashcommit;
|
||||
info->head = gitg_ref_copy (head);
|
||||
|
@ -1277,7 +1397,7 @@ gitg_branch_actions_merge (GitgWindow *window,
|
|||
return ret;
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_rebase (GitgWindow *window,
|
||||
GitgRef *source,
|
||||
GitgRef *dest)
|
||||
|
@ -1340,7 +1460,7 @@ gitg_branch_actions_rebase (GitgWindow *window,
|
|||
gitg_ref_get_ref_type (dest) == GITG_REF_TYPE_BRANCH ? _ ("local") : _ ("remote"),
|
||||
gitg_ref_get_shortname (dest));
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
RefInfo *info = ref_info_new (source, dest);
|
||||
info->stashcommit = stashcommit;
|
||||
info->head = gitg_ref_copy (gitg_repository_get_current_working_ref (repository));
|
||||
|
@ -1387,7 +1507,7 @@ on_push_result (GitgWindow *window,
|
|||
ref_info_free (info);
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_push (GitgWindow *window,
|
||||
GitgRef *source,
|
||||
GitgRef *dest)
|
||||
|
@ -1423,7 +1543,7 @@ gitg_branch_actions_push (GitgWindow *window,
|
|||
gitg_ref_get_shortname (source),
|
||||
gitg_ref_get_shortname (dest));
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
RefInfo *info = ref_info_new (source, dest);
|
||||
|
||||
ret = run_progress (window,
|
||||
|
@ -1442,7 +1562,7 @@ gitg_branch_actions_push (GitgWindow *window,
|
|||
return ret;
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_push_remote (GitgWindow *window,
|
||||
GitgRef *source,
|
||||
gchar const *remote,
|
||||
|
@ -1475,7 +1595,7 @@ gitg_branch_actions_push_remote (GitgWindow *window,
|
|||
gitg_ref_get_shortname (source),
|
||||
remote, branch);
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
gchar *rr = g_strconcat ("refs/remotes/", remote, "/", branch, NULL);
|
||||
GitgRef *rmref = gitg_ref_new ("0000000000000000000000000000000000000000", rr);
|
||||
g_free (rr);
|
||||
|
@ -1546,13 +1666,13 @@ gitg_branch_actions_apply_stash (GitgWindow *window,
|
|||
gchar *sha1 = gitg_hash_hash_to_sha1_new (gitg_ref_get_hash (stash));
|
||||
gboolean ret;
|
||||
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"stash",
|
||||
"apply",
|
||||
"--index",
|
||||
sha1,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"stash",
|
||||
"apply",
|
||||
"--index",
|
||||
sha1,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
message = g_strdup_printf (_ ("The stash could not be applied to local branch <%s>"),
|
||||
gitg_ref_get_shortname (branch));
|
||||
|
@ -1590,12 +1710,12 @@ gitg_branch_actions_create (GitgWindow *window, gchar const *sha1, gchar const *
|
|||
|
||||
repository = gitg_window_get_repository (window);
|
||||
|
||||
result = gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"branch",
|
||||
name,
|
||||
sha1,
|
||||
NULL);
|
||||
result = gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"branch",
|
||||
name,
|
||||
sha1,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
|
@ -1631,24 +1751,24 @@ gitg_branch_actions_tag (GitgWindow *window, gchar const *sha1, gchar const *nam
|
|||
|
||||
if (message != NULL && message[0] != '\0')
|
||||
{
|
||||
result = gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"tag",
|
||||
"-m",
|
||||
message,
|
||||
sign ? "-s" : "-a",
|
||||
name,
|
||||
sha1,
|
||||
NULL);
|
||||
result = gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"tag",
|
||||
"-m",
|
||||
message,
|
||||
sign ? "-s" : "-a",
|
||||
name,
|
||||
sha1,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"tag",
|
||||
name,
|
||||
sha1,
|
||||
NULL);
|
||||
result = gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"tag",
|
||||
name,
|
||||
sha1,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
|
@ -1737,9 +1857,14 @@ on_cherry_pick_result (GitgWindow *window,
|
|||
|
||||
if (info->stashcommit)
|
||||
{
|
||||
gitg_repository_commandv (repository, NULL,
|
||||
"update-ref", "-m", "gitg autosave stash",
|
||||
"refs/stash", info->stashcommit, NULL);
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"update-ref",
|
||||
"-m",
|
||||
"gitg autosave stash",
|
||||
"refs/stash",
|
||||
info->stashcommit,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
message = _ ("The stashed changes have been stored to be reapplied manually");
|
||||
}
|
||||
|
@ -1753,17 +1878,22 @@ on_cherry_pick_result (GitgWindow *window,
|
|||
else if (info->stashcommit)
|
||||
{
|
||||
// Reapply stash
|
||||
if (!gitg_repository_commandv (gitg_window_get_repository (window),
|
||||
NULL,
|
||||
"stash",
|
||||
"apply",
|
||||
"--index",
|
||||
info->stashcommit,
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (gitg_window_get_repository (window),
|
||||
"stash",
|
||||
"apply",
|
||||
"--index",
|
||||
info->stashcommit,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
gitg_repository_commandv (repository, NULL,
|
||||
"update-ref", "-m", "gitg autosave stash",
|
||||
"refs/stash", info->stashcommit, NULL);
|
||||
gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"update-ref",
|
||||
"-m",
|
||||
"gitg autosave stash",
|
||||
"refs/stash",
|
||||
info->stashcommit,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
message_dialog (window,
|
||||
GTK_MESSAGE_ERROR,
|
||||
|
@ -1779,7 +1909,7 @@ on_cherry_pick_result (GitgWindow *window,
|
|||
cherry_pick_info_free (info);
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_cherry_pick (GitgWindow *window,
|
||||
GitgRevision *revision,
|
||||
GitgRef *dest)
|
||||
|
@ -1812,11 +1942,11 @@ gitg_branch_actions_cherry_pick (GitgWindow *window,
|
|||
GitgRef *head = gitg_repository_get_current_working_ref (repository);
|
||||
|
||||
// First checkout the correct branch on which to cherry-pick
|
||||
if (!gitg_repository_commandv (repository,
|
||||
NULL,
|
||||
"checkout",
|
||||
gitg_ref_get_shortname (dest),
|
||||
NULL))
|
||||
if (!gitg_shell_run_sync (gitg_command_newv (repository,
|
||||
"checkout",
|
||||
gitg_ref_get_shortname (dest),
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
g_free (stashcommit);
|
||||
|
||||
|
@ -1833,7 +1963,7 @@ gitg_branch_actions_cherry_pick (GitgWindow *window,
|
|||
message = g_strdup_printf (_ ("Cherry-picking on <%s>"),
|
||||
gitg_ref_get_shortname (dest));
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
|
||||
CherryPickInfo *info = cherry_pick_info_new (revision, dest);
|
||||
|
||||
|
@ -1908,7 +2038,7 @@ on_format_patch_result (GitgWindow *window,
|
|||
}
|
||||
|
||||
static void
|
||||
on_format_patch_update (GitgRunner *runner,
|
||||
on_format_patch_update (GitgShell *shell,
|
||||
gchar **lines,
|
||||
FormatPatchInfo *info)
|
||||
{
|
||||
|
@ -1920,7 +2050,7 @@ on_format_patch_update (GitgRunner *runner,
|
|||
}
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_branch_actions_format_patch (GitgWindow *window,
|
||||
GitgRevision *revision,
|
||||
gchar const *destination)
|
||||
|
@ -1929,7 +2059,7 @@ gitg_branch_actions_format_patch (GitgWindow *window,
|
|||
g_return_val_if_fail (revision != NULL, NULL);
|
||||
g_return_val_if_fail (destination != NULL, NULL);
|
||||
|
||||
GitgRunner *ret;
|
||||
GitgShell *ret;
|
||||
|
||||
GFile *file = g_file_new_for_uri (destination);
|
||||
GFileOutputStream *stream = g_file_replace (file,
|
||||
|
|
|
@ -24,28 +24,28 @@
|
|||
#define __GITG_BRANCH_ACTIONS_H__
|
||||
|
||||
#include <libgitg/gitg-ref.h>
|
||||
#include "gitg-window.h"
|
||||
#include <gitg/gitg-window.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean gitg_branch_actions_create (GitgWindow *window, gchar const *sha1, gchar const *name);
|
||||
GitgRunner *gitg_branch_actions_remove (GitgWindow *window, GitgRef *ref);
|
||||
GitgRunner *gitg_branch_actions_rename (GitgWindow *window, GitgRef *ref);
|
||||
GitgShell *gitg_branch_actions_remove (GitgWindow *window, GitgRef *ref);
|
||||
GitgShell *gitg_branch_actions_rename (GitgWindow *window, GitgRef *ref);
|
||||
gboolean gitg_branch_actions_checkout (GitgWindow *window, GitgRef *ref);
|
||||
|
||||
GitgRunner *gitg_branch_actions_merge (GitgWindow *window, GitgRef *source, GitgRef *dest);
|
||||
GitgRunner *gitg_branch_actions_rebase (GitgWindow *window, GitgRef *source, GitgRef *dest);
|
||||
GitgShell *gitg_branch_actions_merge (GitgWindow *window, GitgRef *source, GitgRef *dest);
|
||||
GitgShell *gitg_branch_actions_rebase (GitgWindow *window, GitgRef *source, GitgRef *dest);
|
||||
|
||||
GitgRunner *gitg_branch_actions_push (GitgWindow *window, GitgRef *source, GitgRef *dest);
|
||||
GitgRunner *gitg_branch_actions_push_remote (GitgWindow *window, GitgRef *source, gchar const *remote, gchar const *branch);
|
||||
GitgShell *gitg_branch_actions_push (GitgWindow *window, GitgRef *source, GitgRef *dest);
|
||||
GitgShell *gitg_branch_actions_push_remote (GitgWindow *window, GitgRef *source, gchar const *remote, gchar const *branch);
|
||||
|
||||
gboolean gitg_branch_actions_apply_stash (GitgWindow *window, GitgRef *stash, GitgRef *branch);
|
||||
|
||||
gboolean gitg_branch_actions_tag (GitgWindow *window, gchar const *sha1, gchar const *name, gchar const *message, gboolean sign);
|
||||
|
||||
GitgRunner *gitg_branch_actions_cherry_pick (GitgWindow *window, GitgRevision *revision, GitgRef *dest);
|
||||
GitgShell *gitg_branch_actions_cherry_pick (GitgWindow *window, GitgRevision *revision, GitgRef *dest);
|
||||
|
||||
GitgRunner *gitg_branch_actions_format_patch (GitgWindow *window, GitgRevision *revision, gchar const *destination);
|
||||
GitgShell *gitg_branch_actions_format_patch (GitgWindow *window, GitgRevision *revision, gchar const *destination);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
#include <libgitg/gitg-commit.h>
|
||||
#include <libgitg/gitg-shell.h>
|
||||
|
||||
#include "gitg-commit-view.h"
|
||||
#include "gitg-diff-view.h"
|
||||
|
@ -78,7 +79,7 @@ struct _GitgCommitViewPrivate
|
|||
GtkHScale *hscale_context;
|
||||
gint context_size;
|
||||
|
||||
GitgRunner *runner;
|
||||
GitgShell *shell;
|
||||
guint update_id;
|
||||
gboolean is_diff;
|
||||
|
||||
|
@ -138,11 +139,11 @@ gitg_commit_view_finalize (GObject *object)
|
|||
|
||||
if (view->priv->update_id)
|
||||
{
|
||||
g_signal_handler_disconnect (view->priv->runner, view->priv->update_id);
|
||||
g_signal_handler_disconnect (view->priv->shell, view->priv->update_id);
|
||||
}
|
||||
|
||||
gitg_runner_cancel (view->priv->runner);
|
||||
g_object_unref (view->priv->runner);
|
||||
gitg_io_cancel (GITG_IO (view->priv->shell));
|
||||
g_object_unref (view->priv->shell);
|
||||
g_object_unref (view->priv->ui_manager);
|
||||
|
||||
gdk_cursor_unref (view->priv->hand);
|
||||
|
@ -224,7 +225,7 @@ show_binary_information (GitgCommitView *view)
|
|||
}
|
||||
|
||||
static void
|
||||
on_changes_update (GitgRunner *runner, gchar **buffer, GitgCommitView *view)
|
||||
on_changes_update (GitgShell *shell, gchar **buffer, GitgCommitView *view)
|
||||
{
|
||||
gchar *line;
|
||||
GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view->priv->changes_view));
|
||||
|
@ -261,7 +262,7 @@ on_changes_update (GitgRunner *runner, gchar **buffer, GitgCommitView *view)
|
|||
|
||||
if (content_type && !gitg_utils_can_display_content_type (content_type))
|
||||
{
|
||||
gitg_runner_cancel (runner);
|
||||
gitg_io_cancel (GITG_IO (shell));
|
||||
show_binary_information (view);
|
||||
}
|
||||
else if (content_type)
|
||||
|
@ -283,7 +284,7 @@ on_changes_update (GitgRunner *runner, gchar **buffer, GitgCommitView *view)
|
|||
static void
|
||||
connect_update (GitgCommitView *view)
|
||||
{
|
||||
view->priv->update_id = g_signal_connect (view->priv->runner,
|
||||
view->priv->update_id = g_signal_connect (view->priv->shell,
|
||||
"update",
|
||||
G_CALLBACK (on_changes_update),
|
||||
view);
|
||||
|
@ -384,9 +385,11 @@ check_selection(GtkTreeView *tree_view,
|
|||
GitgCommitView *view)
|
||||
{
|
||||
if (view->priv->update_id)
|
||||
g_signal_handler_disconnect(view->priv->runner, view->priv->update_id);
|
||||
{
|
||||
g_signal_handler_disconnect(view->priv->shell, view->priv->update_id);
|
||||
}
|
||||
|
||||
gitg_runner_cancel(view->priv->runner);
|
||||
gitg_io_cancel(GITG_IO (view->priv->shell));
|
||||
view->priv->update_id = 0;
|
||||
|
||||
GtkTextView *tv = GTK_TEXT_VIEW(view->priv->changes_view);
|
||||
|
@ -478,7 +481,7 @@ unstaged_selection_changed (GtkTreeSelection *selection,
|
|||
view->priv->is_diff = FALSE;
|
||||
connect_update (view);
|
||||
|
||||
gitg_runner_run_stream (view->priv->runner, stream, NULL);
|
||||
gitg_shell_run_stream (view->priv->shell, stream, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
}
|
||||
|
@ -487,6 +490,8 @@ unstaged_selection_changed (GtkTreeSelection *selection,
|
|||
}
|
||||
else
|
||||
{
|
||||
gboolean allow_external;
|
||||
|
||||
set_diff_language (view);
|
||||
view->priv->is_diff = TRUE;
|
||||
connect_update (view);
|
||||
|
@ -496,15 +501,22 @@ unstaged_selection_changed (GtkTreeSelection *selection,
|
|||
gchar ct[10];
|
||||
g_snprintf (ct, sizeof(ct), "-U%d", view->priv->context_size);
|
||||
|
||||
gitg_repository_run_commandv (view->priv->repository,
|
||||
view->priv->runner,
|
||||
NULL,
|
||||
"diff",
|
||||
"--no-color",
|
||||
ct,
|
||||
"--",
|
||||
path,
|
||||
NULL);
|
||||
g_object_get (gitg_preferences_get_default (),
|
||||
"diff-external",
|
||||
&allow_external,
|
||||
NULL);
|
||||
|
||||
gitg_shell_run (view->priv->shell,
|
||||
gitg_command_newv (view->priv->repository,
|
||||
"diff",
|
||||
allow_external ? "--ext-diff" : "--no-ext-diff",
|
||||
"--no-color",
|
||||
ct,
|
||||
"--",
|
||||
path,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
|
@ -521,7 +533,9 @@ staged_selection_changed (GtkTreeSelection *selection, GitgCommitView *view)
|
|||
GtkTreeIter iter;
|
||||
|
||||
if (!check_selection (view->priv->tree_view_staged, &iter, view))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
model = gtk_tree_view_get_model (view->priv->tree_view_staged);
|
||||
unselect_tree_view (view->priv->tree_view_unstaged);
|
||||
|
@ -561,14 +575,15 @@ staged_selection_changed (GtkTreeSelection *selection, GitgCommitView *view)
|
|||
connect_update (view);
|
||||
|
||||
gchar *indexpath = g_strconcat (":0:", path, NULL);
|
||||
gitg_repository_run_commandv (view->priv->repository,
|
||||
view->priv->runner,
|
||||
NULL,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
indexpath,
|
||||
NULL);
|
||||
gitg_shell_run (view->priv->shell,
|
||||
gitg_command_newv (view->priv->repository,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
indexpath,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (indexpath);
|
||||
}
|
||||
|
||||
|
@ -576,6 +591,8 @@ staged_selection_changed (GtkTreeSelection *selection, GitgCommitView *view)
|
|||
}
|
||||
else
|
||||
{
|
||||
gboolean allow_external;
|
||||
|
||||
view->priv->is_diff = TRUE;
|
||||
set_diff_language (view);
|
||||
connect_update (view);
|
||||
|
@ -584,17 +601,24 @@ staged_selection_changed (GtkTreeSelection *selection, GitgCommitView *view)
|
|||
gchar ct[10];
|
||||
g_snprintf (ct, sizeof(ct), "-U%d", view->priv->context_size);
|
||||
|
||||
gitg_repository_run_commandv (view->priv->repository,
|
||||
view->priv->runner,
|
||||
NULL,
|
||||
"diff-index",
|
||||
ct,
|
||||
"--cached",
|
||||
"--no-color",
|
||||
head,
|
||||
"--",
|
||||
path,
|
||||
NULL);
|
||||
g_object_get (gitg_preferences_get_default (),
|
||||
"diff-external",
|
||||
&allow_external,
|
||||
NULL);
|
||||
|
||||
gitg_shell_run (view->priv->shell,
|
||||
gitg_command_newv (view->priv->repository,
|
||||
"diff-index",
|
||||
allow_external ? "--ext-diff" : "--no-ext-diff",
|
||||
ct,
|
||||
"--cached",
|
||||
"--no-color",
|
||||
head,
|
||||
"--",
|
||||
path,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free(head);
|
||||
}
|
||||
|
||||
|
@ -1659,8 +1683,8 @@ gitg_commit_view_init (GitgCommitView *self)
|
|||
{
|
||||
self->priv = GITG_COMMIT_VIEW_GET_PRIVATE (self);
|
||||
|
||||
self->priv->runner = gitg_runner_new (10000);
|
||||
gitg_runner_set_preserve_line_endings (self->priv->runner, TRUE);
|
||||
self->priv->shell = gitg_shell_new (10000);
|
||||
gitg_shell_set_preserve_line_endings (self->priv->shell, TRUE);
|
||||
|
||||
self->priv->hand = gdk_cursor_new (GDK_HAND1);
|
||||
}
|
||||
|
@ -2174,7 +2198,10 @@ do_revert_changes(GitgCommitView *view)
|
|||
|
||||
for (item = files; item; item = g_list_next (item))
|
||||
{
|
||||
ret &= gitg_commit_revert(view->priv->commit, GITG_CHANGED_FILE (item->data), NULL, NULL);
|
||||
ret &= gitg_commit_undo (view->priv->commit,
|
||||
GITG_CHANGED_FILE (item->data),
|
||||
NULL,
|
||||
NULL);
|
||||
g_object_unref (item->data);
|
||||
}
|
||||
|
||||
|
@ -2185,11 +2212,17 @@ do_revert_changes(GitgCommitView *view)
|
|||
GitgChangedFile *file = g_object_ref(view->priv->current_file);
|
||||
|
||||
gchar *hunk = get_hunk_patch(view, &view->priv->context_iter);
|
||||
ret = gitg_commit_revert(view->priv->commit, view->priv->current_file, hunk, NULL);
|
||||
ret = gitg_commit_undo (view->priv->commit,
|
||||
view->priv->current_file,
|
||||
hunk,
|
||||
NULL);
|
||||
g_free(hunk);
|
||||
|
||||
if (ret && view->priv->current_file == file)
|
||||
gitg_diff_view_remove_hunk(GITG_DIFF_VIEW(view->priv->changes_view), &view->priv->context_iter);
|
||||
{
|
||||
gitg_diff_view_remove_hunk (GITG_DIFF_VIEW(view->priv->changes_view),
|
||||
&view->priv->context_iter);
|
||||
}
|
||||
|
||||
g_object_unref(file);
|
||||
}
|
||||
|
|
|
@ -777,13 +777,14 @@ revision_to_text (GitgRepository *repository,
|
|||
gchar **lines;
|
||||
gchar *sha1 = gitg_revision_get_sha1 (revision);
|
||||
|
||||
lines = gitg_repository_command_with_outputv (repository,
|
||||
NULL,
|
||||
"log",
|
||||
"-1",
|
||||
"--pretty=format:%h: %s%n%n%b",
|
||||
sha1,
|
||||
NULL);
|
||||
lines = gitg_shell_run_sync_with_output (gitg_command_newv (repository,
|
||||
"log",
|
||||
"-1",
|
||||
"--pretty=format:%h: %s%n%n%b",
|
||||
sha1,
|
||||
NULL),
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
remove_trailing_newlines (lines);
|
||||
gchar *ret = g_strjoinv ("\n", lines);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <libgitg/gitg-config.h>
|
||||
#include <libgitg/gitg-shell.h>
|
||||
|
||||
#include "gitg-repository-dialog.h"
|
||||
#include "gitg-utils.h"
|
||||
|
@ -100,7 +101,7 @@ G_DEFINE_TYPE (GitgRepositoryDialog, gitg_repository_dialog, GTK_TYPE_DIALOG)
|
|||
typedef struct
|
||||
{
|
||||
GitgRepositoryDialog *dialog;
|
||||
GitgRunner *runner;
|
||||
GitgShell *shell;
|
||||
GtkTreeRowReference *reference;
|
||||
|
||||
#ifdef BUILD_SPINNER
|
||||
|
@ -149,7 +150,7 @@ fetch_cleanup (FetchInfo *info)
|
|||
#endif
|
||||
|
||||
gtk_tree_row_reference_free (info->reference);
|
||||
g_object_unref (info->runner);
|
||||
g_object_unref (info->shell);
|
||||
|
||||
g_slice_free (FetchInfo, info);
|
||||
}
|
||||
|
@ -174,7 +175,7 @@ gitg_repository_dialog_finalize (GObject *object)
|
|||
|
||||
for (item = copy; item; item = g_list_next (item))
|
||||
{
|
||||
gitg_runner_cancel (((FetchInfo *)item->data)->runner);
|
||||
gitg_io_cancel (GITG_IO (((FetchInfo *)item->data)->shell));
|
||||
}
|
||||
|
||||
g_list_free (copy);
|
||||
|
@ -341,7 +342,7 @@ pulse_row (FetchInfo *info)
|
|||
#endif
|
||||
|
||||
static void
|
||||
on_fetch_begin_loading (GitgRunner *runner, FetchInfo *info)
|
||||
on_fetch_begin_loading (GitgShell *shell, FetchInfo *info)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path = gtk_tree_row_reference_get_path (info->reference);
|
||||
|
@ -387,7 +388,7 @@ on_fetch_begin_loading (GitgRunner *runner, FetchInfo *info)
|
|||
}
|
||||
|
||||
static void
|
||||
on_fetch_end_loading (GitgRunner *runner, gboolean cancelled, FetchInfo *info)
|
||||
on_fetch_end_loading (GitgShell *shell, gboolean cancelled, FetchInfo *info)
|
||||
{
|
||||
if (cancelled || !gtk_tree_row_reference_valid (info->reference))
|
||||
{
|
||||
|
@ -406,7 +407,7 @@ on_fetch_end_loading (GitgRunner *runner, gboolean cancelled, FetchInfo *info)
|
|||
static void
|
||||
fetch_remote (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
|
||||
{
|
||||
GitgRunner *runner = gitg_runner_new (1000);
|
||||
GitgShell *shell = gitg_shell_new (1000);
|
||||
FetchInfo *info = g_slice_new0 (FetchInfo);
|
||||
GtkTreeModel *model = GTK_TREE_MODEL (dialog->priv->list_store_remotes);
|
||||
|
||||
|
@ -414,17 +415,17 @@ fetch_remote (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
|
|||
|
||||
info->dialog = dialog;
|
||||
info->reference = gtk_tree_row_reference_new (model, path);
|
||||
info->runner = runner;
|
||||
info->shell = shell;
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
g_signal_connect (runner,
|
||||
"begin-loading",
|
||||
g_signal_connect (shell,
|
||||
"begin",
|
||||
G_CALLBACK (on_fetch_begin_loading),
|
||||
info);
|
||||
|
||||
g_signal_connect (runner,
|
||||
"end-loading",
|
||||
g_signal_connect (shell,
|
||||
"end",
|
||||
G_CALLBACK (on_fetch_end_loading),
|
||||
info);
|
||||
|
||||
|
@ -433,12 +434,12 @@ fetch_remote (GitgRepositoryDialog *dialog, GtkTreeIter *iter)
|
|||
gchar *name;
|
||||
gtk_tree_model_get (model, iter, COLUMN_NAME, &name, -1);
|
||||
|
||||
gitg_repository_run_commandv (dialog->priv->repository,
|
||||
runner,
|
||||
NULL,
|
||||
"fetch",
|
||||
name,
|
||||
NULL);
|
||||
gitg_shell_run (shell,
|
||||
gitg_command_newv (dialog->priv->repository,
|
||||
"fetch",
|
||||
name,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
@ -684,7 +685,7 @@ fetch_remote_cancel (GitgRepositoryDialog *dialog,
|
|||
|
||||
if (equal)
|
||||
{
|
||||
gitg_runner_cancel (info->runner);
|
||||
gitg_io_cancel (GITG_IO (info->shell));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -736,12 +737,12 @@ on_button_fetch_remote_clicked (GtkButton *button,
|
|||
static gboolean
|
||||
remove_remote (GitgRepositoryDialog *dialog, gchar const *name)
|
||||
{
|
||||
return gitg_repository_commandv (dialog->priv->repository,
|
||||
NULL,
|
||||
"remote",
|
||||
"rm",
|
||||
name,
|
||||
NULL);
|
||||
return gitg_shell_run_sync (gitg_command_newv (dialog->priv->repository,
|
||||
"remote",
|
||||
"rm",
|
||||
name,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -828,7 +829,13 @@ on_button_add_remote_clicked (GtkButton *button,
|
|||
gchar *name = g_strdup_printf ("remote%d", num + 1);
|
||||
gchar const url[] = "git://example.com/repository.git";
|
||||
|
||||
if (gitg_repository_commandv (dialog->priv->repository, NULL, "remote", "add", name, url, NULL))
|
||||
if (gitg_shell_run_sync (gitg_command_newv (dialog->priv->repository,
|
||||
"remote",
|
||||
"add",
|
||||
name,
|
||||
url,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
|
@ -901,7 +908,13 @@ on_remote_name_edited (GtkCellRendererText *renderer,
|
|||
COLUMN_URL, &url,
|
||||
-1);
|
||||
|
||||
if (gitg_repository_commandv (dialog->priv->repository, NULL, "remote", "add", new_text, url, NULL))
|
||||
if (gitg_shell_run_sync (gitg_command_newv (dialog->priv->repository,
|
||||
"remote",
|
||||
"add",
|
||||
new_text,
|
||||
url,
|
||||
NULL),
|
||||
NULL))
|
||||
{
|
||||
remove_remote (dialog, oldname);
|
||||
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
#include <string.h>
|
||||
#include <libgitg/gitg-repository.h>
|
||||
#include <libgitg/gitg-revision.h>
|
||||
#include <libgitg/gitg-runner.h>
|
||||
#include <libgitg/gitg-shell.h>
|
||||
#include <libgitg/gitg-hash.h>
|
||||
#include "gitg-diff-view.h"
|
||||
#include "gitg-utils.h"
|
||||
#include "gitg-preferences.h"
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
|
||||
#include "gitg-revision-panel.h"
|
||||
#include "gitg-activatable.h"
|
||||
|
||||
|
@ -26,8 +28,8 @@ struct _GitgRevisionChangesPanelPrivate
|
|||
GtkTreeView *diff_files;
|
||||
GtkListStore *list_store_diff_files;
|
||||
|
||||
GitgRunner *diff_runner;
|
||||
GitgRunner *diff_files_runner;
|
||||
GitgShell *diff_shell;
|
||||
GitgShell *diff_files_shell;
|
||||
|
||||
GitgRepository *repository;
|
||||
GitgRevision *revision;
|
||||
|
@ -520,16 +522,16 @@ gitg_revision_changes_panel_dispose (GObject *object)
|
|||
|
||||
set_revision (changes_panel, NULL, NULL);
|
||||
|
||||
if (changes_panel->priv->diff_files_runner)
|
||||
if (changes_panel->priv->diff_files_shell)
|
||||
{
|
||||
g_object_unref (changes_panel->priv->diff_files_runner);
|
||||
changes_panel->priv->diff_files_runner = NULL;
|
||||
g_object_unref (changes_panel->priv->diff_files_shell);
|
||||
changes_panel->priv->diff_files_shell = NULL;
|
||||
}
|
||||
|
||||
if (changes_panel->priv->diff_files_runner)
|
||||
if (changes_panel->priv->diff_files_shell)
|
||||
{
|
||||
g_object_unref (changes_panel->priv->diff_runner);
|
||||
changes_panel->priv->diff_runner = NULL;
|
||||
g_object_unref (changes_panel->priv->diff_shell);
|
||||
changes_panel->priv->diff_shell = NULL;
|
||||
}
|
||||
|
||||
if (changes_panel->priv->builder)
|
||||
|
@ -564,8 +566,8 @@ reload_diff (GitgRevisionChangesPanel *changes_panel)
|
|||
GtkTreeSelection *selection;
|
||||
|
||||
// First cancel a possibly still running diff
|
||||
gitg_runner_cancel (changes_panel->priv->diff_runner);
|
||||
gitg_runner_cancel (changes_panel->priv->diff_files_runner);
|
||||
gitg_io_cancel (GITG_IO (changes_panel->priv->diff_shell));
|
||||
gitg_io_cancel (GITG_IO (changes_panel->priv->diff_files_shell));
|
||||
|
||||
free_cached_headers (changes_panel);
|
||||
|
||||
|
@ -592,45 +594,54 @@ reload_diff (GitgRevisionChangesPanel *changes_panel)
|
|||
}
|
||||
|
||||
gchar sign = gitg_revision_get_sign (changes_panel->priv->revision);
|
||||
gboolean allow_external;
|
||||
|
||||
g_object_get (gitg_preferences_get_default (),
|
||||
"diff-external",
|
||||
&allow_external,
|
||||
NULL);
|
||||
|
||||
switch (sign)
|
||||
{
|
||||
case 't':
|
||||
gitg_repository_run_commandv (changes_panel->priv->repository,
|
||||
changes_panel->priv->diff_runner,
|
||||
NULL,
|
||||
"diff",
|
||||
"--cached",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
NULL);
|
||||
gitg_shell_run (changes_panel->priv->diff_shell,
|
||||
gitg_command_newv (changes_panel->priv->repository,
|
||||
"diff",
|
||||
allow_external ? "--ext-diff" : "--no-ext-diff",
|
||||
"--cached",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
NULL),
|
||||
NULL);
|
||||
break;
|
||||
case 'u':
|
||||
gitg_repository_run_commandv (changes_panel->priv->repository,
|
||||
changes_panel->priv->diff_runner,
|
||||
NULL,
|
||||
"diff",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
NULL);
|
||||
gitg_shell_run (changes_panel->priv->diff_shell,
|
||||
gitg_command_newv (changes_panel->priv->repository,
|
||||
"diff",
|
||||
allow_external ? "--ext-diff" : "--no-ext-diff",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
NULL),
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
gchar *hash = gitg_revision_get_sha1 (changes_panel->priv->revision);
|
||||
gitg_repository_run_commandv (changes_panel->priv->repository,
|
||||
changes_panel->priv->diff_runner,
|
||||
NULL,
|
||||
"show",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
hash,
|
||||
NULL);
|
||||
|
||||
gitg_shell_run (changes_panel->priv->diff_shell,
|
||||
gitg_command_newv (changes_panel->priv->repository,
|
||||
"show",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--encoding=UTF-8",
|
||||
"--no-color",
|
||||
hash,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (hash);
|
||||
}
|
||||
|
@ -649,14 +660,14 @@ set_revision (GitgRevisionChangesPanel *changes_panel,
|
|||
return;
|
||||
}
|
||||
|
||||
if (changes_panel->priv->diff_runner)
|
||||
if (changes_panel->priv->diff_shell)
|
||||
{
|
||||
gitg_runner_cancel (changes_panel->priv->diff_runner);
|
||||
gitg_io_cancel (GITG_IO (changes_panel->priv->diff_shell));
|
||||
}
|
||||
|
||||
if (changes_panel->priv->diff_files_runner)
|
||||
if (changes_panel->priv->diff_files_shell)
|
||||
{
|
||||
gitg_runner_cancel (changes_panel->priv->diff_files_runner);
|
||||
gitg_io_cancel (GITG_IO (changes_panel->priv->diff_files_shell));
|
||||
}
|
||||
|
||||
if (changes_panel->priv->repository)
|
||||
|
@ -691,7 +702,7 @@ set_revision (GitgRevisionChangesPanel *changes_panel,
|
|||
}
|
||||
|
||||
static void
|
||||
on_diff_files_begin_loading (GitgRunner *runner,
|
||||
on_diff_files_begin_loading (GitgShell *shell,
|
||||
GitgRevisionChangesPanel *self)
|
||||
{
|
||||
GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
|
||||
|
@ -703,7 +714,7 @@ on_diff_files_begin_loading (GitgRunner *runner,
|
|||
}
|
||||
|
||||
static void
|
||||
on_diff_files_end_loading (GitgRunner *runner,
|
||||
on_diff_files_end_loading (GitgShell *shell,
|
||||
gboolean cancelled,
|
||||
GitgRevisionChangesPanel *self)
|
||||
{
|
||||
|
@ -766,7 +777,7 @@ add_diff_file (GitgRevisionChangesPanel *view,
|
|||
}
|
||||
|
||||
static void
|
||||
on_diff_files_update (GitgRunner *runner,
|
||||
on_diff_files_update (GitgShell *shell,
|
||||
gchar **buffer,
|
||||
GitgRevisionChangesPanel *self)
|
||||
{
|
||||
|
@ -808,7 +819,7 @@ on_diff_files_update (GitgRunner *runner,
|
|||
}
|
||||
|
||||
static void
|
||||
on_diff_begin_loading (GitgRunner *runner,
|
||||
on_diff_begin_loading (GitgShell *shell,
|
||||
GitgRevisionChangesPanel *self)
|
||||
{
|
||||
GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
|
||||
|
@ -818,7 +829,7 @@ on_diff_begin_loading (GitgRunner *runner,
|
|||
}
|
||||
|
||||
static void
|
||||
on_diff_end_loading (GitgRunner *runner,
|
||||
on_diff_end_loading (GitgShell *shell,
|
||||
gboolean cancelled,
|
||||
GitgRevisionChangesPanel *self)
|
||||
{
|
||||
|
@ -831,6 +842,12 @@ on_diff_end_loading (GitgRunner *runner,
|
|||
}
|
||||
|
||||
gchar sign = gitg_revision_get_sign (self->priv->revision);
|
||||
gboolean allow_external;
|
||||
|
||||
g_object_get (gitg_preferences_get_default (),
|
||||
"diff-external",
|
||||
&allow_external,
|
||||
NULL);
|
||||
|
||||
if (sign == 't' || sign == 'u')
|
||||
{
|
||||
|
@ -840,38 +857,39 @@ on_diff_end_loading (GitgRunner *runner,
|
|||
if (sign == 't')
|
||||
cached = "--cached";
|
||||
|
||||
gitg_repository_run_commandv (self->priv->repository,
|
||||
self->priv->diff_files_runner,
|
||||
NULL,
|
||||
"diff-index",
|
||||
"--raw",
|
||||
"-M",
|
||||
"--abbrev=40",
|
||||
head,
|
||||
cached,
|
||||
NULL);
|
||||
gitg_shell_run (self->priv->diff_files_shell,
|
||||
gitg_command_newv (self->priv->repository,
|
||||
"diff-index",
|
||||
allow_external ? "--ext-diff" : "--no-ext-diff",
|
||||
"--raw",
|
||||
"-M",
|
||||
"--abbrev=40",
|
||||
head,
|
||||
cached,
|
||||
NULL),
|
||||
NULL);
|
||||
g_free (head);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *sha = gitg_revision_get_sha1 (self->priv->revision);
|
||||
gitg_repository_run_commandv (self->priv->repository,
|
||||
self->priv->diff_files_runner,
|
||||
NULL,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
"--raw",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--abbrev=40",
|
||||
sha,
|
||||
NULL);
|
||||
gitg_shell_run (self->priv->diff_files_shell,
|
||||
gitg_command_newv (self->priv->repository,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
"--raw",
|
||||
"-M",
|
||||
"--pretty=format:",
|
||||
"--abbrev=40",
|
||||
sha,
|
||||
NULL),
|
||||
NULL);
|
||||
g_free (sha);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_diff_update (GitgRunner *runner,
|
||||
on_diff_update (GitgShell *shell,
|
||||
gchar **buffer,
|
||||
GitgRevisionChangesPanel *self)
|
||||
{
|
||||
|
@ -893,37 +911,37 @@ gitg_revision_changes_panel_init (GitgRevisionChangesPanel *self)
|
|||
{
|
||||
self->priv = GITG_REVISION_CHANGES_PANEL_GET_PRIVATE (self);
|
||||
|
||||
self->priv->diff_runner = gitg_runner_new (2000);
|
||||
self->priv->diff_shell = gitg_shell_new (2000);
|
||||
|
||||
g_signal_connect (self->priv->diff_runner,
|
||||
"begin-loading",
|
||||
g_signal_connect (self->priv->diff_shell,
|
||||
"begin",
|
||||
G_CALLBACK (on_diff_begin_loading),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->diff_runner,
|
||||
g_signal_connect (self->priv->diff_shell,
|
||||
"update",
|
||||
G_CALLBACK (on_diff_update),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->diff_runner,
|
||||
"end-loading",
|
||||
g_signal_connect (self->priv->diff_shell,
|
||||
"end",
|
||||
G_CALLBACK (on_diff_end_loading),
|
||||
self);
|
||||
|
||||
self->priv->diff_files_runner = gitg_runner_new (2000);
|
||||
self->priv->diff_files_shell = gitg_shell_new (2000);
|
||||
|
||||
g_signal_connect (self->priv->diff_files_runner,
|
||||
"begin-loading",
|
||||
g_signal_connect (self->priv->diff_files_shell,
|
||||
"begin",
|
||||
G_CALLBACK(on_diff_files_begin_loading),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->diff_files_runner,
|
||||
g_signal_connect (self->priv->diff_files_shell,
|
||||
"update",
|
||||
G_CALLBACK(on_diff_files_update),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->diff_files_runner,
|
||||
"end-loading",
|
||||
g_signal_connect (self->priv->diff_files_shell,
|
||||
"end",
|
||||
G_CALLBACK(on_diff_files_end_loading),
|
||||
self);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ struct _GitgRevisionDetailsPanelPrivate
|
|||
GitgRepository *repository;
|
||||
GitgRevision *revision;
|
||||
|
||||
GitgRunner *runner;
|
||||
GitgShell *shell;
|
||||
gboolean in_stat;
|
||||
|
||||
GSList *stats;
|
||||
|
@ -202,12 +202,12 @@ gitg_revision_details_panel_dispose (GObject *object)
|
|||
panel->priv->builder = NULL;
|
||||
}
|
||||
|
||||
if (panel->priv->runner)
|
||||
if (panel->priv->shell)
|
||||
{
|
||||
gitg_runner_cancel (panel->priv->runner);
|
||||
g_object_unref (panel->priv->runner);
|
||||
gitg_io_cancel (GITG_IO (panel->priv->shell));
|
||||
g_object_unref (panel->priv->shell);
|
||||
|
||||
panel->priv->runner = NULL;
|
||||
panel->priv->shell = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gitg_revision_details_panel_parent_class)->dispose (object);
|
||||
|
@ -224,8 +224,8 @@ gitg_revision_details_panel_class_init (GitgRevisionDetailsPanelClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
on_runner_begin (GitgRunner *runner,
|
||||
GitgRevisionDetailsPanel *panel)
|
||||
on_shell_begin (GitgShell *shell,
|
||||
GitgRevisionDetailsPanel *panel)
|
||||
{
|
||||
GdkCursor *cursor;
|
||||
|
||||
|
@ -363,9 +363,9 @@ make_stats_table (GitgRevisionDetailsPanel *panel)
|
|||
}
|
||||
|
||||
static void
|
||||
on_runner_end (GitgRunner *runner,
|
||||
gboolean cancelled,
|
||||
GitgRevisionDetailsPanel *panel)
|
||||
on_shell_end (GitgShell *shell,
|
||||
gboolean cancelled,
|
||||
GitgRevisionDetailsPanel *panel)
|
||||
{
|
||||
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (panel->priv->text_view)),
|
||||
NULL);
|
||||
|
@ -432,9 +432,9 @@ add_stat (GitgRevisionDetailsPanel *panel,
|
|||
}
|
||||
|
||||
static void
|
||||
on_runner_update (GitgRunner *runner,
|
||||
gchar **lines,
|
||||
GitgRevisionDetailsPanel *panel)
|
||||
on_shell_update (GitgShell *shell,
|
||||
gchar **lines,
|
||||
GitgRevisionDetailsPanel *panel)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter end;
|
||||
|
@ -476,21 +476,21 @@ gitg_revision_details_panel_init (GitgRevisionDetailsPanel *self)
|
|||
{
|
||||
self->priv = GITG_REVISION_DETAILS_PANEL_GET_PRIVATE(self);
|
||||
|
||||
self->priv->runner = gitg_runner_new (1000);
|
||||
self->priv->shell = gitg_shell_new (1000);
|
||||
|
||||
g_signal_connect (self->priv->runner,
|
||||
"begin-loading",
|
||||
G_CALLBACK (on_runner_begin),
|
||||
g_signal_connect (self->priv->shell,
|
||||
"begin",
|
||||
G_CALLBACK (on_shell_begin),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->runner,
|
||||
"end-loading",
|
||||
G_CALLBACK (on_runner_end),
|
||||
g_signal_connect (self->priv->shell,
|
||||
"end",
|
||||
G_CALLBACK (on_shell_end),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->runner,
|
||||
g_signal_connect (self->priv->shell,
|
||||
"update",
|
||||
G_CALLBACK (on_runner_update),
|
||||
G_CALLBACK (on_shell_update),
|
||||
self);
|
||||
}
|
||||
|
||||
|
@ -644,7 +644,7 @@ update_details (GitgRevisionDetailsPanel *panel)
|
|||
{
|
||||
gchar *sha1;
|
||||
|
||||
gitg_runner_cancel (panel->priv->runner);
|
||||
gitg_io_cancel (GITG_IO (panel->priv->shell));
|
||||
|
||||
gtk_text_buffer_set_text (gtk_text_view_get_buffer (panel->priv->text_view),
|
||||
"",
|
||||
|
@ -657,14 +657,14 @@ update_details (GitgRevisionDetailsPanel *panel)
|
|||
|
||||
sha1 = gitg_revision_get_sha1 (panel->priv->revision);
|
||||
|
||||
gitg_repository_run_commandv (panel->priv->repository,
|
||||
panel->priv->runner,
|
||||
NULL,
|
||||
"show",
|
||||
"--numstat",
|
||||
"--pretty=format:%s%n%n%b%n\x01",
|
||||
sha1,
|
||||
NULL);
|
||||
gitg_shell_run (panel->priv->shell,
|
||||
gitg_command_newv (panel->priv->repository,
|
||||
"show",
|
||||
"--numstat",
|
||||
"--pretty=format:%s%n%n%b%n\x01",
|
||||
sha1,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (sha1);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <gio/gio.h>
|
||||
#include <stdlib.h>
|
||||
#include <libgitg/gitg-revision.h>
|
||||
#include <libgitg/gitg-runner.h>
|
||||
#include <libgitg/gitg-shell.h>
|
||||
|
||||
#include "gitg-revision-files-panel.h"
|
||||
#include "gitg-utils.h"
|
||||
|
@ -54,7 +54,7 @@ struct _GitgRevisionFilesViewPrivate
|
|||
{
|
||||
GtkTreeView *tree_view;
|
||||
GtkSourceView *contents;
|
||||
GitgRunner *content_runner;
|
||||
GitgShell *content_shell;
|
||||
GtkTreeStore *store;
|
||||
|
||||
gchar *drag_dir;
|
||||
|
@ -62,7 +62,7 @@ struct _GitgRevisionFilesViewPrivate
|
|||
|
||||
GitgRepository *repository;
|
||||
GitgRevision *revision;
|
||||
GitgRunner *loader;
|
||||
GitgShell *loader;
|
||||
GtkTreePath *load_path;
|
||||
|
||||
gboolean skipped_blank_line;
|
||||
|
@ -127,7 +127,7 @@ gitg_revision_files_view_finalize (GObject *object)
|
|||
g_strfreev (self->priv->drag_files);
|
||||
}
|
||||
|
||||
gitg_runner_cancel (self->priv->loader);
|
||||
gitg_io_cancel (GITG_IO (self->priv->loader));
|
||||
g_object_unref (self->priv->loader);
|
||||
|
||||
G_OBJECT_CLASS (gitg_revision_files_view_parent_class)->finalize (object);
|
||||
|
@ -150,7 +150,7 @@ set_revision (GitgRevisionFilesView *files_view,
|
|||
return;
|
||||
}
|
||||
|
||||
gitg_runner_cancel (files_view->priv->loader);
|
||||
gitg_io_cancel (GITG_IO (files_view->priv->loader));
|
||||
gtk_tree_store_clear (files_view->priv->store);
|
||||
|
||||
if (files_view->priv->repository)
|
||||
|
@ -270,7 +270,7 @@ on_selection_changed (GtkTreeSelection *selection,
|
|||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
gitg_runner_cancel (tree->priv->content_runner);
|
||||
gitg_io_cancel (GITG_IO (tree->priv->content_shell));
|
||||
|
||||
gtk_text_buffer_set_text (buffer, "", -1);
|
||||
|
||||
|
@ -326,13 +326,13 @@ on_selection_changed (GtkTreeSelection *selection,
|
|||
|
||||
gchar *id = node_identity (tree, &iter);
|
||||
|
||||
gitg_repository_run_commandv (tree->priv->repository,
|
||||
tree->priv->content_runner,
|
||||
NULL,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
id,
|
||||
NULL);
|
||||
gitg_shell_run (tree->priv->content_shell,
|
||||
gitg_command_newv (tree->priv->repository,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
id,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (id);
|
||||
}
|
||||
|
@ -857,8 +857,8 @@ append_node (GitgRevisionFilesView *tree,
|
|||
}
|
||||
|
||||
static void
|
||||
on_update (GitgRunner *runner,
|
||||
gchar **buffer,
|
||||
on_update (GitgShell *shell,
|
||||
gchar **buffer,
|
||||
GitgRevisionFilesView *tree)
|
||||
{
|
||||
gchar *line;
|
||||
|
@ -919,9 +919,9 @@ compare_func (GtkTreeModel *model,
|
|||
}
|
||||
|
||||
static void
|
||||
on_contents_update (GitgRunner *runner,
|
||||
gchar **buffer,
|
||||
GitgRevisionFilesView *tree)
|
||||
on_contents_update (GitgShell *shell,
|
||||
gchar **buffer,
|
||||
GitgRevisionFilesView *tree)
|
||||
{
|
||||
gchar *line;
|
||||
GtkTextBuffer *buf;
|
||||
|
@ -943,7 +943,7 @@ on_contents_update (GitgRunner *runner,
|
|||
|
||||
if (content_type && !gitg_utils_can_display_content_type (content_type))
|
||||
{
|
||||
gitg_runner_cancel (runner);
|
||||
gitg_io_cancel (GITG_IO (shell));
|
||||
show_binary_information (tree);
|
||||
}
|
||||
else
|
||||
|
@ -978,14 +978,14 @@ gitg_revision_files_view_init (GitgRevisionFilesView *self)
|
|||
NAME_COLUMN,
|
||||
GTK_SORT_ASCENDING);
|
||||
|
||||
self->priv->loader = gitg_runner_new (1000);
|
||||
self->priv->loader = gitg_shell_new (1000);
|
||||
g_signal_connect (self->priv->loader,
|
||||
"update",
|
||||
G_CALLBACK (on_update),
|
||||
self);
|
||||
|
||||
self->priv->content_runner = gitg_runner_new (5000);
|
||||
g_signal_connect (self->priv->content_runner,
|
||||
self->priv->content_shell = gitg_shell_new (5000);
|
||||
g_signal_connect (self->priv->content_shell,
|
||||
"update",
|
||||
G_CALLBACK (on_contents_update),
|
||||
self);
|
||||
|
@ -1017,7 +1017,7 @@ static void
|
|||
load_node (GitgRevisionFilesView *tree,
|
||||
GtkTreeIter *parent)
|
||||
{
|
||||
if (gitg_runner_running (tree->priv->loader))
|
||||
if (gitg_io_get_running (GITG_IO (tree->priv->loader)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1041,12 +1041,12 @@ load_node (GitgRevisionFilesView *tree,
|
|||
}
|
||||
|
||||
tree->priv->skipped_blank_line = FALSE;
|
||||
gitg_repository_run_commandv (tree->priv->repository,
|
||||
tree->priv->loader,
|
||||
NULL,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
id,
|
||||
NULL);
|
||||
gitg_shell_run (tree->priv->loader,
|
||||
gitg_command_newv (tree->priv->repository,
|
||||
"show",
|
||||
"--encoding=UTF-8",
|
||||
id,
|
||||
NULL),
|
||||
NULL);
|
||||
g_free (id);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <glib/gi18n.h>
|
||||
#include <libgitg/gitg-config.h>
|
||||
#include <libgitg/gitg-ref.h>
|
||||
#include <libgitg/gitg-runner.h>
|
||||
#include <libgitg/gitg-hash.h>
|
||||
|
||||
#include "config.h"
|
||||
|
@ -158,31 +157,31 @@ static GtkBuildableIface parent_iface;
|
|||
static GtkWindowClass *parent_class = NULL;
|
||||
|
||||
static void
|
||||
on_branch_action_runner_end (GitgRunner *runner,
|
||||
gboolean cancelled,
|
||||
GitgWindow *window)
|
||||
on_branch_action_shell_end (GitgShell *shell,
|
||||
gboolean cancelled,
|
||||
GitgWindow *window)
|
||||
{
|
||||
window->priv->branch_actions = g_list_remove (window->priv->branch_actions, runner);
|
||||
g_object_unref (runner);
|
||||
window->priv->branch_actions = g_list_remove (window->priv->branch_actions, shell);
|
||||
g_object_unref (shell);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_window_add_branch_action (GitgWindow *window,
|
||||
GitgRunner *runner)
|
||||
GitgShell *shell)
|
||||
{
|
||||
if (runner != NULL && gitg_runner_running (runner))
|
||||
if (shell != NULL && gitg_io_get_running (GITG_IO (shell)))
|
||||
{
|
||||
window->priv->branch_actions = g_list_prepend (window->priv->branch_actions, runner);
|
||||
window->priv->branch_actions = g_list_prepend (window->priv->branch_actions, shell);
|
||||
|
||||
g_signal_connect (runner, "end-loading", G_CALLBACK (on_branch_action_runner_end), window);
|
||||
g_signal_connect (shell, "end", G_CALLBACK (on_branch_action_shell_end), window);
|
||||
}
|
||||
else if (runner)
|
||||
else if (shell)
|
||||
{
|
||||
g_object_unref (runner);
|
||||
runner = NULL;
|
||||
g_object_unref (shell);
|
||||
shell = NULL;
|
||||
}
|
||||
|
||||
return runner != NULL;
|
||||
return shell != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -198,7 +197,7 @@ gitg_window_finalize (GObject *object)
|
|||
|
||||
for (item = copy; item; item = g_list_next (item))
|
||||
{
|
||||
gitg_runner_cancel (GITG_RUNNER (item->data));
|
||||
gitg_io_cancel (item->data);
|
||||
}
|
||||
|
||||
g_list_free (copy);
|
||||
|
@ -1217,7 +1216,7 @@ on_repository_loaded (GitgRepository *repository,
|
|||
}
|
||||
|
||||
static void
|
||||
on_update (GitgRunner *loader,
|
||||
on_update (GitgShell *loader,
|
||||
gchar **revisions,
|
||||
GitgWindow *window)
|
||||
{
|
||||
|
@ -1782,7 +1781,7 @@ load_repository (GitgWindow *window,
|
|||
gtk_tree_view_set_model (window->priv->tree_view,
|
||||
GTK_TREE_MODEL (window->priv->repository));
|
||||
|
||||
GitgRunner *loader = gitg_repository_get_loader (window->priv->repository);
|
||||
GitgShell *loader = gitg_repository_get_loader (window->priv->repository);
|
||||
|
||||
gitg_window_set_select_on_load (window, selection);
|
||||
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
#include <gtk/gtk.h>
|
||||
#include <libgitg/gitg-repository.h>
|
||||
#include <libgitg/gitg-shell.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_WINDOW (gitg_window_get_type ())
|
||||
#define GITG_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_WINDOW, GitgWindow))
|
||||
#define GITG_TYPE_WINDOW (gitg_window_get_type ())
|
||||
#define GITG_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_WINDOW, GitgWindow))
|
||||
#define GITG_WINDOW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_WINDOW, GitgWindow const))
|
||||
#define GITG_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_WINDOW, GitgWindowClass))
|
||||
#define GITG_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_WINDOW))
|
||||
#define GITG_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_WINDOW))
|
||||
#define GITG_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_WINDOW))
|
||||
#define GITG_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_WINDOW, GitgWindowClass))
|
||||
|
||||
|
@ -40,13 +41,15 @@ typedef struct _GitgWindow GitgWindow;
|
|||
typedef struct _GitgWindowClass GitgWindowClass;
|
||||
typedef struct _GitgWindowPrivate GitgWindowPrivate;
|
||||
|
||||
struct _GitgWindow {
|
||||
struct _GitgWindow
|
||||
{
|
||||
GtkWindow parent;
|
||||
|
||||
GitgWindowPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GitgWindowClass {
|
||||
struct _GitgWindowClass
|
||||
{
|
||||
GtkWindowClass parent_class;
|
||||
};
|
||||
|
||||
|
@ -71,10 +74,10 @@ gboolean gitg_window_load_repository_from_environment (GitgWindow *window,
|
|||
|
||||
void gitg_window_show_commit (GitgWindow *window);
|
||||
|
||||
GitgRepository *gitg_window_get_repository(GitgWindow *window);
|
||||
GitgRepository *gitg_window_get_repository (GitgWindow *window);
|
||||
void gitg_window_set_select_on_load (GitgWindow *window, gchar const *selection);
|
||||
|
||||
gboolean gitg_window_add_branch_action (GitgWindow *window, GitgRunner *runner);
|
||||
gboolean gitg_window_add_branch_action (GitgWindow *window, GitgShell *shell);
|
||||
|
||||
gboolean gitg_window_select (GitgWindow *window, gchar const *selection);
|
||||
gboolean gitg_window_activate (GitgWindow *window, gchar const *activatable, gchar const *action);
|
||||
|
|
|
@ -30,7 +30,11 @@ INST_H_FILES = \
|
|||
gitg-ref.h \
|
||||
gitg-repository.h \
|
||||
gitg-revision.h \
|
||||
gitg-runner.h
|
||||
gitg-runner.h \
|
||||
gitg-command.h \
|
||||
gitg-shell.h \
|
||||
gitg-io.h \
|
||||
gitg-line-parser.h
|
||||
|
||||
NOINST_H_FILES = \
|
||||
gitg-convert.h \
|
||||
|
@ -57,7 +61,11 @@ C_FILES = \
|
|||
gitg-revision.c \
|
||||
gitg-runner.c \
|
||||
gitg-smart-charset-converter.c \
|
||||
gitg-encodings.c
|
||||
gitg-encodings.c \
|
||||
gitg-command.c \
|
||||
gitg-io.c \
|
||||
gitg-shell.c \
|
||||
gitg-line-parser.c
|
||||
|
||||
ENUM_H_FILES = \
|
||||
gitg-changed-file.h
|
||||
|
|
491
libgitg/gitg-command.c
Normal file
491
libgitg/gitg-command.c
Normal file
|
@ -0,0 +1,491 @@
|
|||
#include "gitg-command.h"
|
||||
|
||||
#define GITG_COMMAND_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_COMMAND, GitgCommandPrivate))
|
||||
|
||||
#define CONST_CONST(x) ((gchar const * const *)x)
|
||||
|
||||
struct _GitgCommandPrivate
|
||||
{
|
||||
GitgRepository *repository;
|
||||
gchar **arguments;
|
||||
gchar **environment;
|
||||
GFile *working_directory;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GitgCommand, gitg_command, G_TYPE_INITIALLY_UNOWNED)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_REPOSITORY,
|
||||
PROP_ARGUMENTS,
|
||||
PROP_ENVIRONMENT,
|
||||
PROP_WORKING_DIRECTORY
|
||||
};
|
||||
|
||||
static void
|
||||
gitg_command_finalize (GObject *object)
|
||||
{
|
||||
GitgCommand *command;
|
||||
|
||||
command = GITG_COMMAND (object);
|
||||
|
||||
g_strfreev (command->priv->arguments);
|
||||
g_strfreev (command->priv->environment);
|
||||
|
||||
G_OBJECT_CLASS (gitg_command_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_command_dispose (GObject *object)
|
||||
{
|
||||
GitgCommand *command;
|
||||
|
||||
command = GITG_COMMAND (object);
|
||||
|
||||
if (command->priv->repository != NULL)
|
||||
{
|
||||
g_object_unref (command->priv->repository);
|
||||
command->priv->repository = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gitg_command_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_command_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GitgCommand *self = GITG_COMMAND (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_REPOSITORY:
|
||||
self->priv->repository = g_value_dup_object (value);
|
||||
break;
|
||||
case PROP_ARGUMENTS:
|
||||
gitg_command_set_arguments (self,
|
||||
g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_ENVIRONMENT:
|
||||
gitg_command_set_environment (self,
|
||||
g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_WORKING_DIRECTORY:
|
||||
gitg_command_set_working_directory (self,
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_command_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GitgCommand *self = GITG_COMMAND (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_REPOSITORY:
|
||||
g_value_set_object (value, self->priv->repository);
|
||||
break;
|
||||
case PROP_ARGUMENTS:
|
||||
g_value_set_boxed (value, self->priv->arguments);
|
||||
break;
|
||||
case PROP_ENVIRONMENT:
|
||||
g_value_set_boxed (value, self->priv->environment);
|
||||
break;
|
||||
case PROP_WORKING_DIRECTORY:
|
||||
g_value_take_object (value, gitg_command_get_working_directory (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_command_class_init (GitgCommandClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gitg_command_finalize;
|
||||
object_class->dispose = gitg_command_dispose;
|
||||
|
||||
object_class->get_property = gitg_command_get_property;
|
||||
object_class->set_property = gitg_command_set_property;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof(GitgCommandPrivate));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_REPOSITORY,
|
||||
g_param_spec_object ("repository",
|
||||
"Repository",
|
||||
"Repository",
|
||||
GITG_TYPE_REPOSITORY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ARGUMENTS,
|
||||
g_param_spec_boxed ("arguments",
|
||||
"Arguments",
|
||||
"Arguments",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ENVIRONMENT,
|
||||
g_param_spec_boxed ("environment",
|
||||
"Environment",
|
||||
"Environment",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_WORKING_DIRECTORY,
|
||||
g_param_spec_object ("working-directory",
|
||||
"Working Directory",
|
||||
"Working directory",
|
||||
G_TYPE_FILE,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_command_init (GitgCommand *self)
|
||||
{
|
||||
self->priv = GITG_COMMAND_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
static gchar **
|
||||
collect_arguments (va_list ap)
|
||||
{
|
||||
GPtrArray *arguments;
|
||||
gchar const *arg;
|
||||
|
||||
arguments = g_ptr_array_new ();
|
||||
|
||||
while ((arg = va_arg (ap, gchar const *)) != NULL)
|
||||
{
|
||||
g_ptr_array_add (arguments, g_strdup (arg));
|
||||
}
|
||||
|
||||
g_ptr_array_add (arguments, NULL);
|
||||
|
||||
return (gchar **)g_ptr_array_free (arguments, FALSE);
|
||||
}
|
||||
|
||||
static gchar **
|
||||
combine_environment (gchar const * const *environment)
|
||||
{
|
||||
GPtrArray *ret;
|
||||
|
||||
ret = g_ptr_array_new ();
|
||||
|
||||
while (*environment)
|
||||
{
|
||||
gchar const *key = *environment++;
|
||||
gchar const *value = *environment++;
|
||||
|
||||
gchar *combined = g_strconcat (key, "=", value, NULL);
|
||||
|
||||
g_ptr_array_add (ret, combined);
|
||||
}
|
||||
|
||||
g_ptr_array_add (ret, NULL);
|
||||
|
||||
return (gchar **)g_ptr_array_free (ret, FALSE);
|
||||
}
|
||||
|
||||
GitgCommand *
|
||||
gitg_command_new (GitgRepository *repository,
|
||||
gchar const * const *arguments)
|
||||
{
|
||||
g_return_val_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository), NULL);
|
||||
|
||||
return g_object_new (GITG_TYPE_COMMAND,
|
||||
"repository", repository,
|
||||
"arguments", arguments,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GitgCommand *
|
||||
gitg_command_newv (GitgRepository *repository,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
GitgCommand *ret;
|
||||
gchar **arguments;
|
||||
|
||||
g_return_val_if_fail (repository == NULL || GITG_IS_REPOSITORY (repository), NULL);
|
||||
|
||||
va_start (ap, repository);
|
||||
|
||||
arguments = collect_arguments (ap);
|
||||
ret = gitg_command_new (repository, CONST_CONST (arguments));
|
||||
|
||||
g_strfreev (arguments);
|
||||
va_end (ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GitgRepository *
|
||||
gitg_command_get_repository (GitgCommand *command)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
|
||||
|
||||
return command->priv->repository;
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_set_arguments (GitgCommand *command,
|
||||
gchar const * const *arguments)
|
||||
{
|
||||
GPtrArray *ret;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
ret = g_ptr_array_new ();
|
||||
|
||||
if (command->priv->repository)
|
||||
{
|
||||
GFile *git_dir;
|
||||
GFile *work_tree;
|
||||
|
||||
gchar *git_dir_path;
|
||||
gchar *work_tree_path;
|
||||
|
||||
git_dir = gitg_repository_get_git_dir (command->priv->repository);
|
||||
work_tree = gitg_repository_get_work_tree (command->priv->repository);
|
||||
|
||||
git_dir_path = g_file_get_path (git_dir);
|
||||
work_tree_path = g_file_get_path (work_tree);
|
||||
|
||||
g_object_unref (git_dir);
|
||||
g_object_unref (work_tree);
|
||||
|
||||
g_ptr_array_add (ret, g_strdup ("git"));
|
||||
g_ptr_array_add (ret, g_strdup ("--git-dir"));
|
||||
g_ptr_array_add (ret, git_dir_path);
|
||||
g_ptr_array_add (ret, g_strdup ("--work-tree"));
|
||||
g_ptr_array_add (ret, work_tree_path);
|
||||
}
|
||||
|
||||
while (*arguments)
|
||||
{
|
||||
g_ptr_array_add (ret, g_strdup (*arguments++));
|
||||
}
|
||||
|
||||
g_ptr_array_add (ret, NULL);
|
||||
|
||||
g_strfreev (command->priv->arguments);
|
||||
command->priv->arguments = (gchar **)g_ptr_array_free (ret, FALSE);
|
||||
|
||||
g_object_notify (G_OBJECT (command), "arguments");
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_set_argumentsv (GitgCommand *command,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
gchar **arguments;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
va_start (ap, command);
|
||||
arguments = collect_arguments (ap);
|
||||
va_end (ap);
|
||||
|
||||
gitg_command_set_arguments (command, CONST_CONST (arguments));
|
||||
|
||||
g_strfreev (arguments);
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_add_arguments (GitgCommand *command,
|
||||
gchar const * const *arguments)
|
||||
{
|
||||
GPtrArray *args;
|
||||
gchar **ptr;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
args = g_ptr_array_new ();
|
||||
|
||||
for (ptr = command->priv->arguments; *ptr; ++ptr)
|
||||
{
|
||||
g_ptr_array_add (args, *ptr);
|
||||
}
|
||||
|
||||
while (*arguments)
|
||||
{
|
||||
g_ptr_array_add (args, g_strdup (*arguments++));
|
||||
}
|
||||
|
||||
g_free (command->priv->arguments);
|
||||
|
||||
g_ptr_array_add (args, NULL);
|
||||
command->priv->arguments = (gchar **)g_ptr_array_free (args, FALSE);
|
||||
|
||||
g_object_notify (G_OBJECT (command), "arguments");
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_add_argumentsv (GitgCommand *command,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
gchar **arguments;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
va_start (ap, command);
|
||||
arguments = collect_arguments (ap);
|
||||
va_end (ap);
|
||||
|
||||
gitg_command_add_arguments (command, CONST_CONST (arguments));
|
||||
|
||||
g_strfreev (arguments);
|
||||
}
|
||||
|
||||
gchar const * const *
|
||||
gitg_command_get_arguments (GitgCommand *command)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
|
||||
return CONST_CONST (command->priv->arguments);
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_set_environment (GitgCommand *command,
|
||||
gchar const * const *environment)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
g_strfreev (command->priv->environment);
|
||||
command->priv->environment = combine_environment (environment);
|
||||
|
||||
g_object_notify (G_OBJECT (command), "environment");
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_set_environmentv (GitgCommand *command,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
gchar **environment;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
va_start (ap, command);
|
||||
environment = collect_arguments (ap);
|
||||
va_end (ap);
|
||||
|
||||
gitg_command_set_environment (command, CONST_CONST (environment));
|
||||
|
||||
g_strfreev (environment);
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_add_environment (GitgCommand *command,
|
||||
gchar const * const *environment)
|
||||
{
|
||||
GPtrArray *args;
|
||||
gchar **combined;
|
||||
gchar **ptr;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
args = g_ptr_array_new ();
|
||||
|
||||
for (ptr = command->priv->environment; *ptr; ++ptr)
|
||||
{
|
||||
g_ptr_array_add (args, *ptr);
|
||||
}
|
||||
|
||||
combined = combine_environment (environment);
|
||||
|
||||
for (ptr = combined; *ptr; ++ptr)
|
||||
{
|
||||
g_ptr_array_add (args, *ptr);
|
||||
}
|
||||
|
||||
g_free (combined);
|
||||
g_free (command->priv->environment);
|
||||
|
||||
g_ptr_array_add (args, NULL);
|
||||
|
||||
command->priv->environment = (gchar **)g_ptr_array_free (args, FALSE);
|
||||
|
||||
g_object_notify (G_OBJECT (command), "arguments");
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_add_environmentv (GitgCommand *command,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
gchar **environment;
|
||||
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
|
||||
va_start (ap, command);
|
||||
environment = collect_arguments (ap);
|
||||
va_end (ap);
|
||||
|
||||
gitg_command_add_environment (command, CONST_CONST (environment));
|
||||
g_strfreev (environment);
|
||||
}
|
||||
|
||||
gchar const * const *
|
||||
gitg_command_get_environment (GitgCommand *command)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
|
||||
|
||||
return CONST_CONST (command->priv->environment);
|
||||
}
|
||||
|
||||
void
|
||||
gitg_command_set_working_directory (GitgCommand *command,
|
||||
GFile *working_directory)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_COMMAND (command));
|
||||
g_return_if_fail (working_directory == NULL || G_IS_FILE (working_directory));
|
||||
|
||||
if (command->priv->working_directory)
|
||||
{
|
||||
g_object_unref (command->priv->working_directory);
|
||||
command->priv->working_directory = NULL;
|
||||
}
|
||||
|
||||
if (working_directory)
|
||||
{
|
||||
command->priv->working_directory = g_file_dup (working_directory);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (command), "working-directory");
|
||||
}
|
||||
|
||||
GFile *
|
||||
gitg_command_get_working_directory (GitgCommand *command)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_COMMAND (command), NULL);
|
||||
|
||||
if (command->priv->working_directory)
|
||||
{
|
||||
return g_file_dup (command->priv->working_directory);
|
||||
}
|
||||
else if (command->priv->repository)
|
||||
{
|
||||
return gitg_repository_get_work_tree (command->priv->repository);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
76
libgitg/gitg-command.h
Normal file
76
libgitg/gitg-command.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#ifndef __GITG_COMMAND_H__
|
||||
#define __GITG_COMMAND_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <libgitg/gitg-repository.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_COMMAND (gitg_command_get_type ())
|
||||
#define GITG_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMAND, GitgCommand))
|
||||
#define GITG_COMMAND_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_COMMAND, GitgCommand const))
|
||||
#define GITG_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_COMMAND, GitgCommandClass))
|
||||
#define GITG_IS_COMMAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_COMMAND))
|
||||
#define GITG_IS_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_COMMAND))
|
||||
#define GITG_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_COMMAND, GitgCommandClass))
|
||||
|
||||
typedef struct _GitgCommand GitgCommand;
|
||||
typedef struct _GitgCommandClass GitgCommandClass;
|
||||
typedef struct _GitgCommandPrivate GitgCommandPrivate;
|
||||
|
||||
struct _GitgCommand
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnowned parent;
|
||||
|
||||
GitgCommandPrivate *priv;
|
||||
|
||||
/*< public >*/
|
||||
};
|
||||
|
||||
struct _GitgCommandClass
|
||||
{
|
||||
/*< private >*/
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
};
|
||||
|
||||
GType gitg_command_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GitgCommand *gitg_command_new (GitgRepository *repository,
|
||||
gchar const * const *arguments);
|
||||
GitgCommand *gitg_command_newv (GitgRepository *repository,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
GitgRepository *gitg_command_get_repository (GitgCommand *command);
|
||||
|
||||
GFile *gitg_command_get_working_directory (GitgCommand *command);
|
||||
void gitg_command_set_working_directory (GitgCommand *command,
|
||||
GFile *file);
|
||||
|
||||
void gitg_command_set_arguments (GitgCommand *command,
|
||||
gchar const * const *arguments);
|
||||
void gitg_command_set_argumentsv (GitgCommand *command,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void gitg_command_add_arguments (GitgCommand *command,
|
||||
gchar const * const *arguments);
|
||||
void gitg_command_add_argumentsv (GitgCommand *command,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar const * const *gitg_command_get_arguments (GitgCommand *command);
|
||||
|
||||
void gitg_command_set_environment (GitgCommand *command,
|
||||
gchar const * const *environment);
|
||||
void gitg_command_set_environmentv (GitgCommand *command,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void gitg_command_add_environment (GitgCommand *command,
|
||||
gchar const * const *environment);
|
||||
void gitg_command_add_environmentv (GitgCommand *command,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar const * const *gitg_command_get_environment (GitgCommand *command);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GITG_COMMAND_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,8 @@ typedef struct _GitgCommitPrivate GitgCommitPrivate;
|
|||
typedef enum
|
||||
{
|
||||
GITG_COMMIT_ERROR_NONE = 0,
|
||||
GITG_COMMIT_ERROR_SIGNOFF
|
||||
GITG_COMMIT_ERROR_SIGNOFF,
|
||||
GITG_COMMIT_ERROR_MERGE
|
||||
} GitgCommitError;
|
||||
|
||||
struct _GitgCommit {
|
||||
|
@ -62,24 +63,45 @@ struct _GitgCommitClass {
|
|||
void (*removed) (GitgCommit *commit, GitgChangedFile *file);
|
||||
};
|
||||
|
||||
GQuark gitg_commit_error_quark(void);
|
||||
GQuark gitg_commit_error_quark (void);
|
||||
|
||||
GType gitg_commit_get_type(void) G_GNUC_CONST;
|
||||
GitgCommit *gitg_commit_new(GitgRepository *repository);
|
||||
GType gitg_commit_get_type (void) G_GNUC_CONST;
|
||||
GitgCommit *gitg_commit_new (GitgRepository *repository);
|
||||
|
||||
void gitg_commit_refresh(GitgCommit *commit);
|
||||
gboolean gitg_commit_stage(GitgCommit *commit, GitgChangedFile *file, gchar const *hunk, GError **error);
|
||||
gboolean gitg_commit_unstage(GitgCommit *commit, GitgChangedFile *file, gchar const *hunk, GError **error);
|
||||
void gitg_commit_refresh (GitgCommit *commit);
|
||||
gboolean gitg_commit_stage (GitgCommit *commit,
|
||||
GitgChangedFile *file,
|
||||
gchar const *hunk,
|
||||
GError **error);
|
||||
gboolean gitg_commit_unstage (GitgCommit *commit,
|
||||
GitgChangedFile *file,
|
||||
gchar const *hunk,
|
||||
GError **error);
|
||||
gboolean gitg_commit_has_changes (GitgCommit *commit);
|
||||
gboolean gitg_commit_commit (GitgCommit *commit,
|
||||
gchar const *comment,
|
||||
gboolean signoff,
|
||||
gboolean amend,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_commit_has_changes(GitgCommit *commit);
|
||||
gboolean gitg_commit_commit(GitgCommit *commit, gchar const *comment, gboolean signoff, gboolean amend, GError **error);
|
||||
gboolean gitg_commit_revert (GitgCommit *commit,
|
||||
GitgRevision *from,
|
||||
GitgRevision *to,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_commit_revert(GitgCommit *commit, GitgChangedFile *file, gchar const *hunk, GError **error);
|
||||
gboolean gitg_commit_add_ignore(GitgCommit *commit, GitgChangedFile *file, GError **error);
|
||||
gboolean gitg_commit_undo (GitgCommit *commit,
|
||||
GitgChangedFile *file,
|
||||
gchar const *hunk,
|
||||
GError **error);
|
||||
|
||||
GitgChangedFile *gitg_commit_find_changed_file(GitgCommit *commit, GFile *file);
|
||||
gboolean gitg_commit_add_ignore (GitgCommit *commit,
|
||||
GitgChangedFile *file,
|
||||
GError **error);
|
||||
|
||||
gchar *gitg_commit_amend_message (GitgCommit *commit);
|
||||
GitgChangedFile *gitg_commit_find_changed_file (GitgCommit *commit,
|
||||
GFile *file);
|
||||
|
||||
gchar *gitg_commit_amend_message (GitgCommit *commit);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "gitg-config.h"
|
||||
|
||||
#include "gitg-shell.h"
|
||||
|
||||
#define GITG_CONFIG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_CONFIG, GitgConfigPrivate))
|
||||
|
||||
|
@ -34,7 +34,7 @@ enum
|
|||
struct _GitgConfigPrivate
|
||||
{
|
||||
GitgRepository *repository;
|
||||
GitgRunner *runner;
|
||||
GitgShell *shell;
|
||||
|
||||
GString *accumulated;
|
||||
};
|
||||
|
@ -113,24 +113,22 @@ gitg_config_class_init (GitgConfigClass *klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gitg_config_accumulate (GitgRunner *runner, gchar **buffer, GitgConfig *config)
|
||||
gitg_config_accumulate (GitgShell *shell,
|
||||
gchar **buffer,
|
||||
GitgConfig *config)
|
||||
{
|
||||
gchar **ptr = buffer;
|
||||
|
||||
while (*ptr)
|
||||
{
|
||||
if (config->priv->accumulated->len != 0)
|
||||
{
|
||||
g_string_append_c (config->priv->accumulated, '\n');
|
||||
}
|
||||
|
||||
g_string_append (config->priv->accumulated, *ptr);
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_config_begin_loading (GitgRunner *runner, GitgConfig *config)
|
||||
gitg_config_begin (GitgShell *shell,
|
||||
GitgConfig *config)
|
||||
{
|
||||
g_string_erase (config->priv->accumulated, 0, -1);
|
||||
}
|
||||
|
@ -140,18 +138,18 @@ gitg_config_init (GitgConfig *self)
|
|||
{
|
||||
self->priv = GITG_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
self->priv->runner = gitg_runner_new_synchronized (1000);
|
||||
self->priv->shell = gitg_shell_new_synchronized (1000);
|
||||
|
||||
self->priv->accumulated = g_string_new ("");
|
||||
|
||||
g_signal_connect (self->priv->runner,
|
||||
"update",
|
||||
g_signal_connect (self->priv->shell,
|
||||
"update",
|
||||
G_CALLBACK (gitg_config_accumulate),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->priv->runner,
|
||||
"begin-loading",
|
||||
G_CALLBACK (gitg_config_begin_loading),
|
||||
g_signal_connect (self->priv->shell,
|
||||
"begin",
|
||||
G_CALLBACK (gitg_config_begin),
|
||||
self);
|
||||
}
|
||||
|
||||
|
@ -168,7 +166,8 @@ get_value_process (GitgConfig *config, gboolean ret)
|
|||
|
||||
if (ret)
|
||||
{
|
||||
res = g_strndup (config->priv->accumulated->str, config->priv->accumulated->len);
|
||||
res = g_strndup (config->priv->accumulated->str,
|
||||
config->priv->accumulated->len);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -181,15 +180,14 @@ get_value_process (GitgConfig *config, gboolean ret)
|
|||
static gchar *
|
||||
get_value_global (GitgConfig *config, gchar const *key)
|
||||
{
|
||||
gchar const *argv[] = {
|
||||
"git",
|
||||
"config",
|
||||
"--global",
|
||||
key,
|
||||
NULL
|
||||
};
|
||||
gboolean ret = gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--global",
|
||||
key,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
gboolean ret = gitg_runner_run (config->priv->runner, argv, NULL);
|
||||
return get_value_process (config, ret);
|
||||
}
|
||||
|
||||
|
@ -198,17 +196,14 @@ get_value_global_regex (GitgConfig *config,
|
|||
gchar const *regex,
|
||||
gchar const *value_regex)
|
||||
{
|
||||
gchar const *argv[] = {
|
||||
"git",
|
||||
"config",
|
||||
"--global",
|
||||
"--get-regexp",
|
||||
regex,
|
||||
value_regex,
|
||||
NULL
|
||||
};
|
||||
gboolean ret = gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--global",
|
||||
"--get-regexp",
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
gboolean ret = gitg_runner_run (config->priv->runner, argv, NULL);
|
||||
return get_value_process (config, ret);
|
||||
}
|
||||
|
||||
|
@ -225,14 +220,14 @@ get_value_local (GitgConfig *config, gchar const *key)
|
|||
cfg_file = g_file_get_child (git_dir, "config");
|
||||
cfg = g_file_get_path (cfg_file);
|
||||
|
||||
ret = gitg_repository_run_commandv (config->priv->repository,
|
||||
config->priv->runner,
|
||||
NULL,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
key,
|
||||
NULL);
|
||||
ret = gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
key,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (cfg);
|
||||
|
||||
|
@ -257,16 +252,16 @@ get_value_local_regex (GitgConfig *config,
|
|||
cfg_file = g_file_get_child (git_dir, "config");
|
||||
cfg = g_file_get_path (cfg_file);
|
||||
|
||||
ret = gitg_repository_run_commandv (config->priv->repository,
|
||||
config->priv->runner,
|
||||
NULL,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
"--get-regexp",
|
||||
regex,
|
||||
value_regex,
|
||||
NULL);
|
||||
ret = gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
"--get-regexp",
|
||||
regex,
|
||||
value_regex,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (cfg);
|
||||
|
||||
|
@ -279,16 +274,14 @@ get_value_local_regex (GitgConfig *config,
|
|||
static gboolean
|
||||
set_value_global (GitgConfig *config, gchar const *key, gchar const *value)
|
||||
{
|
||||
gchar const *argv[] = {
|
||||
"git",
|
||||
"config",
|
||||
"--global",
|
||||
value == NULL ? "--unset" : key,
|
||||
value == NULL ? key : value,
|
||||
NULL
|
||||
};
|
||||
|
||||
return gitg_runner_run (config->priv->runner, argv, NULL);
|
||||
return gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--global",
|
||||
value == NULL ? "--unset" : key,
|
||||
value == NULL ? key : value,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -304,15 +297,15 @@ set_value_local (GitgConfig *config, gchar const *key, gchar const *value)
|
|||
cfg_file = g_file_get_child (git_dir, "config");
|
||||
cfg = g_file_get_path (cfg_file);
|
||||
|
||||
ret = gitg_repository_run_commandv (config->priv->repository,
|
||||
config->priv->runner,
|
||||
NULL,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
value == NULL ? "--unset" : key,
|
||||
value == NULL ? key : value,
|
||||
NULL);
|
||||
ret = gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
value == NULL ? "--unset" : key,
|
||||
value == NULL ? key : value,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (cfg);
|
||||
|
||||
|
@ -325,17 +318,15 @@ set_value_local (GitgConfig *config, gchar const *key, gchar const *value)
|
|||
static gboolean
|
||||
rename_global (GitgConfig *config, gchar const *old, gchar const *nw)
|
||||
{
|
||||
gchar const *argv[] = {
|
||||
"git",
|
||||
"config",
|
||||
"--global",
|
||||
"--rename-section",
|
||||
old,
|
||||
nw,
|
||||
NULL
|
||||
};
|
||||
|
||||
return gitg_runner_run (config->priv->runner, argv, NULL);
|
||||
return gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--global",
|
||||
"--rename-section",
|
||||
old,
|
||||
nw,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -351,16 +342,16 @@ rename_local (GitgConfig *config, gchar const *old, gchar const *nw)
|
|||
cfg_file = g_file_get_child (git_dir, "config");
|
||||
cfg = g_file_get_path (cfg_file);
|
||||
|
||||
ret = gitg_repository_run_commandv (config->priv->repository,
|
||||
config->priv->runner,
|
||||
NULL,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
"--rename-section",
|
||||
old,
|
||||
nw,
|
||||
NULL);
|
||||
ret = gitg_shell_run (config->priv->shell,
|
||||
gitg_command_newv (config->priv->repository,
|
||||
"config",
|
||||
"--file",
|
||||
cfg,
|
||||
"--rename-section",
|
||||
old,
|
||||
nw,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (cfg);
|
||||
|
||||
|
|
|
@ -28,36 +28,47 @@
|
|||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_CONFIG (gitg_config_get_type ())
|
||||
#define GITG_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CONFIG, GitgConfig))
|
||||
#define GITG_TYPE_CONFIG (gitg_config_get_type ())
|
||||
#define GITG_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CONFIG, GitgConfig))
|
||||
#define GITG_CONFIG_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_CONFIG, GitgConfig const))
|
||||
#define GITG_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_CONFIG, GitgConfigClass))
|
||||
#define GITG_IS_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_CONFIG))
|
||||
#define GITG_IS_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_CONFIG))
|
||||
#define GITG_IS_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_CONFIG))
|
||||
#define GITG_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_CONFIG, GitgConfigClass))
|
||||
|
||||
typedef struct _GitgConfig GitgConfig;
|
||||
typedef struct _GitgConfig GitgConfig;
|
||||
typedef struct _GitgConfigClass GitgConfigClass;
|
||||
typedef struct _GitgConfigPrivate GitgConfigPrivate;
|
||||
|
||||
struct _GitgConfig {
|
||||
struct _GitgConfig
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
GitgConfigPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GitgConfigClass {
|
||||
struct _GitgConfigClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gitg_config_get_type (void) G_GNUC_CONST;
|
||||
GitgConfig *gitg_config_new (GitgRepository *repository);
|
||||
GType gitg_config_get_type (void) G_GNUC_CONST;
|
||||
GitgConfig *gitg_config_new (GitgRepository *repository);
|
||||
|
||||
gchar *gitg_config_get_value (GitgConfig *config, gchar const *key);
|
||||
gchar *gitg_config_get_value_regex (GitgConfig *config, gchar const *regex, gchar const *value_regex);
|
||||
gchar *gitg_config_get_value (GitgConfig *config,
|
||||
gchar const *key);
|
||||
|
||||
gboolean gitg_config_rename (GitgConfig *config, gchar const *old, gchar const *nw);
|
||||
gboolean gitg_config_set_value (GitgConfig *config, gchar const *key, gchar const *value);
|
||||
gchar *gitg_config_get_value_regex (GitgConfig *config,
|
||||
gchar const *regex,
|
||||
gchar const *value_regex);
|
||||
|
||||
gboolean gitg_config_rename (GitgConfig *config,
|
||||
gchar const *old,
|
||||
gchar const *nw);
|
||||
|
||||
gboolean gitg_config_set_value (GitgConfig *config,
|
||||
gchar const *key,
|
||||
gchar const *value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
406
libgitg/gitg-io.c
Normal file
406
libgitg/gitg-io.c
Normal file
|
@ -0,0 +1,406 @@
|
|||
#include "gitg-io.h"
|
||||
|
||||
|
||||
#define GITG_IO_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_IO, GitgIOPrivate))
|
||||
|
||||
struct _GitgIOPrivate
|
||||
{
|
||||
GInputStream *input;
|
||||
GOutputStream *output;
|
||||
|
||||
gint exit_status;
|
||||
|
||||
guint cancelled : 1;
|
||||
guint running : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_INPUT,
|
||||
PROP_OUTPUT,
|
||||
PROP_CANCELLED,
|
||||
PROP_EXIT_STATUS,
|
||||
PROP_RUNNING
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BEGIN,
|
||||
END,
|
||||
NUM_SIGNALS
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GitgIO, gitg_io, G_TYPE_OBJECT)
|
||||
|
||||
static guint signals[NUM_SIGNALS] = {0,};
|
||||
|
||||
static void
|
||||
gitg_io_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (gitg_io_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_dispose (GObject *object)
|
||||
{
|
||||
GitgIO *io;
|
||||
|
||||
io = GITG_IO (object);
|
||||
|
||||
gitg_io_close (io);
|
||||
|
||||
G_OBJECT_CLASS (gitg_io_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GitgIO *self = GITG_IO (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_INPUT:
|
||||
gitg_io_set_input (self, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_OUTPUT:
|
||||
gitg_io_set_output (self, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_CANCELLED:
|
||||
gitg_io_set_cancelled (self, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_EXIT_STATUS:
|
||||
gitg_io_set_exit_status (self, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_RUNNING:
|
||||
gitg_io_set_running (self, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GitgIO *self = GITG_IO (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_INPUT:
|
||||
g_value_set_object (value, self->priv->input);
|
||||
break;
|
||||
case PROP_OUTPUT:
|
||||
g_value_set_object (value, self->priv->output);
|
||||
break;
|
||||
case PROP_CANCELLED:
|
||||
g_value_set_boolean (value, self->priv->cancelled);
|
||||
break;
|
||||
case PROP_EXIT_STATUS:
|
||||
g_value_set_int (value, self->priv->exit_status);
|
||||
break;
|
||||
case PROP_RUNNING:
|
||||
g_value_set_boolean (value, self->priv->running);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_cancel_impl (GitgIO *io)
|
||||
{
|
||||
io->priv->cancelled = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_begin_impl (GitgIO *io)
|
||||
{
|
||||
gitg_io_set_running (io, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_end_impl (GitgIO *io,
|
||||
GError *error)
|
||||
{
|
||||
gitg_io_set_running (io, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_class_init (GitgIOClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gitg_io_finalize;
|
||||
object_class->dispose = gitg_io_dispose;
|
||||
|
||||
object_class->get_property = gitg_io_get_property;
|
||||
object_class->set_property = gitg_io_set_property;
|
||||
|
||||
klass->cancel = gitg_io_cancel_impl;
|
||||
klass->begin = gitg_io_begin_impl;
|
||||
klass->end = gitg_io_end_impl;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INPUT,
|
||||
g_param_spec_object ("input",
|
||||
"Input",
|
||||
"Input",
|
||||
G_TYPE_INPUT_STREAM,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_OUTPUT,
|
||||
g_param_spec_object ("output",
|
||||
"Output",
|
||||
"Output",
|
||||
G_TYPE_OUTPUT_STREAM,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_CANCELLED,
|
||||
g_param_spec_boolean ("cancelled",
|
||||
"Cancelled",
|
||||
"Cancelled",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_EXIT_STATUS,
|
||||
g_param_spec_int ("exit-status",
|
||||
"Exit status",
|
||||
"Exit Status",
|
||||
G_MININT,
|
||||
G_MAXINT,
|
||||
0,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_RUNNING,
|
||||
g_param_spec_boolean ("running",
|
||||
"Running",
|
||||
"Running",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
signals[BEGIN] =
|
||||
g_signal_new ("begin",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GitgIOClass, begin),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
signals[END] =
|
||||
g_signal_new ("end",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GitgIOClass, end),
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_ERROR);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GitgIOPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_io_init (GitgIO *self)
|
||||
{
|
||||
self->priv = GITG_IO_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
GitgIO *
|
||||
gitg_io_new ()
|
||||
{
|
||||
return g_object_new (GITG_TYPE_IO, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_begin (GitgIO *io)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
|
||||
if (!io->priv->running)
|
||||
{
|
||||
g_signal_emit (io, signals[BEGIN], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_end (GitgIO *io,
|
||||
GError *error)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
|
||||
if (io->priv->running)
|
||||
{
|
||||
g_signal_emit (io, signals[END], 0, error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_cancel (GitgIO *io)
|
||||
{
|
||||
if (GITG_IO_GET_CLASS (io)->cancel)
|
||||
{
|
||||
GITG_IO_GET_CLASS (io)->cancel (io);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_io_get_cancelled (GitgIO *io)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_IO (io), FALSE);
|
||||
|
||||
return io->priv->cancelled;
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_set_cancelled (GitgIO *io,
|
||||
gboolean cancelled)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
|
||||
if (io->priv->cancelled != cancelled)
|
||||
{
|
||||
io->priv->cancelled = cancelled;
|
||||
g_object_notify (G_OBJECT (io), "cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_set_output (GitgIO *io,
|
||||
GOutputStream *stream)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
|
||||
|
||||
if (io->priv->output)
|
||||
{
|
||||
g_object_unref (io->priv->output);
|
||||
io->priv->output = NULL;
|
||||
}
|
||||
|
||||
if (stream)
|
||||
{
|
||||
io->priv->output = g_object_ref (stream);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_set_input (GitgIO *io,
|
||||
GInputStream *stream)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
|
||||
if (io->priv->input)
|
||||
{
|
||||
g_object_unref (io->priv->input);
|
||||
io->priv->input = NULL;
|
||||
}
|
||||
|
||||
if (stream)
|
||||
{
|
||||
io->priv->input = g_object_ref (stream);
|
||||
}
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
gitg_io_get_input (GitgIO *io)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_IO (io), NULL);
|
||||
return io->priv->input;
|
||||
}
|
||||
|
||||
GOutputStream *
|
||||
gitg_io_get_output (GitgIO *io)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_IO (io), NULL);
|
||||
return io->priv->output;
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_close (GitgIO *io)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
|
||||
if (io->priv->input)
|
||||
{
|
||||
g_input_stream_close (io->priv->input, NULL, NULL);
|
||||
|
||||
g_object_unref (io->priv->input);
|
||||
io->priv->input = NULL;
|
||||
}
|
||||
|
||||
if (io->priv->output)
|
||||
{
|
||||
g_output_stream_close (io->priv->output, NULL, NULL);
|
||||
|
||||
g_object_unref (io->priv->output);
|
||||
io->priv->output = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gint
|
||||
gitg_io_get_exit_status (GitgIO *io)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_IO (io), 0);
|
||||
|
||||
return io->priv->exit_status;
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_set_exit_status (GitgIO *io,
|
||||
gint exit_status)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
|
||||
if (io->priv->exit_status != exit_status)
|
||||
{
|
||||
io->priv->exit_status = exit_status;
|
||||
g_object_notify (G_OBJECT (io), "exit-status");
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_io_get_running (GitgIO *io)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_IO (io), FALSE);
|
||||
|
||||
return io->priv->running;
|
||||
}
|
||||
|
||||
void
|
||||
gitg_io_set_running (GitgIO *io,
|
||||
gboolean running)
|
||||
{
|
||||
g_return_if_fail (GITG_IS_IO (io));
|
||||
|
||||
if (io->priv->running != running)
|
||||
{
|
||||
io->priv->running = running;
|
||||
|
||||
if (running)
|
||||
{
|
||||
io->priv->cancelled = FALSE;
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (io), "running");
|
||||
}
|
||||
}
|
70
libgitg/gitg-io.h
Normal file
70
libgitg/gitg-io.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
#ifndef __GITG_IO_H__
|
||||
#define __GITG_IO_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_IO (gitg_io_get_type ())
|
||||
#define GITG_IO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_IO, GitgIO))
|
||||
#define GITG_IO_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_IO, GitgIO const))
|
||||
#define GITG_IO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_IO, GitgIOClass))
|
||||
#define GITG_IS_IO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_IO))
|
||||
#define GITG_IS_IO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_IO))
|
||||
#define GITG_IO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_IO, GitgIOClass))
|
||||
|
||||
typedef struct _GitgIO GitgIO;
|
||||
typedef struct _GitgIOClass GitgIOClass;
|
||||
typedef struct _GitgIOPrivate GitgIOPrivate;
|
||||
|
||||
struct _GitgIO
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
|
||||
GitgIOPrivate *priv;
|
||||
|
||||
/*< public >*/
|
||||
};
|
||||
|
||||
struct _GitgIOClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (*cancel) (GitgIO *io);
|
||||
|
||||
/* Signals */
|
||||
void (*begin) (GitgIO *io);
|
||||
void (*end) (GitgIO *io, GError *error);
|
||||
};
|
||||
|
||||
GType gitg_io_get_type (void) G_GNUC_CONST;
|
||||
GitgIO *gitg_io_new (void);
|
||||
|
||||
void gitg_io_begin (GitgIO *io);
|
||||
void gitg_io_end (GitgIO *io, GError *error);
|
||||
|
||||
void gitg_io_set_input (GitgIO *io, GInputStream *stream);
|
||||
void gitg_io_set_output (GitgIO *io, GOutputStream *stream);
|
||||
|
||||
GInputStream *gitg_io_get_input (GitgIO *io);
|
||||
GOutputStream *gitg_io_get_output (GitgIO *io);
|
||||
|
||||
void gitg_io_close (GitgIO *io);
|
||||
void gitg_io_cancel (GitgIO *io);
|
||||
|
||||
gboolean gitg_io_get_cancelled (GitgIO *io);
|
||||
void gitg_io_set_cancelled (GitgIO *io, gboolean cancelled);
|
||||
|
||||
gint gitg_io_get_exit_status (GitgIO *io);
|
||||
void gitg_io_set_exit_status (GitgIO *io, gint status);
|
||||
|
||||
gboolean gitg_io_get_running (GitgIO *io);
|
||||
void gitg_io_set_running (GitgIO *io, gboolean running);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GITG_IO_H__ */
|
452
libgitg/gitg-line-parser.c
Normal file
452
libgitg/gitg-line-parser.c
Normal file
|
@ -0,0 +1,452 @@
|
|||
#include "gitg-line-parser.h"
|
||||
|
||||
|
||||
#define GITG_LINE_PARSER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GITG_TYPE_LINE_PARSER, GitgLineParserPrivate))
|
||||
|
||||
struct _GitgLineParserPrivate
|
||||
{
|
||||
gchar *rest_buffer;
|
||||
gsize rest_buffer_size;
|
||||
|
||||
gchar **lines;
|
||||
guint buffer_size;
|
||||
|
||||
gchar *read_buffer;
|
||||
|
||||
gboolean preserve_line_endings;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LINES,
|
||||
DONE,
|
||||
NUM_SIGNALS
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GitgLineParser, gitg_line_parser, G_TYPE_OBJECT)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_BUFFER_SIZE,
|
||||
PROP_PRESERVE_LINE_ENDINGS
|
||||
};
|
||||
|
||||
static guint signals[NUM_SIGNALS] = {0,};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GitgLineParser *parser;
|
||||
GInputStream *stream;
|
||||
GCancellable *cancellable;
|
||||
} AsyncData;
|
||||
|
||||
static AsyncData *
|
||||
async_data_new (GitgLineParser *parser,
|
||||
GInputStream *stream,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
AsyncData *data;
|
||||
|
||||
data = g_slice_new (AsyncData);
|
||||
data->parser = parser;
|
||||
data->stream = stream;
|
||||
data->cancellable = g_object_ref (cancellable);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
async_data_free (AsyncData *data)
|
||||
{
|
||||
g_object_unref (data->cancellable);
|
||||
g_slice_free (AsyncData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
free_lines (GitgLineParser *stream)
|
||||
{
|
||||
gint i = 0;
|
||||
|
||||
while (stream->priv->lines[i])
|
||||
{
|
||||
g_free (stream->priv->lines[i++]);
|
||||
}
|
||||
|
||||
stream->priv->lines[0] = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_line_parser_finalize (GObject *object)
|
||||
{
|
||||
GitgLineParser *stream;
|
||||
|
||||
stream = GITG_LINE_PARSER (object);
|
||||
|
||||
free_lines (stream);
|
||||
|
||||
g_slice_free1 (sizeof (gchar *) * (stream->priv->buffer_size + 1), stream->priv->lines);
|
||||
g_slice_free1 (sizeof (gchar) * (stream->priv->buffer_size + 1), stream->priv->read_buffer);
|
||||
|
||||
G_OBJECT_CLASS (gitg_line_parser_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
find_newline (const gchar *ptr,
|
||||
const gchar *end,
|
||||
const gchar **line_end)
|
||||
{
|
||||
|
||||
while (ptr < end)
|
||||
{
|
||||
gunichar c;
|
||||
|
||||
c = g_utf8_get_char (ptr);
|
||||
|
||||
if (c == '\n')
|
||||
{
|
||||
/* That's it */
|
||||
*line_end = g_utf8_next_char (ptr);
|
||||
return ptr;
|
||||
}
|
||||
else if (c == '\r')
|
||||
{
|
||||
gchar *next;
|
||||
|
||||
next = g_utf8_next_char (ptr);
|
||||
|
||||
if (next < end)
|
||||
{
|
||||
gunichar n = g_utf8_get_char (next);
|
||||
|
||||
if (n == '\n')
|
||||
{
|
||||
/* Consume both! */
|
||||
*line_end = g_utf8_next_char (next);
|
||||
return ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* That's it! */
|
||||
*line_end = next;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Need to save it, it might come later... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = g_utf8_next_char (ptr);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_lines (GitgLineParser *stream,
|
||||
const gchar *buffer,
|
||||
gssize size)
|
||||
{
|
||||
gchar const *ptr;
|
||||
gchar const *newline = NULL;
|
||||
gint i = 0;
|
||||
gchar *all = NULL;
|
||||
gchar const *end;
|
||||
|
||||
if (stream->priv->rest_buffer_size > 0)
|
||||
{
|
||||
GString *str = g_string_sized_new (stream->priv->rest_buffer_size + size);
|
||||
|
||||
g_string_append_len (str, stream->priv->rest_buffer, stream->priv->rest_buffer_size);
|
||||
g_string_append_len (str, buffer, size);
|
||||
|
||||
all = g_string_free (str, FALSE);
|
||||
size += stream->priv->rest_buffer_size;
|
||||
|
||||
g_free (stream->priv->rest_buffer);
|
||||
stream->priv->rest_buffer = NULL;
|
||||
stream->priv->rest_buffer_size = 0;
|
||||
|
||||
ptr = all;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = buffer;
|
||||
}
|
||||
|
||||
const gchar *line_end;
|
||||
end = ptr + size;
|
||||
|
||||
while ((newline = find_newline (ptr, end, &line_end)))
|
||||
{
|
||||
if (stream->priv->preserve_line_endings)
|
||||
{
|
||||
stream->priv->lines[i++] = g_strndup (ptr, line_end - ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream->priv->lines[i++] = g_strndup (ptr, newline - ptr);
|
||||
}
|
||||
|
||||
ptr = line_end;
|
||||
|
||||
if (i == stream->priv->buffer_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr < end)
|
||||
{
|
||||
stream->priv->rest_buffer_size = end - ptr;
|
||||
stream->priv->rest_buffer = g_strndup (ptr, stream->priv->rest_buffer_size);
|
||||
}
|
||||
|
||||
stream->priv->lines[i] = NULL;
|
||||
|
||||
g_signal_emit (stream, signals[LINES], 0, stream->priv->lines);
|
||||
|
||||
g_free (all);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_rest (GitgLineParser *stream)
|
||||
{
|
||||
if (stream->priv->rest_buffer_size > 0)
|
||||
{
|
||||
if (!stream->priv->preserve_line_endings &&
|
||||
stream->priv->rest_buffer[stream->priv->rest_buffer_size - 1] == '\r')
|
||||
{
|
||||
stream->priv->rest_buffer[stream->priv->rest_buffer_size - 1] = '\0';
|
||||
}
|
||||
|
||||
gchar *b[] = {stream->priv->rest_buffer, NULL};
|
||||
|
||||
g_signal_emit (stream, signals[LINES], 0, b);
|
||||
|
||||
g_free (stream->priv->rest_buffer);
|
||||
stream->priv->rest_buffer = NULL;
|
||||
stream->priv->rest_buffer_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parser_done (AsyncData *data,
|
||||
GError *error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
emit_rest (data->parser);
|
||||
}
|
||||
|
||||
g_signal_emit (data->parser, signals[DONE], 0, error);
|
||||
|
||||
async_data_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_line_parser_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GitgLineParser *self = GITG_LINE_PARSER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BUFFER_SIZE:
|
||||
self->priv->buffer_size = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_PRESERVE_LINE_ENDINGS:
|
||||
self->priv->preserve_line_endings = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_line_parser_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GitgLineParser *self = GITG_LINE_PARSER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BUFFER_SIZE:
|
||||
g_value_set_uint (value, self->priv->buffer_size);
|
||||
break;
|
||||
case PROP_PRESERVE_LINE_ENDINGS:
|
||||
g_value_set_boolean (value, self->priv->preserve_line_endings);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_line_parser_constructed (GObject *object)
|
||||
{
|
||||
GitgLineParser *stream;
|
||||
|
||||
stream = GITG_LINE_PARSER (object);
|
||||
|
||||
stream->priv->lines = g_slice_alloc (sizeof (gchar *) * (stream->priv->buffer_size + 1));
|
||||
stream->priv->lines[0] = NULL;
|
||||
|
||||
stream->priv->read_buffer = g_slice_alloc (sizeof (gchar) * (stream->priv->buffer_size + 1));
|
||||
}
|
||||
|
||||
static void start_read_lines (AsyncData *data);
|
||||
|
||||
static void
|
||||
read_ready (GInputStream *stream,
|
||||
GAsyncResult *result,
|
||||
AsyncData *data)
|
||||
{
|
||||
gssize read;
|
||||
GError *error = NULL;
|
||||
|
||||
read = g_input_stream_read_finish (stream, result, &error);
|
||||
|
||||
if (g_cancellable_is_cancelled (data->cancellable))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
async_data_free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (read == -1)
|
||||
{
|
||||
parser_done (data, error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
else if (read == 0)
|
||||
{
|
||||
parser_done (data, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
data->parser->priv->read_buffer[read] = '\0';
|
||||
|
||||
parse_lines (data->parser,
|
||||
data->parser->priv->read_buffer,
|
||||
read);
|
||||
|
||||
start_read_lines (data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
start_read_lines (AsyncData *data)
|
||||
{
|
||||
g_input_stream_read_async (data->stream,
|
||||
data->parser->priv->read_buffer,
|
||||
data->parser->priv->buffer_size,
|
||||
G_PRIORITY_DEFAULT,
|
||||
data->cancellable,
|
||||
(GAsyncReadyCallback)read_ready,
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_line_parser_class_init (GitgLineParserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = gitg_line_parser_finalize;
|
||||
object_class->constructed = gitg_line_parser_constructed;
|
||||
|
||||
object_class->get_property = gitg_line_parser_get_property;
|
||||
object_class->set_property = gitg_line_parser_set_property;
|
||||
|
||||
g_type_class_add_private (object_class, sizeof(GitgLineParserPrivate));
|
||||
|
||||
signals[LINES] =
|
||||
g_signal_new ("lines",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_POINTER);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_ERROR);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_BUFFER_SIZE,
|
||||
g_param_spec_uint ("buffer-size",
|
||||
"Buffer size",
|
||||
"Buffer Size",
|
||||
1,
|
||||
G_MAXUINT,
|
||||
100,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PRESERVE_LINE_ENDINGS,
|
||||
g_param_spec_boolean ("preserve-line-endings",
|
||||
"Preserve line endings",
|
||||
"Preserve Line Endings",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
gitg_line_parser_init (GitgLineParser *self)
|
||||
{
|
||||
self->priv = GITG_LINE_PARSER_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
GitgLineParser *
|
||||
gitg_line_parser_new (guint buffer_size,
|
||||
gboolean preserve_line_endings)
|
||||
{
|
||||
return g_object_new (GITG_TYPE_LINE_PARSER,
|
||||
"buffer-size", buffer_size,
|
||||
"preserve-line-endings", preserve_line_endings,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gitg_line_parser_parse (GitgLineParser *parser,
|
||||
GInputStream *stream,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
AsyncData *data;
|
||||
|
||||
g_return_if_fail (GITG_IS_LINE_PARSER (parser));
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
data = async_data_new (parser, stream, cancellable);
|
||||
start_read_lines (data);
|
||||
}
|
45
libgitg/gitg-line-parser.h
Normal file
45
libgitg/gitg-line-parser.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef __GITG_LINE_PARSER_H__
|
||||
#define __GITG_LINE_PARSER_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_LINE_PARSER (gitg_line_parser_get_type ())
|
||||
#define GITG_LINE_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_LINE_PARSER, GitgLineParser))
|
||||
#define GITG_LINE_PARSER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_LINE_PARSER, GitgLineParser const))
|
||||
#define GITG_LINE_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_LINE_PARSER, GitgLineParserClass))
|
||||
#define GITG_IS_LINE_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_LINE_PARSER))
|
||||
#define GITG_IS_LINE_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_LINE_PARSER))
|
||||
#define GITG_LINE_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_LINE_PARSER, GitgLineParserClass))
|
||||
|
||||
typedef struct _GitgLineParser GitgLineParser;
|
||||
typedef struct _GitgLineParserClass GitgLineParserClass;
|
||||
typedef struct _GitgLineParserPrivate GitgLineParserPrivate;
|
||||
|
||||
struct _GitgLineParser
|
||||
{
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
|
||||
GitgLineParserPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GitgLineParserClass
|
||||
{
|
||||
/*< private >*/
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gitg_line_parser_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GitgLineParser *gitg_line_parser_new (guint buffer_size,
|
||||
gboolean preserve_line_endings);
|
||||
|
||||
void gitg_line_parser_parse (GitgLineParser *parser,
|
||||
GInputStream *stream,
|
||||
GCancellable *cancellable);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GITG_LINE_PARSER_H__ */
|
|
@ -26,6 +26,7 @@
|
|||
#include "gitg-lanes.h"
|
||||
#include "gitg-ref.h"
|
||||
#include "gitg-config.h"
|
||||
#include "gitg-shell.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -91,7 +92,7 @@ struct _GitgRepositoryPrivate
|
|||
GFile *git_dir;
|
||||
GFile *work_tree;
|
||||
|
||||
GitgRunner *loader;
|
||||
GitgShell *loader;
|
||||
GHashTable *hashtable;
|
||||
gint stamp;
|
||||
GType column_types[N_COLUMNS];
|
||||
|
@ -416,7 +417,7 @@ gitg_repository_finalize (GObject *object)
|
|||
GitgRepository *rp = GITG_REPOSITORY (object);
|
||||
|
||||
/* Make sure to cancel the loader */
|
||||
gitg_runner_cancel (rp->priv->loader);
|
||||
gitg_io_cancel (GITG_IO (rp->priv->loader));
|
||||
g_object_unref (rp->priv->loader);
|
||||
|
||||
g_object_unref (rp->priv->lanes);
|
||||
|
@ -610,16 +611,19 @@ parse_ref_intern (GitgRepository *repository,
|
|||
gchar const *ref,
|
||||
gboolean symbolic)
|
||||
{
|
||||
gchar **ret = gitg_repository_command_with_outputv (repository,
|
||||
NULL,
|
||||
"rev-parse",
|
||||
"--verify",
|
||||
symbolic ? "--symbolic-full-name" : ref,
|
||||
symbolic ? ref : NULL,
|
||||
NULL);
|
||||
gchar **ret = gitg_shell_run_sync_with_output (gitg_command_newv (repository,
|
||||
"rev-parse",
|
||||
"--verify",
|
||||
symbolic ? "--symbolic-full-name" : ref,
|
||||
symbolic ? ref : NULL,
|
||||
NULL),
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gchar *r = g_strdup (*ret);
|
||||
g_strfreev (ret);
|
||||
|
@ -748,7 +752,7 @@ gitg_repository_class_init (GitgRepositoryClass *klass)
|
|||
g_param_spec_object ("loader",
|
||||
"LOADER",
|
||||
"The repository loader",
|
||||
GITG_TYPE_RUNNER,
|
||||
GITG_TYPE_SHELL,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
|
@ -902,11 +906,11 @@ add_dummy_commit (GitgRepository *repository,
|
|||
}
|
||||
|
||||
static void
|
||||
on_loader_end_loading (GitgRunner *object,
|
||||
gboolean cancelled,
|
||||
on_loader_end_loading (GitgShell *object,
|
||||
GError *error,
|
||||
GitgRepository *repository)
|
||||
{
|
||||
if (cancelled)
|
||||
if (gitg_io_get_cancelled (GITG_IO (object)))
|
||||
{
|
||||
g_signal_emit (repository, repository_signals[LOADED], 0);
|
||||
return;
|
||||
|
@ -931,7 +935,7 @@ on_loader_end_loading (GitgRunner *object,
|
|||
if (current == LOAD_STAGE_STAGED)
|
||||
{
|
||||
/* Check if there are unstaged changes */
|
||||
if (show_staged && gitg_runner_get_exit_status (object) != 0)
|
||||
if (show_staged && gitg_io_get_exit_status (GITG_IO (object)) != 0)
|
||||
{
|
||||
add_dummy_commit (repository, TRUE);
|
||||
}
|
||||
|
@ -941,28 +945,29 @@ on_loader_end_loading (GitgRunner *object,
|
|||
cached = "--cached";
|
||||
}
|
||||
|
||||
gitg_repository_run_commandv (repository,
|
||||
object,
|
||||
NULL,
|
||||
"diff-index",
|
||||
"--quiet",
|
||||
head,
|
||||
cached,
|
||||
NULL);
|
||||
gitg_shell_run (object,
|
||||
gitg_command_newv (repository,
|
||||
"diff-index",
|
||||
"--no-ext-diff",
|
||||
"--quiet",
|
||||
head,
|
||||
cached,
|
||||
NULL),
|
||||
NULL);
|
||||
|
||||
g_free (head);
|
||||
}
|
||||
break;
|
||||
case LOAD_STAGE_UNSTAGED:
|
||||
if (show_unstaged && gitg_runner_get_exit_status (object) != 0)
|
||||
if (show_unstaged && gitg_io_get_exit_status (GITG_IO (object)) != 0)
|
||||
{
|
||||
add_dummy_commit (repository, FALSE);
|
||||
}
|
||||
|
||||
gitg_repository_run_command (repository,
|
||||
object,
|
||||
(gchar const **)repository->priv->last_args,
|
||||
NULL);
|
||||
|
||||
gitg_shell_run (object,
|
||||
gitg_command_new (repository,
|
||||
(gchar const * const *)repository->priv->last_args),
|
||||
NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1106,7 +1111,7 @@ loader_update_commits (GitgRepository *self,
|
|||
}
|
||||
|
||||
static void
|
||||
on_loader_update (GitgRunner *object,
|
||||
on_loader_update (GitgShell *object,
|
||||
gchar **buffer,
|
||||
GitgRepository *repository)
|
||||
{
|
||||
|
@ -1294,7 +1299,7 @@ gitg_repository_init (GitgRepository *object)
|
|||
NULL,
|
||||
(GDestroyNotify)free_refs);
|
||||
|
||||
object->priv->loader = gitg_runner_new (10000);
|
||||
object->priv->loader = gitg_shell_new (10000);
|
||||
|
||||
g_signal_connect (object->priv->loader,
|
||||
"update",
|
||||
|
@ -1302,7 +1307,7 @@ gitg_repository_init (GitgRepository *object)
|
|||
object);
|
||||
|
||||
g_signal_connect (object->priv->loader,
|
||||
"end-loading",
|
||||
"end",
|
||||
G_CALLBACK (on_loader_end_loading),
|
||||
object);
|
||||
}
|
||||
|
@ -1361,11 +1366,11 @@ gitg_repository_get_git_dir (GitgRepository *self)
|
|||
return g_file_dup (self->priv->git_dir);
|
||||
}
|
||||
|
||||
GitgRunner *
|
||||
GitgShell *
|
||||
gitg_repository_get_loader (GitgRepository *self)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (self), NULL);
|
||||
return GITG_RUNNER (g_object_ref (self->priv->loader));
|
||||
return GITG_SHELL (g_object_ref (self->priv->loader));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -1382,15 +1387,15 @@ reload_revisions (GitgRepository *repository,
|
|||
|
||||
repository->priv->load_stage = LOAD_STAGE_STASH;
|
||||
|
||||
return gitg_repository_run_commandv (repository,
|
||||
repository->priv->loader,
|
||||
error,
|
||||
"log",
|
||||
"--pretty=format:%H\x01%an\x01%ae\x01%at\x01%s",
|
||||
"--encoding=UTF-8",
|
||||
"-g",
|
||||
"refs/stash",
|
||||
NULL);
|
||||
return gitg_shell_run (repository->priv->loader,
|
||||
gitg_command_newv (repository,
|
||||
"log",
|
||||
"--pretty=format:%H\x01%an\x01%ae\x01%at\x01%s",
|
||||
"--encoding=UTF-8",
|
||||
"-g",
|
||||
"refs/stash",
|
||||
NULL),
|
||||
error);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -1402,7 +1407,9 @@ load_current_ref (GitgRepository *self)
|
|||
gint numargs;
|
||||
|
||||
if (self->priv->last_args == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
numargs = g_strv_length (self->priv->last_args);
|
||||
|
||||
|
@ -1417,14 +1424,16 @@ load_current_ref (GitgRepository *self)
|
|||
argv[2 + i] = self->priv->last_args[i];
|
||||
}
|
||||
|
||||
out = gitg_repository_command_with_output (self, argv, NULL);
|
||||
out = gitg_shell_run_sync_with_output (gitg_command_new (self, argv),
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (!out)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*out && !* (out + 1))
|
||||
if (*out && !*(out + 1))
|
||||
{
|
||||
ret = g_strdup (*out);
|
||||
}
|
||||
|
@ -1438,12 +1447,13 @@ load_refs (GitgRepository *self)
|
|||
{
|
||||
gchar **refs;
|
||||
|
||||
refs = gitg_repository_command_with_outputv (self,
|
||||
NULL,
|
||||
"for-each-ref",
|
||||
"--format=%(refname) %(objectname) %(*objectname)",
|
||||
"refs",
|
||||
NULL);
|
||||
refs = gitg_shell_run_sync_with_output (gitg_command_newv (self,
|
||||
"for-each-ref",
|
||||
"--format=%(refname) %(objectname) %(*objectname)",
|
||||
"refs",
|
||||
NULL),
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
if (!refs)
|
||||
{
|
||||
|
@ -1491,7 +1501,7 @@ gitg_repository_reload (GitgRepository *repository)
|
|||
g_return_if_fail (GITG_IS_REPOSITORY (repository));
|
||||
g_return_if_fail (repository->priv->git_dir != NULL);
|
||||
|
||||
gitg_runner_cancel (repository->priv->loader);
|
||||
gitg_io_cancel (GITG_IO (repository->priv->loader));
|
||||
|
||||
repository->priv->load_stage = LOAD_STAGE_NONE;
|
||||
gitg_repository_clear (repository);
|
||||
|
@ -1520,7 +1530,7 @@ gitg_repository_load (GitgRepository *self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gitg_runner_cancel (self->priv->loader);
|
||||
gitg_io_cancel (GITG_IO (self->priv->loader));
|
||||
gitg_repository_clear (self);
|
||||
|
||||
build_log_args (self, argc, av);
|
||||
|
@ -1622,6 +1632,24 @@ gitg_repository_find (GitgRepository *store,
|
|||
iter);
|
||||
}
|
||||
|
||||
static gint
|
||||
ref_compare (GitgRef *a,
|
||||
GitgRef *b)
|
||||
{
|
||||
GitgRefType t1 = gitg_ref_get_ref_type (a);
|
||||
GitgRefType t2 = gitg_ref_get_ref_type (b);
|
||||
|
||||
if (t1 != t2)
|
||||
{
|
||||
return t1 < t2 ? -1 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return g_strcmp0 (gitg_ref_get_shortname (a),
|
||||
gitg_ref_get_shortname (b));
|
||||
}
|
||||
}
|
||||
|
||||
GSList *
|
||||
gitg_repository_get_refs (GitgRepository *repository)
|
||||
{
|
||||
|
@ -1635,13 +1663,14 @@ gitg_repository_get_refs (GitgRepository *repository)
|
|||
{
|
||||
GSList *val;
|
||||
|
||||
for (val = (GSList *)item->data; val; val = val->next)
|
||||
for (val = item->data; val; val = val->next)
|
||||
{
|
||||
ret = g_slist_prepend (ret, gitg_ref_copy ( (GitgRef *)val->data));
|
||||
ret = g_slist_insert_sorted (ret,
|
||||
gitg_ref_copy (val->data),
|
||||
(GCompareFunc)ref_compare);
|
||||
}
|
||||
}
|
||||
|
||||
ret = g_slist_reverse (ret);
|
||||
g_list_free (values);
|
||||
|
||||
return ret;
|
||||
|
@ -1673,297 +1702,6 @@ gitg_repository_relative (GitgRepository *repository,
|
|||
return g_file_get_relative_path (repository->priv->work_tree, file);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_run_command_with_input (GitgRepository *repository,
|
||||
GitgRunner *runner,
|
||||
gchar const **argv,
|
||||
gchar const *input,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
|
||||
g_return_val_if_fail (GITG_IS_RUNNER (runner), FALSE);
|
||||
g_return_val_if_fail (repository->priv->git_dir != NULL, FALSE);
|
||||
|
||||
guint num = g_strv_length ( (gchar **)argv);
|
||||
guint i;
|
||||
|
||||
gchar const **args = g_new0 (gchar const *, num + 6);
|
||||
|
||||
gchar *git_dir_path = g_file_get_path (repository->priv->git_dir);
|
||||
gchar *work_tree_path = g_file_get_path (repository->priv->work_tree);
|
||||
|
||||
args[0] = "git";
|
||||
args[1] = "--git-dir";
|
||||
args[2] = git_dir_path;
|
||||
args[3] = "--work-tree";
|
||||
args[4] = work_tree_path;
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
{
|
||||
args[i + 5] = argv[i];
|
||||
}
|
||||
|
||||
gboolean ret = gitg_runner_run_with_arguments (runner,
|
||||
repository->priv->work_tree,
|
||||
args,
|
||||
input,
|
||||
error);
|
||||
|
||||
g_free (args);
|
||||
g_free (git_dir_path);
|
||||
g_free (work_tree_path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_run_command (GitgRepository *repository,
|
||||
GitgRunner *runner,
|
||||
gchar const **argv,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
|
||||
g_return_val_if_fail (GITG_IS_RUNNER (runner), FALSE);
|
||||
g_return_val_if_fail (repository->priv->git_dir != NULL, FALSE);
|
||||
|
||||
return gitg_repository_run_command_with_input (repository,
|
||||
runner,
|
||||
argv,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_command_with_input (GitgRepository *repository,
|
||||
gchar const **argv,
|
||||
gchar const *input,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
|
||||
g_return_val_if_fail (repository->priv->git_dir != NULL, FALSE);
|
||||
|
||||
GitgRunner *runner = gitg_runner_new_synchronized (1000);
|
||||
|
||||
gboolean ret = gitg_repository_run_command_with_input (repository,
|
||||
runner,
|
||||
argv,
|
||||
input,
|
||||
error);
|
||||
g_object_unref (runner);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_command (GitgRepository *repository,
|
||||
gchar const **argv,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
|
||||
g_return_val_if_fail (repository->priv->git_dir != NULL, FALSE);
|
||||
|
||||
return gitg_repository_command_with_input (repository,
|
||||
argv,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar **buffer;
|
||||
guint size;
|
||||
} CommandOutput;
|
||||
|
||||
static void
|
||||
command_with_output_update (GitgRunner *runner,
|
||||
gchar **buffer,
|
||||
CommandOutput *output)
|
||||
{
|
||||
guint num = g_strv_length (buffer);
|
||||
guint i;
|
||||
|
||||
output->buffer = g_realloc (output->buffer,
|
||||
sizeof (gchar *) * (output->size + num + 1));
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
{
|
||||
output->buffer[output->size + i] = g_strdup (buffer[i]);
|
||||
}
|
||||
|
||||
output->size += num;
|
||||
output->buffer[output->size] = NULL;
|
||||
}
|
||||
|
||||
gchar **
|
||||
gitg_repository_command_with_input_and_output (GitgRepository *repository,
|
||||
gchar const **argv,
|
||||
gchar const *input,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
|
||||
g_return_val_if_fail (repository->priv->git_dir != NULL, NULL);
|
||||
|
||||
GitgRunner *runner = gitg_runner_new_synchronized (1000);
|
||||
CommandOutput output = {NULL, 0};
|
||||
|
||||
g_signal_connect (runner, "update", G_CALLBACK (command_with_output_update), &output);
|
||||
gboolean ret = gitg_repository_run_command_with_input (repository,
|
||||
runner,
|
||||
argv,
|
||||
input,
|
||||
error);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
g_strfreev (output.buffer);
|
||||
output.buffer = NULL;
|
||||
}
|
||||
|
||||
g_object_unref (runner);
|
||||
return output.buffer;
|
||||
}
|
||||
|
||||
gchar **
|
||||
gitg_repository_command_with_output (GitgRepository *repository,
|
||||
gchar const **argv,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), NULL);
|
||||
g_return_val_if_fail (repository->priv->git_dir != NULL, NULL);
|
||||
|
||||
return gitg_repository_command_with_input_and_output (repository,
|
||||
argv,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
static gchar const **
|
||||
parse_valist (va_list ap)
|
||||
{
|
||||
gchar const *a;
|
||||
gchar const **ret = NULL;
|
||||
guint num = 0;
|
||||
|
||||
while ( (a = va_arg (ap, gchar const *)) != NULL)
|
||||
{
|
||||
ret = g_realloc (ret, sizeof (gchar const *) * (++num + 1));
|
||||
ret[num - 1] = a;
|
||||
}
|
||||
|
||||
ret[num] = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_commandv (GitgRepository *repository,
|
||||
GError **error,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, error);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
va_end (ap);
|
||||
|
||||
gboolean ret = gitg_repository_command (repository, argv, error);
|
||||
g_free (argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_command_with_inputv (GitgRepository *repository,
|
||||
gchar const *input,
|
||||
GError **error,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, error);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
va_end (ap);
|
||||
|
||||
gboolean ret = gitg_repository_command_with_input (repository,
|
||||
argv,
|
||||
input,
|
||||
error);
|
||||
g_free (argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_run_commandv (GitgRepository *repository,
|
||||
GitgRunner *runner,
|
||||
GError **error,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, error);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
va_end (ap);
|
||||
|
||||
gboolean ret = gitg_repository_run_command (repository,
|
||||
runner,
|
||||
argv,
|
||||
error);
|
||||
g_free (argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gitg_repository_run_command_with_inputv (GitgRepository *repository,
|
||||
GitgRunner *runner,
|
||||
gchar const *input,
|
||||
GError **error,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, error);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
va_end (ap);
|
||||
|
||||
gboolean ret = gitg_repository_run_command_with_input (repository,
|
||||
runner,
|
||||
argv,
|
||||
input,
|
||||
error);
|
||||
g_free (argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar **
|
||||
gitg_repository_command_with_outputv (GitgRepository *repository,
|
||||
GError **error,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, error);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
va_end (ap);
|
||||
|
||||
gchar **ret = gitg_repository_command_with_output (repository,
|
||||
argv,
|
||||
error);
|
||||
g_free (argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar **
|
||||
gitg_repository_command_with_input_and_outputv (GitgRepository *repository,
|
||||
gchar const *input,
|
||||
GError **error,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, error);
|
||||
gchar const **argv = parse_valist (ap);
|
||||
va_end (ap);
|
||||
|
||||
gchar **ret = gitg_repository_command_with_input_and_output (repository,
|
||||
argv,
|
||||
input,
|
||||
error);
|
||||
g_free (argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gitg_repository_parse_ref (GitgRepository *repository,
|
||||
gchar const *ref)
|
||||
|
@ -2148,8 +1886,9 @@ gboolean
|
|||
gitg_repository_get_loaded (GitgRepository *repository)
|
||||
{
|
||||
g_return_val_if_fail (GITG_IS_REPOSITORY (repository), FALSE);
|
||||
|
||||
return repository->priv->load_stage == LOAD_STAGE_LAST &&
|
||||
!gitg_runner_running (repository->priv->loader);
|
||||
!gitg_io_get_running (GITG_IO (repository->priv->loader));
|
||||
}
|
||||
|
||||
gchar const **
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libgitg/gitg-revision.h>
|
||||
#include <libgitg/gitg-runner.h>
|
||||
#include <libgitg/gitg-ref.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -43,7 +42,9 @@ typedef struct _GitgRepository GitgRepository;
|
|||
typedef struct _GitgRepositoryClass GitgRepositoryClass;
|
||||
typedef struct _GitgRepositoryPrivate GitgRepositoryPrivate;
|
||||
|
||||
typedef enum
|
||||
struct _GitgShell;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GITG_REPOSITORY_NO_ERROR = 0,
|
||||
GITG_REPOSITORY_ERROR_NOT_FOUND
|
||||
|
@ -74,8 +75,6 @@ GFile *gitg_repository_get_git_dir (GitgRepository *repository);
|
|||
|
||||
gboolean gitg_repository_exists (GitgRepository *repository);
|
||||
|
||||
GitgRunner *gitg_repository_get_loader(GitgRepository *repository);
|
||||
|
||||
gboolean gitg_repository_load(GitgRepository *repository, int argc, gchar const **argv, GError **error);
|
||||
gboolean gitg_repository_get_loaded(GitgRepository *repository);
|
||||
|
||||
|
@ -93,30 +92,13 @@ GitgRef *gitg_repository_get_current_working_ref(GitgRepository *repository);
|
|||
|
||||
gchar *gitg_repository_relative(GitgRepository *repository, GFile *file);
|
||||
|
||||
/* Running git commands */
|
||||
gboolean gitg_repository_run_command(GitgRepository *repository, GitgRunner *runner, gchar const **argv, GError **error);
|
||||
gboolean gitg_repository_run_commandv(GitgRepository *repository, GitgRunner *runner, GError **error, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gboolean gitg_repository_run_command_with_input(GitgRepository *repository, GitgRunner *runner, gchar const **argv, gchar const *input, GError **error);
|
||||
gboolean gitg_repository_run_command_with_inputv(GitgRepository *repository, GitgRunner *runner, gchar const *input, GError **error, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gboolean gitg_repository_command_with_input(GitgRepository *repository, gchar const **argv, gchar const *input, GError **error);
|
||||
gboolean gitg_repository_command_with_inputv(GitgRepository *repository, gchar const *input, GError **error, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gboolean gitg_repository_command(GitgRepository *repository, gchar const **argv, GError **error);
|
||||
gboolean gitg_repository_commandv(GitgRepository *repository, GError **error, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar **gitg_repository_command_with_output(GitgRepository *repository, gchar const **argv, GError **error);
|
||||
gchar **gitg_repository_command_with_outputv(GitgRepository *repository, GError **error, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar **gitg_repository_command_with_input_and_output(GitgRepository *repository, gchar const **argv, gchar const *input, GError **error);
|
||||
gchar **gitg_repository_command_with_input_and_outputv(GitgRepository *repository, gchar const *input, GError **error, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar *gitg_repository_parse_ref(GitgRepository *repository, gchar const *ref);
|
||||
gchar *gitg_repository_parse_head(GitgRepository *repository);
|
||||
|
||||
void gitg_repository_reload(GitgRepository *repository);
|
||||
|
||||
struct _GitgShell *gitg_repository_get_loader (GitgRepository *repository);
|
||||
|
||||
gchar **gitg_repository_get_remotes (GitgRepository *repository);
|
||||
GSList const *gitg_repository_get_ref_pushes (GitgRepository *repository, GitgRef *ref);
|
||||
gchar const **gitg_repository_get_current_selection (GitgRepository *repository);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,102 +1,53 @@
|
|||
/*
|
||||
* gitg-runner.h
|
||||
* This file is part of gitg - git repository viewer
|
||||
*
|
||||
* Copyright (C) 2009 - Jesse van den Kieboom
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GITG_RUNNER_H__
|
||||
#define __GITG_RUNNER_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <libgitg/gitg-command.h>
|
||||
#include <libgitg/gitg-io.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_RUNNER (gitg_runner_get_type ())
|
||||
#define GITG_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RUNNER, GitgRunner))
|
||||
#define GITG_TYPE_RUNNER (gitg_runner_get_type ())
|
||||
#define GITG_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RUNNER, GitgRunner))
|
||||
#define GITG_RUNNER_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_RUNNER, GitgRunner const))
|
||||
#define GITG_RUNNER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_RUNNER, GitgRunnerClass))
|
||||
#define GITG_IS_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_RUNNER))
|
||||
#define GITG_IS_RUNNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_RUNNER))
|
||||
#define GITG_IS_RUNNER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_RUNNER))
|
||||
#define GITG_RUNNER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_RUNNER, GitgRunnerClass))
|
||||
|
||||
#define GITG_RUNNER_ERROR (gitg_runner_error_quark())
|
||||
|
||||
typedef struct _GitgRunner GitgRunner;
|
||||
typedef struct _GitgRunner GitgRunner;
|
||||
typedef struct _GitgRunnerClass GitgRunnerClass;
|
||||
typedef struct _GitgRunnerPrivate GitgRunnerPrivate;
|
||||
|
||||
typedef enum
|
||||
struct _GitgRunner
|
||||
{
|
||||
GITG_RUNNER_ERROR_NONE = 0,
|
||||
GITG_RUNNER_ERROR_EXIT
|
||||
} GitgRunnerError;
|
||||
|
||||
struct _GitgRunner {
|
||||
GObject parent;
|
||||
/*< private >*/
|
||||
GitgIO parent;
|
||||
|
||||
GitgRunnerPrivate *priv;
|
||||
|
||||
/*< public >*/
|
||||
};
|
||||
|
||||
struct _GitgRunnerClass {
|
||||
GObjectClass parent_class;
|
||||
struct _GitgRunnerClass
|
||||
{
|
||||
/*< private >*/
|
||||
GitgIOClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* begin_loading) (GitgRunner *runner);
|
||||
void (* update) (GitgRunner *runner, gchar **buffer);
|
||||
void (* end_loading) (GitgRunner *runner, gboolean cancelled);
|
||||
/*< public >*/
|
||||
};
|
||||
|
||||
GType gitg_runner_get_type (void) G_GNUC_CONST;
|
||||
GitgRunner *gitg_runner_new (guint buffer_size);
|
||||
GitgRunner *gitg_runner_new_synchronized (guint buffer_size);
|
||||
GitgRunner *gitg_runner_new (GitgCommand *command);
|
||||
|
||||
guint gitg_runner_get_buffer_size (GitgRunner *runner);
|
||||
void gitg_runner_run (GitgRunner *runner);
|
||||
|
||||
gboolean gitg_runner_run_stream (GitgRunner *runner,
|
||||
GInputStream *stream,
|
||||
GError **error);
|
||||
GitgCommand *gitg_runner_get_command (GitgRunner *runner);
|
||||
void gitg_runner_set_command (GitgRunner *runner, GitgCommand *command);
|
||||
|
||||
gboolean gitg_runner_run_with_arguments (GitgRunner *runner,
|
||||
GFile *work_tree,
|
||||
gchar const **argv,
|
||||
gchar const *input,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_runner_run (GitgRunner *runner,
|
||||
gchar const **argv,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_runner_running (GitgRunner *runner);
|
||||
|
||||
gint gitg_runner_get_exit_status (GitgRunner *runner);
|
||||
void gitg_runner_cancel (GitgRunner *runner);
|
||||
|
||||
void gitg_runner_set_environment (GitgRunner *runner, gchar const **environment);
|
||||
void gitg_runner_add_environment (GitgRunner *runner, gchar const *key, gchar const *value);
|
||||
|
||||
void gitg_runner_set_preserve_line_endings (GitgRunner *runner,
|
||||
gboolean preserve_line_endings);
|
||||
|
||||
gboolean gitg_runner_get_preserve_line_endings (GitgRunner *runner);
|
||||
|
||||
GQuark gitg_runner_error_quark (void);
|
||||
GInputStream *gitg_runner_get_stream (GitgRunner *runner);
|
||||
void gitg_runner_stream_close (GitgRunner *runner, GError *error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
1052
libgitg/gitg-shell.c
Normal file
1052
libgitg/gitg-shell.c
Normal file
File diff suppressed because it is too large
Load diff
153
libgitg/gitg-shell.h
Normal file
153
libgitg/gitg-shell.h
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* gitg-shell.h
|
||||
* This file is part of gitg - git repository viewer
|
||||
*
|
||||
* Copyright (C) 2009 - Jesse van den Kieboom
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GITG_SHELL_H__
|
||||
#define __GITG_SHELL_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <libgitg/gitg-io.h>
|
||||
#include <libgitg/gitg-command.h>
|
||||
#include <libgitg/gitg-repository.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GITG_TYPE_SHELL (gitg_shell_get_type ())
|
||||
#define GITG_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_SHELL, GitgShell))
|
||||
#define GITG_SHELL_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GITG_TYPE_SHELL, GitgShell const))
|
||||
#define GITG_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GITG_TYPE_SHELL, GitgShellClass))
|
||||
#define GITG_IS_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GITG_TYPE_SHELL))
|
||||
#define GITG_IS_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GITG_TYPE_SHELL))
|
||||
#define GITG_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GITG_TYPE_SHELL, GitgShellClass))
|
||||
|
||||
#define GITG_SHELL_ERROR (gitg_shell_error_quark())
|
||||
|
||||
typedef struct _GitgShell GitgShell;
|
||||
typedef struct _GitgShellClass GitgShellClass;
|
||||
typedef struct _GitgShellPrivate GitgShellPrivate;
|
||||
|
||||
struct _GitgShell
|
||||
{
|
||||
GitgIO parent;
|
||||
|
||||
GitgShellPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GitgShellClass
|
||||
{
|
||||
GitgIOClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (* update) (GitgShell *shell,
|
||||
gchar const * const *buffer);
|
||||
};
|
||||
|
||||
GType gitg_shell_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GitgShell *gitg_shell_new (guint buffer_size);
|
||||
GitgShell *gitg_shell_new_synchronized (guint buffer_size);
|
||||
|
||||
void gitg_shell_set_preserve_line_endings (GitgShell *shell,
|
||||
gboolean preserve_line_endings);
|
||||
gboolean gitg_shell_get_preserve_line_endings (GitgShell *shell);
|
||||
|
||||
guint gitg_shell_get_buffer_size (GitgShell *shell);
|
||||
|
||||
GitgCommand **gitg_shell_parse_commands (GitgRepository *repository,
|
||||
const gchar *cmdstr,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_parse (GitgShell *shell,
|
||||
GitgRepository *repository,
|
||||
const gchar *cmd,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_runva (GitgShell *shell,
|
||||
va_list ap,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_stream (GitgShell *shell,
|
||||
GInputStream *stream,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run (GitgShell *shell,
|
||||
GitgCommand *command,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_list (GitgShell *shell,
|
||||
GitgCommand **commands,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_runv (GitgShell *shell,
|
||||
GError **error,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar **gitg_shell_run_sync_with_output (GitgCommand *command,
|
||||
gboolean preserve_line_endings,
|
||||
GError **error);
|
||||
|
||||
gchar **gitg_shell_run_sync_with_output_list (GitgCommand **commands,
|
||||
gboolean preserve_line_endings,
|
||||
GError **error);
|
||||
|
||||
gchar **gitg_shell_run_sync_with_outputv (gboolean preserve_line_endings,
|
||||
GError **error,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gboolean gitg_shell_run_sync (GitgCommand *command,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_sync_list (GitgCommand **commands,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_syncv (GError **error,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gboolean gitg_shell_run_sync_with_input (GitgCommand *command,
|
||||
const gchar *input,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_sync_with_input_list (GitgCommand **commands,
|
||||
const gchar *input,
|
||||
GError **error);
|
||||
|
||||
gboolean gitg_shell_run_sync_with_inputv (const gchar *input,
|
||||
GError **error,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gchar **gitg_shell_run_sync_with_input_and_output (GitgCommand *command,
|
||||
gboolean preserve_line_endings,
|
||||
const gchar *input,
|
||||
GError **error);
|
||||
|
||||
gchar **gitg_shell_run_sync_with_input_and_output_list (GitgCommand **commands,
|
||||
gboolean preserve_line_endings,
|
||||
const gchar *input,
|
||||
GError **error);
|
||||
|
||||
gchar **gitg_shell_run_sync_with_input_and_outputv (gboolean preserve_line_endings,
|
||||
const gchar *input,
|
||||
GError **error,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GITG_SHELL_H__ */
|
12
tests/Makefile.am
Normal file
12
tests/Makefile.am
Normal file
|
@ -0,0 +1,12 @@
|
|||
INCLUDES = -g -I$(top_srcdir) -I$(top_srcdir)/gitg -I$(top_srcdir)/libgitg $(GITG_DEBUG_FLAGS) $(GITG_CFLAGS)
|
||||
|
||||
noinst_PROGRAMS = $(TEST_PROGS)
|
||||
progs_ldadd = $(top_builddir)/libgitg/libgitg-1.0.la
|
||||
|
||||
TEST_PROGS = shell
|
||||
shell_SOURCES = shell.c
|
||||
shell_LDADD = $(progs_ldadd)
|
||||
|
||||
TESTS = $(TEST_PROGS)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
273
tests/shell.c
Normal file
273
tests/shell.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
#include <libgitg/gitg-shell.h>
|
||||
#include <string.h>
|
||||
|
||||
#define test_add_repo(name, callback) g_test_add (name, RepositoryInfo, NULL, repository_setup, callback, repository_cleanup)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GitgRepository *repository;
|
||||
} RepositoryInfo;
|
||||
|
||||
static gboolean
|
||||
remove_all (gchar const *path,
|
||||
GError **error)
|
||||
{
|
||||
gchar const *argv[] = {
|
||||
"rm",
|
||||
"-rf",
|
||||
path,
|
||||
NULL
|
||||
};
|
||||
|
||||
g_spawn_sync ("/",
|
||||
(gchar **)argv,
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH |
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL |
|
||||
G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
static void
|
||||
repository_setup (RepositoryInfo *info,
|
||||
gconstpointer data)
|
||||
{
|
||||
/* Create repository */
|
||||
gchar const *tmp = g_get_tmp_dir ();
|
||||
gchar *repo_path;
|
||||
GError *error = NULL;
|
||||
|
||||
repo_path = g_build_filename (tmp, "gitg-test-repo", NULL);
|
||||
|
||||
if (g_file_test (repo_path, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
remove_all (repo_path, &error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
}
|
||||
|
||||
g_assert (g_mkdir (repo_path, 0700) == 0);
|
||||
|
||||
gchar const *argv[] = {
|
||||
"git",
|
||||
"init",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
g_spawn_sync (repo_path,
|
||||
(gchar **)argv,
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH |
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL |
|
||||
G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
argv[0] = "/bin/bash";
|
||||
argv[1] = "-c";
|
||||
argv[2] = "echo haha > test.txt && git add test.txt && git commit -m 'Initial import'";
|
||||
|
||||
g_spawn_sync (repo_path,
|
||||
(gchar **)argv,
|
||||
NULL,
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL |
|
||||
G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
GFile *work_tree = g_file_new_for_path (repo_path);
|
||||
gchar *git_dir_path = g_build_filename (repo_path, ".git", NULL);
|
||||
GFile *git_dir = g_file_new_for_path (git_dir_path);
|
||||
g_free (git_dir_path);
|
||||
|
||||
info->repository = gitg_repository_new (git_dir, work_tree);
|
||||
|
||||
g_object_unref (work_tree);
|
||||
g_object_unref (git_dir);
|
||||
}
|
||||
|
||||
static void
|
||||
repository_cleanup (RepositoryInfo *info,
|
||||
gconstpointer data)
|
||||
{
|
||||
GFile *work_tree;
|
||||
GError *error = NULL;
|
||||
|
||||
work_tree = gitg_repository_get_work_tree (info->repository);
|
||||
gchar *path = g_file_get_path (work_tree);
|
||||
g_object_unref (work_tree);
|
||||
|
||||
remove_all (path, &error);
|
||||
g_free (path);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_object_unref (info->repository);
|
||||
}
|
||||
|
||||
static void
|
||||
test_success (RepositoryInfo *info,
|
||||
gconstpointer data)
|
||||
{
|
||||
gboolean ret;
|
||||
GError *error = NULL;
|
||||
|
||||
ret = gitg_shell_run_sync (gitg_command_newv (info->repository,
|
||||
"rev-parse",
|
||||
"HEAD",
|
||||
NULL),
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
test_fail (RepositoryInfo *info,
|
||||
gconstpointer data)
|
||||
{
|
||||
gboolean ret;
|
||||
GError *error = NULL;
|
||||
|
||||
ret = gitg_shell_run_sync (gitg_command_newv (info->repository,
|
||||
"bogus",
|
||||
NULL),
|
||||
&error);
|
||||
|
||||
g_assert (!ret);
|
||||
g_assert (error != NULL);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
static void
|
||||
test_output (RepositoryInfo *info,
|
||||
gconstpointer data)
|
||||
{
|
||||
gchar **ret;
|
||||
GError *error = NULL;
|
||||
|
||||
ret = gitg_shell_run_sync_with_output (gitg_command_newv (info->repository,
|
||||
"rev-parse",
|
||||
"HEAD",
|
||||
NULL),
|
||||
FALSE,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
|
||||
g_assert (ret);
|
||||
g_assert (g_strv_length (ret) == 1);
|
||||
|
||||
g_assert (strlen (ret[0]) == 40);
|
||||
}
|
||||
|
||||
static void
|
||||
test_input (void)
|
||||
{
|
||||
gchar **ret;
|
||||
gchar const *input = "Hello world";
|
||||
GError *error = NULL;
|
||||
|
||||
ret = gitg_shell_run_sync_with_input_and_output (gitg_command_newv (NULL,
|
||||
"cat",
|
||||
"-",
|
||||
NULL),
|
||||
FALSE,
|
||||
input,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_assert (g_strv_length (ret) == 1);
|
||||
g_assert_cmpstr (ret[0], ==, input);
|
||||
}
|
||||
|
||||
static void
|
||||
test_pipe (void)
|
||||
{
|
||||
gchar **ret;
|
||||
GError *error = NULL;
|
||||
gchar const *input = "Hello world";
|
||||
|
||||
ret = gitg_shell_run_sync_with_outputv (FALSE,
|
||||
&error,
|
||||
gitg_command_newv (NULL, "echo", input, NULL),
|
||||
gitg_command_newv (NULL, "cat", "-", NULL),
|
||||
NULL);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_assert (g_strv_length (ret) == 1);
|
||||
g_assert_cmpstr (ret[0], ==, input);
|
||||
}
|
||||
|
||||
static void
|
||||
test_pipestr (void)
|
||||
{
|
||||
gchar **ret;
|
||||
GError *error = NULL;
|
||||
gchar const *input = "Hello world";
|
||||
gchar *cmdstr;
|
||||
GitgCommand **commands;
|
||||
|
||||
cmdstr = g_strconcat ("echo '", input, "' | cat -", NULL);
|
||||
|
||||
commands = gitg_shell_parse_commands (NULL, cmdstr, &error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (commands);
|
||||
|
||||
ret = gitg_shell_run_sync_with_output_list (commands,
|
||||
FALSE,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
|
||||
g_assert (g_strv_length (ret) == 1);
|
||||
g_assert_cmpstr (ret[0], ==, input);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_type_init ();
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
gitg_debug_init ();
|
||||
|
||||
test_add_repo ("/shell/success", test_success);
|
||||
test_add_repo ("/shell/fail", test_fail);
|
||||
|
||||
test_add_repo ("/shell/output", test_output);
|
||||
|
||||
g_test_add_func ("/shell/input", test_input);
|
||||
g_test_add_func ("/shell/pipe", test_pipe);
|
||||
g_test_add_func ("/shell/pipestr", test_pipestr);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
/* ex:ts=8:noet: */
|
10
tools/Makefile.am
Normal file
10
tools/Makefile.am
Normal file
|
@ -0,0 +1,10 @@
|
|||
INCLUDES = -g -I$(top_srcdir) -I$(top_srcdir)/gitg -I$(top_srcdir)/libgitg $(GITG_DEBUG_FLAGS) $(GITG_CFLAGS)
|
||||
|
||||
noinst_PROGRAMS = $(TOOLS_PROGS)
|
||||
tools_ldadd = $(top_builddir)/libgitg/libgitg-1.0.la
|
||||
|
||||
TOOLS_PROGS = gitg-shell
|
||||
gitg_shell_SOURCES = gitg-shell.c
|
||||
gitg_shell_LDADD = $(tools_ldadd)
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
206
tools/gitg-shell.c
Normal file
206
tools/gitg-shell.c
Normal file
|
@ -0,0 +1,206 @@
|
|||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <libgitg/gitg-shell.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <libgitg/gitg-debug.h>
|
||||
|
||||
static gchar *repository_path = NULL;
|
||||
|
||||
static GOptionEntry entries[] =
|
||||
{
|
||||
{ "repository", 'r', 0, G_OPTION_ARG_FILENAME, &repository_path, "Repository path" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static GFile *
|
||||
find_git_dir (GFile *work_tree)
|
||||
{
|
||||
GFile *ret;
|
||||
|
||||
work_tree = g_file_dup (work_tree);
|
||||
|
||||
while (work_tree)
|
||||
{
|
||||
ret = g_file_get_child (work_tree, ".git");
|
||||
|
||||
if (g_file_query_exists (ret, NULL))
|
||||
{
|
||||
g_object_unref (work_tree);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
GFile *tmp;
|
||||
|
||||
tmp = g_file_get_parent (work_tree);
|
||||
g_object_unref (work_tree);
|
||||
|
||||
work_tree = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_options (int *argc,
|
||||
char ***argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
|
||||
context = g_option_context_new ("- git shell tool");
|
||||
|
||||
g_option_context_set_ignore_unknown_options (context, TRUE);
|
||||
g_option_context_add_main_entries (context, entries, "gitg");
|
||||
|
||||
if (!g_option_context_parse (context, argc, argv, &error))
|
||||
{
|
||||
g_print ("option parsing failed: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
}
|
||||
|
||||
static void
|
||||
on_shell_end (GitgShell *shell,
|
||||
GError *error,
|
||||
GMainLoop *loop)
|
||||
{
|
||||
g_main_loop_quit (loop);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GitgRepository *repository;
|
||||
GFile *work_tree;
|
||||
GFile *git_dir;
|
||||
gint i;
|
||||
GString *cmdstr;
|
||||
gchar *cs;
|
||||
GitgCommand **commands;
|
||||
GitgShell *shell;
|
||||
GMainLoop *loop;
|
||||
GError *error = NULL;
|
||||
GInputStream *input;
|
||||
GOutputStream *output;
|
||||
|
||||
g_type_init ();
|
||||
|
||||
parse_options (&argc, &argv);
|
||||
|
||||
gitg_debug_init ();
|
||||
|
||||
if (i == 1)
|
||||
{
|
||||
g_print ("Please specify a command...\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!repository_path)
|
||||
{
|
||||
gchar *path;
|
||||
GFile *file;
|
||||
|
||||
path = g_get_current_dir ();
|
||||
file = g_file_new_for_path (path);
|
||||
|
||||
git_dir = find_git_dir (file);
|
||||
g_free (path);
|
||||
g_object_unref (file);
|
||||
|
||||
if (git_dir)
|
||||
{
|
||||
work_tree = g_file_get_parent (git_dir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
work_tree = g_file_new_for_commandline_arg (repository_path);
|
||||
git_dir = find_git_dir (work_tree);
|
||||
}
|
||||
|
||||
if (!git_dir)
|
||||
{
|
||||
g_print ("Could not find git dir...\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
repository = gitg_repository_new (git_dir, work_tree);
|
||||
|
||||
g_object_unref (work_tree);
|
||||
g_object_unref (git_dir);
|
||||
|
||||
cmdstr = g_string_new ("");
|
||||
|
||||
/* Create commands */
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
gchar *quoted;
|
||||
|
||||
if (strcmp (argv[i], "!") == 0)
|
||||
{
|
||||
quoted = g_strdup ("|");
|
||||
}
|
||||
else
|
||||
{
|
||||
quoted = g_shell_quote (argv[i]);
|
||||
}
|
||||
|
||||
if (i != 1)
|
||||
{
|
||||
g_string_append_c (cmdstr, ' ');
|
||||
}
|
||||
|
||||
g_string_append (cmdstr, quoted);
|
||||
}
|
||||
|
||||
cs = g_string_free (cmdstr, FALSE);
|
||||
g_print ("Running: %s\n\n", cs);
|
||||
|
||||
commands = gitg_shell_parse_commands (repository, cs, &error);
|
||||
|
||||
g_free (cs);
|
||||
g_object_unref (repository);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_print ("Could not parse arguments: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
shell = gitg_shell_new (1000);
|
||||
|
||||
input = g_unix_input_stream_new (STDIN_FILENO, TRUE);
|
||||
output = g_unix_output_stream_new (STDOUT_FILENO, TRUE);
|
||||
|
||||
gitg_io_set_input (GITG_IO (shell), input);
|
||||
gitg_io_set_output (GITG_IO (shell), output);
|
||||
|
||||
g_signal_connect (shell,
|
||||
"end",
|
||||
G_CALLBACK (on_shell_end),
|
||||
loop);
|
||||
|
||||
if (!gitg_shell_run_list (shell, commands, &error))
|
||||
{
|
||||
g_print ("Error launching shell: %s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_free (commands);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
g_main_loop_unref (loop);
|
||||
g_object_unref (shell);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue