Ejemplo n.º 1
0
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);
}