changed the refresh hotkey
[giggle.git] / libgiggle / giggle-git-diff.c
blobe7075863804deb457eeeedfde0491f2a90c527ad
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2007 Imendio AB
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include <config.h>
23 #include "giggle-git-diff.h"
25 typedef struct GiggleGitDiffPriv GiggleGitDiffPriv;
27 struct GiggleGitDiffPriv {
28 GiggleRevision *rev1;
29 GiggleRevision *rev2;
31 GList *files;
32 GiggleRevision *patch_format;
34 gchar *result;
37 static void git_diff_finalize (GObject *object);
38 static void git_diff_get_property (GObject *object,
39 guint param_id,
40 GValue *value,
41 GParamSpec *pspec);
42 static void git_diff_set_property (GObject *object,
43 guint param_id,
44 const GValue *value,
45 GParamSpec *pspec);
47 static gboolean git_diff_get_command_line (GiggleJob *job,
48 gchar **command_line);
49 static void git_diff_handle_output (GiggleJob *job,
50 const gchar *output_str,
51 gsize output_len);
53 G_DEFINE_TYPE (GiggleGitDiff, giggle_git_diff, GIGGLE_TYPE_JOB)
55 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GIGGLE_TYPE_GIT_DIFF, GiggleGitDiffPriv))
57 enum {
58 PROP_0,
59 PROP_REV1,
60 PROP_REV2,
61 PROP_FILES,
62 PROP_PATCH_FORMAT
65 static void
66 giggle_git_diff_class_init (GiggleGitDiffClass *class)
68 GObjectClass *object_class = G_OBJECT_CLASS (class);
69 GiggleJobClass *job_class = GIGGLE_JOB_CLASS (class);
71 object_class->finalize = git_diff_finalize;
72 object_class->get_property = git_diff_get_property;
73 object_class->set_property = git_diff_set_property;
75 job_class->get_command_line = git_diff_get_command_line;
76 job_class->handle_output = git_diff_handle_output;
78 g_object_class_install_property (object_class,
79 PROP_REV1,
80 g_param_spec_object ("revision1",
81 "Revision 1",
82 "Revision 1 to make diff on",
83 GIGGLE_TYPE_REVISION,
84 G_PARAM_READWRITE));
85 g_object_class_install_property (object_class,
86 PROP_REV2,
87 g_param_spec_object ("revision2",
88 "Revision 2",
89 "Revision 2 to make diff on",
90 GIGGLE_TYPE_REVISION,
91 G_PARAM_READWRITE));
92 g_object_class_install_property (object_class,
93 PROP_FILES,
94 g_param_spec_pointer ("files",
95 "Files",
96 "Files list to make diff on",
97 G_PARAM_READWRITE));
98 g_object_class_install_property (object_class,
99 PROP_PATCH_FORMAT,
100 g_param_spec_object ("patch-format",
101 "Patch format",
102 "The revision to output a patch format for",
103 GIGGLE_TYPE_REVISION,
104 G_PARAM_READWRITE));
106 g_type_class_add_private (object_class, sizeof (GiggleGitDiffPriv));
109 static void
110 giggle_git_diff_init (GiggleGitDiff *dummy)
114 static void
115 git_diff_finalize (GObject *object)
117 GiggleGitDiffPriv *priv;
119 priv = GET_PRIV (object);
121 if (priv->rev1) {
122 g_object_unref (priv->rev1);
125 if (priv->rev2) {
126 g_object_unref (priv->rev2);
129 g_free (priv->result);
131 g_list_foreach (priv->files, (GFunc) g_free, NULL);
132 g_list_free (priv->files);
134 if (priv->patch_format) {
135 g_object_unref (priv->patch_format);
138 G_OBJECT_CLASS (giggle_git_diff_parent_class)->finalize (object);
141 static void
142 git_diff_get_property (GObject *object,
143 guint param_id,
144 GValue *value,
145 GParamSpec *pspec)
147 GiggleGitDiffPriv *priv;
149 priv = GET_PRIV (object);
151 switch (param_id) {
152 case PROP_REV1:
153 g_value_set_object (value, priv->rev1);
154 break;
155 case PROP_REV2:
156 g_value_set_object (value, priv->rev2);
157 break;
158 case PROP_FILES:
159 g_value_set_pointer (value, priv->files);
160 break;
161 case PROP_PATCH_FORMAT:
162 g_value_set_object (value, priv->patch_format);
163 break;
164 default:
165 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
166 break;
170 static void
171 git_diff_set_property (GObject *object,
172 guint param_id,
173 const GValue *value,
174 GParamSpec *pspec)
176 GiggleGitDiffPriv *priv;
178 priv = GET_PRIV (object);
180 switch (param_id) {
181 case PROP_REV1:
182 if (priv->rev1) {
183 g_object_unref (priv->rev1);
185 #if GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION > 12
186 priv->rev1 = g_value_dup_object (value);
187 #else
188 priv->rev1 = GIGGLE_REVISION (g_value_dup_object (value));
189 #endif
190 break;
191 case PROP_REV2:
192 if (priv->rev2) {
193 g_object_unref (priv->rev2);
195 #if GLIB_MAJOR_VERSION > 2 || GLIB_MINOR_VERSION > 12
196 priv->rev2 = g_value_dup_object (value);
197 #else
198 priv->rev2 = GIGGLE_REVISION (g_value_dup_object (value));
199 #endif
200 break;
201 case PROP_FILES:
202 priv->files = g_value_get_pointer (value);
203 break;
204 case PROP_PATCH_FORMAT:
205 priv->patch_format = g_value_get_object (value);
206 break;
207 default:
208 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
209 break;
213 static gboolean
214 git_diff_get_command_line (GiggleJob *job, gchar **command_line)
216 GiggleGitDiffPriv *priv;
217 GString *str;
218 GList *files;
220 priv = GET_PRIV (job);
221 files = priv->files;
223 /* NOTE:
224 * Git currently (20071009) v1.5.2.1 only supports:
226 * $ git format-patch
228 * for COMPLETE changes sets to a branch, you can't use this
229 * command for a selection of files you have changed, also, it
230 * only works for committed work, not uncommitted work AFAICS.
232 if (priv->patch_format) {
233 str = g_string_new (GIT_COMMAND " format-patch");
235 g_string_append_printf (str, " %s -1",
236 giggle_revision_get_sha (priv->patch_format));
237 } else {
238 str = g_string_new (GIT_COMMAND " diff");
240 if (priv->rev1) {
241 g_string_append_printf (str, " %s", giggle_revision_get_sha (priv->rev1));
244 if (priv->rev2) {
245 g_string_append_printf (str, " %s", giggle_revision_get_sha (priv->rev2));
248 while (files) {
249 g_string_append_printf (str, " %s", (gchar *) files->data);
250 files = files->next;
254 *command_line = g_string_free (str, FALSE);
255 return TRUE;
258 static void
259 git_diff_handle_output (GiggleJob *job,
260 const gchar *output_str,
261 gsize output_len)
263 GiggleGitDiffPriv *priv;
265 priv = GET_PRIV (job);
267 priv->result = g_strdup (output_str);
270 GiggleJob *
271 giggle_git_diff_new (void)
273 return g_object_new (GIGGLE_TYPE_GIT_DIFF, NULL);
276 void
277 giggle_git_diff_set_revisions (GiggleGitDiff *diff,
278 GiggleRevision *rev1,
279 GiggleRevision *rev2)
281 g_return_if_fail (GIGGLE_IS_GIT_DIFF (diff));
282 g_return_if_fail (!rev1 || GIGGLE_IS_REVISION (rev1));
283 g_return_if_fail (!rev2 || GIGGLE_IS_REVISION (rev2));
285 g_object_set (diff,
286 "revision1", rev1,
287 "revision2", rev2,
288 NULL);
291 void
292 giggle_git_diff_set_files (GiggleGitDiff *diff,
293 GList *files)
295 GiggleGitDiffPriv *priv;
297 g_return_if_fail (GIGGLE_IS_GIT_DIFF (diff));
299 priv = GET_PRIV (diff);
301 if (priv->files) {
302 g_warning ("You have the 'patch-format' property set to TRUE. "
303 "Use of the git-format-patch command does not allow specific files. "
304 "These files will be ignored while 'patch-format' is TRUE.");
307 g_object_set (diff,
308 "files", files,
309 NULL);
312 void
313 giggle_git_diff_set_patch_format (GiggleGitDiff *diff,
314 GiggleRevision *rev)
316 GiggleGitDiffPriv *priv;
318 g_return_if_fail (GIGGLE_IS_GIT_DIFF (diff));
319 g_return_if_fail (GIGGLE_IS_REVISION (rev));
321 priv = GET_PRIV (diff);
323 if (priv->files) {
324 g_warning ("Use of the git-format-patch command does not allow specific files. "
325 "You have files set for this GiggleGitDiff which will be ignored.");
328 g_object_set (diff,
329 "patch-format", rev,
330 NULL);
333 GiggleRevision *
334 giggle_git_diff_get_patch_format (GiggleGitDiff *diff)
336 GiggleGitDiffPriv *priv;
338 g_return_val_if_fail (GIGGLE_IS_GIT_DIFF (diff), NULL);
340 priv = GET_PRIV (diff);
342 return priv->patch_format;
345 const gchar *
346 giggle_git_diff_get_result (GiggleGitDiff *diff)
348 GiggleGitDiffPriv *priv;
350 g_return_val_if_fail (GIGGLE_IS_GIT_DIFF (diff), NULL);
352 priv = GET_PRIV (diff);
354 return priv->result;