在libgit2中存储pop

时间:2013-03-29 08:57:33

标签: libgit2

git_stash_save()允许用户保存更改,类似于git stash。 是否有git stash pop更改功能?

我可以看到git_stash_foreach()git_stash_drop()。有没有办法使用它们来实现这个功能?

<小时/> 编辑:根据nulltoken's回答,我希望以下代码能够正常运行:

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", "no.name@gmail.com", 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_treetop_cmt吗?

2 个答案:

答案 0 :(得分: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(),这会将其剥离到树中。

答案 1 :(得分:2)

最终版本作为未来搜索者的复制粘贴代码段:

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", "no.name@gmail.com", 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);
  }
}