gboolean gitg_commit_add_ignore(GitgCommit *commit, GitgChangedFile *file, GError **error) { g_return_if_fail(GITG_IS_COMMIT(commit)); g_return_if_fail(GITG_IS_CHANGED_FILE(file)); GFile *f = gitg_changed_file_get_file(file); gchar *path = gitg_repository_relative(commit->priv->repository, f); gchar *ignore = g_strdup_printf("%s/.gitignore", gitg_repository_get_path(commit->priv->repository)); GFile *ig = g_file_new_for_path(ignore); GFileOutputStream *stream = g_file_append_to(ig, G_FILE_CREATE_NONE, NULL, error); gboolean ret = FALSE; if (stream) { gchar *line = g_strdup_printf("/%s\n", path); ret = g_output_stream_write_all(G_OUTPUT_STREAM(stream), line, strlen(line), NULL, NULL, error); g_output_stream_close(G_OUTPUT_STREAM(stream), NULL, NULL); g_object_unref(stream); g_free(line); } if (ret) remove_file(commit, file); g_object_unref(f); g_free(ignore); g_free(path); }
gboolean gitg_commit_revert(GitgCommit *commit, GitgChangedFile *file, gchar const *hunk, GError **error) { gboolean ret; if (!hunk) { GFile *f = gitg_changed_file_get_file(file); gchar *path = gitg_repository_relative(commit->priv->repository, f); ret = gitg_repository_command_with_inputv(commit->priv->repository, path, error, "checkout-index", "--index", "--quiet", "--force", "--stdin", NULL); g_free(path); remove_file(commit, file); g_object_unref(f); } else { GitgRunner *runner = gitg_runner_new_synchronized(1000); gchar const *argv[] = {"patch", "-p1", "-R", NULL}; ret = gitg_runner_run_with_arguments(runner, argv, gitg_repository_get_path(commit->priv->repository), hunk, NULL); update_index_file(commit, file); update_index_unstaged(commit, file); g_object_unref(runner); } return ret; }
static void read_other_files_update(GitgRunner *runner, gchar **buffer, GitgCommit *commit) { gchar *line; while ((line = *buffer++)) { /* Skip empty lines */ if (!*line) continue; /* Check if file is already in our index */ gboolean added = FALSE; GSList *item; gchar *path = g_build_filename(gitg_repository_get_path(commit->priv->repository), line, NULL); GFile *file = g_file_new_for_path(path); g_free(path); GitgChangedFile *f = g_hash_table_lookup(commit->priv->files, file); if (f) { changed_file_new(f); g_object_unref(file); continue; } f = gitg_changed_file_new(file); changed_file_new(f); g_hash_table_insert(commit->priv->files, file, f); g_signal_emit(commit, commit_signals[INSERTED], 0, f); } }
static void add_recent_item(GitgWindow *window) { GtkRecentManager *manager = gtk_recent_manager_get_default(); GtkRecentData data = { 0 }; gchar *groups[] = {"gitg", NULL}; gchar const *path = gitg_repository_get_path(window->priv->repository); gchar *basename = g_path_get_basename(path); data.display_name = basename; data.app_name = "gitg"; data.mime_type = "inode/directory"; data.app_exec = "gitg %f"; data.groups = groups; GFile *file = g_file_new_for_path(gitg_repository_get_path(window->priv->repository)); gchar *uri = g_file_get_uri(file); gtk_recent_manager_add_full(manager, uri, &data); g_free(basename); g_free(uri); g_object_unref(file); }
gboolean gitg_utils_export_files(GitgRepository *repository, GitgRevision *revision, gchar const *todir, gchar * const *paths) { GString *gstr = g_string_new("sh -c \"git --git-dir"); // Append the git path gchar *gitpath = gitg_utils_dot_git_path(gitg_repository_get_path(repository)); append_escape(gstr, gitpath); g_free(gitpath); // Append the revision gchar *sha = gitg_revision_get_sha1(revision); g_string_append_printf(gstr, " archive --format=tar %s", sha); g_free(sha); // Append the files while (*paths) { append_escape(gstr, *paths); paths++; } g_string_append(gstr, " | tar -xC"); append_escape(gstr, todir); g_string_append(gstr, "\""); GError *error = NULL; gint status; gboolean ret = g_spawn_command_line_sync(gstr->str, NULL, NULL, &status, &error); if (!ret) { g_warning("Export failed:\n%s\n%s", gstr->str, error->message); g_error_free(error); } g_string_free(gstr, TRUE); return ret; }
static gboolean create_repository(GitgWindow *window, gchar const *path, gboolean usewd) { gboolean ret = TRUE; if (path) { gchar realp[PATH_MAX]; if (realpath(path, realp)) { window->priv->repository = gitg_repository_new(realp); if (!gitg_repository_get_path(window->priv->repository)) { // Try current directory path = NULL; g_object_unref(window->priv->repository); window->priv->repository = NULL; ret = FALSE; } } else { ret = FALSE; path = NULL; } } if (!path && usewd) { gchar *curdir = g_get_current_dir(); window->priv->repository = gitg_repository_new(curdir); g_free(curdir); } return ret; }
static void load_repository(GitgWindow *window, gchar const *path, gint argc, gchar const **argv, gboolean usewd) { if (window->priv->repository) { gtk_tree_view_set_model(window->priv->tree_view, NULL); g_signal_handlers_disconnect_by_func(window->priv->repository, G_CALLBACK(on_repository_load), window); g_object_unref(window->priv->repository); window->priv->repository = NULL; } gboolean haspath = create_repository(window, path, usewd); if (window->priv->repository && gitg_repository_get_path(window->priv->repository)) { gtk_tree_view_set_model(window->priv->tree_view, GTK_TREE_MODEL(window->priv->repository)); GitgRunner *loader = gitg_repository_get_loader(window->priv->repository); g_signal_connect(loader, "begin-loading", G_CALLBACK(on_begin_loading), window); g_signal_connect(loader, "end-loading", G_CALLBACK(on_end_loading), window); g_signal_connect(loader, "update", G_CALLBACK(on_update), window); g_object_unref(loader); gchar const **ar = argv; if (!haspath && path) { ar = (gchar const **)g_new(gchar *, ++argc); int i; for (i = 0; i < argc - 1; ++i) ar[i] = argv[i]; ar[argc - 1] = path; }
static void add_files(GitgCommit *commit, gchar **buffer, gboolean cached) { gchar *line; while (line = *buffer++) { gchar **parts = g_strsplit_set(line, " \t", 0); guint len = g_strv_length(parts); if (len < 6) { g_warning("Invalid line: %s (%d)", line, len); g_strfreev(parts); continue; } gchar const *mode = parts[0] + 1; gchar const *sha = parts[2]; GSList *item; gchar *path = g_build_filename(gitg_repository_get_path(commit->priv->repository), parts[5], NULL); GFile *file = g_file_new_for_path(path); g_free(path); GitgChangedFile *f = GITG_CHANGED_FILE(g_hash_table_lookup(commit->priv->files, file)); if (f) { GitgChangedFileChanges changes = gitg_changed_file_get_changes(f); g_object_set_data(G_OBJECT(f), CAN_DELETE_KEY, NULL); if (cached) { gitg_changed_file_set_sha(f, sha); gitg_changed_file_set_mode(f, mode); changes |= GITG_CHANGED_FILE_CHANGES_CACHED; } else { changes |= GITG_CHANGED_FILE_CHANGES_UNSTAGED; } gitg_changed_file_set_changes(f, changes); g_object_unref(file); g_strfreev(parts); continue; } f = gitg_changed_file_new(file); GitgChangedFileStatus status; if (strcmp(parts[4], "D") == 0) status = GITG_CHANGED_FILE_STATUS_DELETED; else if (strcmp(mode, "000000") == 0) status = GITG_CHANGED_FILE_STATUS_NEW; else status = GITG_CHANGED_FILE_STATUS_MODIFIED; gitg_changed_file_set_status(f, status); gitg_changed_file_set_sha(f, sha); gitg_changed_file_set_mode(f, mode); GitgChangedFileChanges changes; changes = cached ? GITG_CHANGED_FILE_CHANGES_CACHED : GITG_CHANGED_FILE_CHANGES_UNSTAGED; gitg_changed_file_set_changes(f, changes); g_hash_table_insert(commit->priv->files, file, f); g_signal_emit(commit, commit_signals[INSERTED], 0, f); g_strfreev(parts); } }