Example #1
0
StagedFiles PmrWorkspace::stagedFiles()
{
    // Retrieve and return all current staged files

    StagedFiles res = StagedFiles();
    git_index *index;

    if (git_repository_index(&index, mGitRepository) == GIT_OK) {
        git_status_options statusOptions;

        git_status_init_options(&statusOptions, GIT_STATUS_OPTIONS_VERSION);

        statusOptions.flags =  GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
                              |GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY;
        statusOptions.show = GIT_STATUS_SHOW_INDEX_ONLY;

        git_status_list *statusList;

        if (git_status_list_new(&statusList, mGitRepository, &statusOptions) == GIT_OK) {
            for (size_t i = 0, iMax = git_status_list_entrycount(statusList); i < iMax; ++i) {
                const git_status_entry *status = git_status_byindex(statusList, i);
                const char *filePath = (status->head_to_index != nullptr)?
                                           status->head_to_index->old_file.path:
                                           (status->index_to_workdir != nullptr)?
                                               status->index_to_workdir->old_file.path:
                                               nullptr;

                if (filePath != nullptr) {
                    if ((status->status & GIT_STATUS_INDEX_TYPECHANGE) != 0) {
                        res << StagedFile(filePath, GIT_STATUS_INDEX_TYPECHANGE);
                    } else if ((status->status & GIT_STATUS_INDEX_RENAMED) != 0) {
                        res << StagedFile(filePath, GIT_STATUS_INDEX_RENAMED);
                    } else if ((status->status & GIT_STATUS_INDEX_DELETED) != 0) {
                        res << StagedFile(filePath, GIT_STATUS_INDEX_DELETED);
                    } else if ((status->status & GIT_STATUS_INDEX_MODIFIED) != 0) {
                        res << StagedFile(filePath, GIT_STATUS_INDEX_MODIFIED);
                    } else if ((status->status & GIT_STATUS_INDEX_NEW) != 0) {
                        res << StagedFile(filePath, GIT_STATUS_INDEX_NEW);
                    }
                }
            }

            git_status_list_free(statusList);
        }

        git_index_free(index);
    }

    return res;
}
Example #2
0
emacs_value egit_status_foreach(emacs_env *env, emacs_value _repo,
                                emacs_value function, emacs_value show,
                                emacs_value flags, emacs_value pathspec,
                                emacs_value baseline)
{
    EGIT_ASSERT_REPOSITORY(_repo);
    EM_ASSERT_FUNCTION(function);

    git_status_options options;
    git_status_init_options(&options, GIT_STATUS_OPTIONS_VERSION);

    if (!convert_show_option(&options.show, env, show)) {
        return em_nil;
    }
    if (!convert_flags_option(&options.flags, env, flags)) {
        return em_nil;
    }
    if (!egit_strarray_from_list(&options.pathspec, env, pathspec)) {
        return em_nil;
    }
    if (!convert_baseline_option(&options.baseline, env, baseline)) {
        egit_strarray_dispose(&options.pathspec);
        return em_nil;
    }

    git_repository *repo = EGIT_EXTRACT(_repo);
    egit_generic_payload ctx = {.env = env, .func = function};

    int rv = git_status_foreach_ext(repo, &options, &foreach_callback, (void *)(&ctx));
    egit_strarray_dispose(&options.pathspec);

    if (rv != GIT_EUSER) {
        EGIT_CHECK_ERROR(rv);
    }

    return em_nil;
}
Example #3
0
void CGitStatus::Load()
{
	GitStatus status;

	CriticalSection lock(this->m_critSec);
	status = this->GetStatus();
	if (status == GS_NOTLOADED || status == GS_INVALIDATED)
	{
		this->m_waitHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
		SetStatus(GS_LOADING);
	}
	lock.Unlock();

	if (status == GS_LOADED || status == GS_ERROR)
	{
		return;
	}

	// If it is loading just wait for it to complete.
	if (status == GS_LOADING)
	{
		_ASSERT(this->m_waitHandle.IsValid());
		WaitForSingleObject(this->m_waitHandle, INFINITE);
		return;
	}

	git_buf buf;
	git_repository *repo = NULL;
	wstring_convert<codecvt_utf8<wchar_t>> converter;
	InitState();

	if (!GetRepoRootInternal(this->m_startDir, this->m_repoRoot, buf, repo))
	{
		Logger::LogWarning(_T("Unable to open git repository"));
		SetStatus(GS_ERROR);
		::SetEvent(this->m_waitHandle);
		return;
	}

	// This is temporary.
	CMutexLock mutexLock(&m_mutex);

	this->m_gitDir = MyUtils::NormalizePath(converter.from_bytes(buf.ptr));

	// Get current state of repo. (merge/rebase in progress etc)
	this->m_repoState = git_repository_state(repo);

	// Get branch info.
	git_reference *ref;
	if (git_repository_head(&ref, repo))
	{
		Logger::LogError(_T("Unable to retrieve branch"));
		SetStatus(GS_ERROR);
		::SetEvent(this->m_waitHandle);
		return;
	}
	const char* headName = git_reference_shorthand(ref);
	this->m_branch = converter.from_bytes(headName);

	// Get the status of the repo.
	git_status_options opts;
	git_status_init_options(&opts, GIT_STATUS_OPTIONS_VERSION);
	opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
	git_status_foreach_ext(repo, &opts, &GitStatus_Callack, this);

	// Free stuff
	git_buf_free(&buf);
	git_repository_free(repo);

	this->SetStatus(GS_LOADED);
	::SetEvent(this->m_waitHandle);

	// Start monitoring for changes.
	this->MonitorForChanges();
	return;
}
Example #4
0
void PmrWorkspace::refreshStatus()
{
    // Keep track of our 'old' file nodes

    PmrWorkspaceFileNodes oldFileNodes = mRepositoryStatusMap.values();

    // Refresh our status

    mStagedCount = 0;
    mUnstagedCount = 0;

    mRepositoryStatusMap.clear();

    if (isOpen()) {
        git_status_options statusOptions;

        git_status_init_options(&statusOptions, GIT_STATUS_OPTIONS_VERSION);

        statusOptions.flags =  GIT_STATUS_OPT_INCLUDE_UNTRACKED
                              |GIT_STATUS_OPT_INCLUDE_UNMODIFIED
                              |GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
                              |GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY
                              |GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
        statusOptions.show  = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;

        git_status_list *statusList;

        if (git_status_list_new(&statusList, mGitRepository, &statusOptions) == GIT_OK) {
            // Go through the different entries and keep track of every single
            // one of them in mRepositoryStatusMap, as well as update
            // mStagedCount and mUnstagedCount, if needed

            for (size_t i = 0, iMax = git_status_list_entrycount(statusList); i < iMax; ++i) {
                const git_status_entry *status = git_status_byindex(statusList, i);
                const char *filePath = (status->head_to_index != nullptr)?
                                           status->head_to_index->old_file.path:
                                           (status->index_to_workdir != nullptr)?
                                               status->index_to_workdir->old_file.path:
                                               nullptr;

                if (filePath != nullptr) {
                    CharPair statusChars = gitStatusChars(status->status);

                    if (statusChars.first != ' ') {
                        ++mStagedCount;
                    }

                    if (statusChars.second != ' ') {
                        ++mUnstagedCount;
                    }

                    mRepositoryStatusMap.insert(filePath, parentFileNode(filePath)->addChild(QFileInfo(filePath).fileName(), statusChars));
                }
            }

            git_status_list_free(statusList);
        }

        // Delete any 'old' file node that is not being used anymore

        PmrWorkspaceFileNodes newFileNodes = mRepositoryStatusMap.values();
        PmrWorkspaceFileNodes oldFileNodesToDelete = PmrWorkspaceFileNodes();

        for (auto oldFileNode : oldFileNodes) {
            if (!newFileNodes.contains(oldFileNode)) {
                oldFileNodesToDelete << oldFileNode;
            }
        }

        if (!oldFileNodesToDelete.isEmpty()) {
            deleteFileNodes(mRootFileNode, oldFileNodesToDelete);
        }
    } else if (mRootFileNode->hasChildren()) {
        // We are not open, so clear our root file node

        for (auto child : mRootFileNode->children()) {
            delete child;
        }
    }
}
Example #5
0
static gboolean
submain (struct EvTag *self,
         int    argc,
         char **argv,
         GError **error)
{
  gboolean ret = FALSE;
  git_status_options statusopts = GIT_STATUS_OPTIONS_INIT;
  GCancellable *cancellable = NULL;
  const char *command_name = NULL;
  Subcommand *command;
  char *prgname = NULL;
  int in, out;
  int r;

  /*
   * Parse the global options. We rearrange the options as
   * necessary, in order to pass relevant options through
   * to the commands, but also have them take effect globally.
   */

  for (in = 1, out = 1; in < argc; in++, out++)
    {
      /* The non-option is the command, take it out of the arguments */
      if (argv[in][0] != '-')
        {
          if (command_name == NULL)
            {
              command_name = argv[in];
              out--;
              continue;
            }
        }

      else if (g_str_equal (argv[in], "--"))
        {
          break;
        }

      argv[out] = argv[in];
    }

  argc = out;

  command = commands;
  while (command->name)
    {
      if (g_strcmp0 (command_name, command->name) == 0)
        break;
      command++;
    }

  if (!command->fn)
    {
      GOptionContext *context;
      char *help;

      context = option_context_new_with_commands (commands);

      /* This will not return for some options (e.g. --version). */
      if (option_context_parse (context, NULL, &argc, &argv, cancellable, error))
        {
          if (command_name == NULL)
            {
              g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                   "No command specified");
            }
          else
            {
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           "Unknown command '%s'", command_name);
            }
        }

      help = g_option_context_get_help (context, FALSE, NULL);
      g_printerr ("%s", help);

      g_option_context_free (context);

      goto out;
    }

  prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name);
  g_set_prgname (prgname);

  r = git_repository_open_ext (&self->top_repo, ".", 0, NULL);
  if (!handle_libgit_ret (r, error))
    goto out;

  r = git_status_init_options (&statusopts, GIT_STATUS_OPTIONS_VERSION);
  if (!handle_libgit_ret (r, error))
    goto out;

  {
    struct TreeWalkData twdata = { FALSE, self, self->top_repo, NULL, cancellable, error };
    r = git_status_foreach_ext (self->top_repo, &statusopts, status_cb, &twdata);
    if (twdata.caught_error)
      goto out;
    if (!handle_libgit_ret (r, error))
      goto out;
  }

  self->checksum = g_checksum_new (G_CHECKSUM_SHA512); 

  if (!command->fn (self, argc, argv, cancellable, error))
    goto out;

  ret = TRUE;
 out:
  return ret;
}