int main (int argc, char *argv[]) { GFile *file; GgitRepository *repo; GgitRevisionWalker *revwalker; GgitRef *head; GgitOId *oid; gint64 n_revisions = 10; GError *err = NULL; ggit_init (); if (argc < 2 || argc > 3) { g_print ("Usage: %s path_to_git_repository [N_REVISIONS]\n", argv[0]); return 1; } if (argc == 3) { n_revisions = g_ascii_strtoll (argv[2], NULL, 10); if (n_revisions < -1) { g_printerr ("Error: invalid number of " "revisions: %" G_GINT64_FORMAT "\n", n_revisions); return 1; } } file = g_file_new_for_path (argv[1]); if (!g_file_query_exists (file, NULL)) { g_object_unref (file); g_printerr ("Error: invalid git repository: %s\n", argv[1]); return 1; } repo = ggit_repository_open (file, &err); g_assert_no_error (err); revwalker = ggit_revision_walker_new (repo, &err); g_assert_no_error (err); ggit_revision_walker_set_sort_mode (revwalker, GGIT_SORT_TIME | GGIT_SORT_TOPOLOGICAL); head = ggit_repository_get_head (repo, &err); g_assert_no_error (err); oid = ggit_ref_get_target (head); ggit_revision_walker_push (revwalker, oid, &err); g_assert_no_error (err); ggit_oid_free (oid); g_object_unref (head); while ((oid = ggit_revision_walker_next (revwalker, &err)) != NULL) { GgitCommit *commit; gchar *oid_str; GgitSignature *author; GgitSignature *committer; gchar *author_str; gchar *committer_str; const gchar *subject; const gchar *message; GgitCommitParents *commit_parents; commit = GGIT_COMMIT (ggit_repository_lookup (repo, oid, GGIT_TYPE_COMMIT, &err)); g_assert_no_error (err); oid_str = ggit_oid_to_string (oid); author = ggit_commit_get_author (commit); committer = ggit_commit_get_committer (commit); author_str = signature_to_string (author); committer_str = signature_to_string (committer); subject = ggit_commit_get_subject (commit); message = ggit_commit_get_message (commit); g_print ("SHA: %s\n" "Author: %s\n" "Committer: %s\n" "Subject: %s\n" "Message: %s\n", oid_str, author_str, committer_str, subject, message); commit_parents = ggit_commit_get_parents (commit); if (ggit_commit_parents_get_size (commit_parents) > 0) { GgitCommit *parent_commit; GgitTree *commit_tree; GgitTree *parent_tree; GgitDiff *diff; parent_commit = ggit_commit_parents_get (commit_parents, 0); commit_tree = ggit_commit_get_tree (commit); parent_tree = ggit_commit_get_tree (parent_commit); diff = ggit_diff_new_tree_to_tree (repo, parent_tree, commit_tree, NULL, &err); g_assert_no_error (err); ggit_diff_print (diff, GGIT_DIFF_FORMAT_PATCH, diff_print_cb, NULL, &err); g_assert_no_error (err); g_object_unref (diff); g_object_unref (parent_tree); g_object_unref (commit_tree); g_object_unref (parent_commit); } g_print ("----------------------------------------\n"); g_object_unref (commit_parents); g_free (committer_str); g_free (author_str); g_object_unref (committer); g_object_unref (author); g_free (oid_str); g_object_unref (commit); ggit_oid_free (oid); if (n_revisions != -1 && --n_revisions == 0) { break; } } g_assert_no_error (err); g_object_unref (revwalker); g_object_unref (repo); g_object_unref (file); return 0; }
static gboolean ide_git_buffer_change_monitor_calculate_threaded (IdeGitBufferChangeMonitor *self, DiffTask *diff, GError **error) { g_autofree gchar *relative_path = NULL; g_autoptr(GFile) workdir = NULL; const guint8 *data; gsize data_len = 0; g_assert (IDE_IS_GIT_BUFFER_CHANGE_MONITOR (self)); g_assert (diff); g_assert (G_IS_FILE (diff->file)); g_assert (diff->state); g_assert (GGIT_IS_REPOSITORY (diff->repository)); g_assert (diff->content); g_assert (!diff->blob || GGIT_IS_BLOB (diff->blob)); g_assert (error); g_assert (!*error); workdir = ggit_repository_get_workdir (diff->repository); if (!workdir) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, _("Repository does not have a working directory.")); return FALSE; } relative_path = g_file_get_relative_path (workdir, diff->file); if (!relative_path) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, _("File is not under control of git working directory.")); return FALSE; } diff->is_child_of_workdir = TRUE; /* * Find the blob if necessary. This will be cached by the main thread for us on the way out * of the async operation. */ if (!diff->blob) { GgitOId *entry_oid = NULL; GgitOId *oid = NULL; GgitObject *blob = NULL; GgitObject *commit = NULL; GgitRef *head = NULL; GgitTree *tree = NULL; GgitTreeEntry *entry = NULL; head = ggit_repository_get_head (diff->repository, error); if (!head) goto cleanup; oid = ggit_ref_get_target (head); if (!oid) goto cleanup; commit = ggit_repository_lookup (diff->repository, oid, GGIT_TYPE_COMMIT, error); if (!commit) goto cleanup; tree = ggit_commit_get_tree (GGIT_COMMIT (commit)); if (!tree) goto cleanup; entry = ggit_tree_get_by_path (tree, relative_path, error); if (!entry) goto cleanup; entry_oid = ggit_tree_entry_get_id (entry); if (!entry_oid) goto cleanup; blob = ggit_repository_lookup (diff->repository, entry_oid, GGIT_TYPE_BLOB, error); if (!blob) goto cleanup; diff->blob = g_object_ref (blob); cleanup: g_clear_object (&blob); g_clear_pointer (&entry_oid, ggit_oid_free); g_clear_pointer (&entry, ggit_tree_entry_unref); g_clear_object (&tree); g_clear_object (&commit); g_clear_pointer (&oid, ggit_oid_free); g_clear_object (&head); } if (!diff->blob) { if ((*error) == NULL) g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("The requested file does not exist within the git index.")); return FALSE; } data = g_bytes_get_data (diff->content, &data_len); ggit_diff_blob_to_buffer (diff->blob, relative_path, data, data_len, relative_path, NULL, NULL, NULL, NULL, diff_line_cb, (gpointer)diff->state, error); return ((*error) == NULL); }