тайник поп в libgit2

git_stash_save() позволяет сохранять изменения, аналогично git stash. Есть ли функция для git stash pop возврата изменений?

Я вижу git_stash_foreach() и git_stash_drop(). Есть ли способ использовать их для достижения этой функциональности?


Изменить: основываясь на ответе nulltoken, я ожидал, что следующий код будет работать:

void tstStashPop ( const char * repo_path )
{
  git_repository *repo;
  git_commit * top_cmt;
  git_oid saved_stash;
  git_tree * top_tree;
  git_signature *signature;

  // open a repository
  if ( git_repository_open(&repo, repo_path) != 0 )
  {
    assert(false);
  }
  else
  {
    // create a signature
    git_signature_new(&signature, "no name", "[email protected]", 1323847743, 60);

    if ( git_stash_save( &saved_stash, repo, signature,
               "message for this stash", /*GIT_STASH_INCLUDE_UNTRACKED*/0) 
       != GIT_ENOTFOUND )
    {
      // get the commit that was saved by git stash save
      if ( git_commit_lookup( &top_cmt, repo, &saved_stash ) != 0 ) 
      {
        assert(false);
      }
      else
      {
        // get the tree for this commit
        if ( git_commit_tree( &top_tree, top_cmt ) != 0 )
        {
          assert(false);
        }
        else
        {
          // checkout the tree
          git_checkout_opts opts;
          opts = GIT_CHECKOUT_OPTS_INIT;
          opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
          if ( git_checkout_tree( repo, (git_object*)top_tree, &opts ) != 0 )
          {
            assert(false);
          }
        }
      }
      // remove the stashed commit
      git_stash_drop( repo, 0 );
    }

    // free signature
    git_signature_free(signature);

    // free repo
    git_repository_free(repo);
  }
}

Об ошибке не сообщается, но изменения не восстанавливаются. git_stash_save() работает (я вижу сообщение с git stash list) и git_stash_drop() тоже работает. Однако git_checkout_tree() не производит никакого эффекта.

Кроме того, должен ли я освободить top_tree и top_cmt?


person Nicu Tofan    schedule 29.03.2013    source источник


Ответы (2)


Есть ли функция git stash pop для возврата изменений?

Еще нет. Действительно, git stash (pop | apply) объединит содержимое тайника с текущим содержимым рабочего каталога.

К сожалению, merge пока недоступен в libgit2.

Обновлять

Однако git_checkout_tree() не дает никакого эффекта.

Возможно, вы захотите определить стратегию оформления заказа через opts.checkout_strategy. Значение по умолчанию — пробный прогон, ничего не обновляется.

Вы можете обратиться к include/git2/ checkout.h для получения более подробной информации о параметрах.

Кроме того, следует ли освобождать top_tree и top_cmt?

Действительно, git_tree_free() и git_commit_free() были бы здесь полезны.

В качестве альтернативы вы можете избежать вызова git_commit_tree() и напрямую передать фиксацию git_checkout_tree(), которая разместит ее в дереве.

person nulltoken    schedule 29.03.2013
comment
Как насчет обходного пути? Я ожидаю (из моего поверхностного понимания libgit2), что формат сохраняемых данных будет стандартным, который можно применять как обычный коммит. - person Nicu Tofan; 29.03.2013
comment
@TNick Возможно, вы действительно сможете попытаться проверить Tree из Commit, на которые указывает ссылка на тайник. Однако вам придется решить, как справляться с конфликтами (безопасно/принудительно). - person nulltoken; 29.03.2013
comment
Обновил вопрос с примером - person Nicu Tofan; 29.03.2013
comment
Этого кажется недостаточно, если неотслеживаемые файлы также спрятаны. git_stash_save() создает две фиксации: одну для индекса и одну для неотслеживаемых файлов. Эти два и базовый коммит устанавливаются в качестве родителей для коммита рабочего дерева, которое также возвращается. - person Nicu Tofan; 30.03.2013
comment
Как было сказано ранее, проверка была лишь обходным решением. Слияние требуется для реализации git_stash_pop - person nulltoken; 30.03.2013
comment
Слияние теперь доступно в версии 0.20.0. Есть ли шансы увидеть быстрый обходной путь для этого сейчас? - person Rémi Benoit; 02.12.2013
comment
@RémiBenoit Я думаю, что было бы неплохо открыть запрос функции в системе отслеживания проблем libgit2.. - person nulltoken; 02.12.2013

Окончательный вариант в виде сниппета для будущего искателя:

void tstStashPop ( const char * repo_path )
{
  git_repository *repo;
  git_commit * top_cmt;
  git_oid saved_stash;
  git_tree * top_tree;
  git_signature *signature;

  // open a repository
  if ( git_repository_open(&repo, repo_path) != 0 )
  {
    assert(false);
  }
  else
  {
    // create a signature
    git_signature_new(&signature, "no name", "[email protected]", 1323847743, 60);

    if ( git_stash_save( &saved_stash, repo, signature,
               "message for this stash", /*GIT_STASH_INCLUDE_UNTRACKED*/0) 
       != GIT_ENOTFOUND )
    {
      // get the commit that was saved by git stash save
      if ( git_commit_lookup( &top_cmt, repo, &saved_stash ) != 0 ) 
      {
        assert(false);
      }
      else
      {
        // get the tree for this commit
        if ( git_commit_tree( &top_tree, top_cmt ) != 0 )
        {
          assert(false);
        }
        else
        {
          // checkout the tree
          git_checkout_opts opts;
          opts = GIT_CHECKOUT_OPTS_INIT;
          opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
          if ( git_checkout_tree( repo, (git_object*)top_tree, &opts ) != 0 )
          {
            assert(false);
          }
          git_tree_free(top_tree);
        }
        git_commit_free(top_cmt);
      }
      // remove the stashed commit
      git_stash_drop( repo, 0 );
    }

    // free signature
    git_signature_free(signature);

    // free repo
    git_repository_free(repo);
  }
}
person Nicu Tofan    schedule 29.03.2013