libgit2 / libgit2/libgit2sharp

Question: Using `RewriteHistory` multiple times on the same commit

未關閉
#2,023 0 則留言 1 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

主要語言
C#
星號
3.5k
分支
925
PR 合併指標
30 天內沒有已合併 PR

描述

Hi Folks, This isn't a bug report but a question I have regarding calling the RewriteHistory method on the same commit.

public class Tests
{
    Repository Repository;
    DirectoryInfo RepositoryDirectoryInfo;

    private static void CopyDirectoryContents(string sourcePath, string targetPath)
    {
       // copies repository, containg .git and repository content to a temp path. not important for this.
    }

    private static Repository LoadRepository(string repositoryAbsolutePath)
    {
        return new Repository(repositoryAbsolutePath);
    }

    [SetUp]
    public void Setup()
    {
        // Create a temporary directory
        string temporaryGitRepositoryAbsPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
        RepositoryDirectoryInfo = Directory.CreateDirectory(temporaryGitRepositoryAbsPath);

        // Create a copy of the git Repository fixture as testing will modify the fixture itself
        string fixtureGitRepositoryRelPath = "Fixtures\\SampleGitRepository";
        CopyDirectoryContents(fixtureGitRepositoryRelPath, RepositoryDirectoryInfo.FullName);

        Repository = LoadRepository(RepositoryDirectoryInfo.FullName);
    }

    [Test]
    public void Test1()
    {
        // Get the commits and grab the first one
        List<Commit> firstCommits = Repository.Commits.ToList();
        Commit firstChangeToFirstCommit = firstCommits.First();

        // Rewrite commit. Change commit message.
        GitRewriter.RewriteCommit(
            repository: Repository,
            commit: firstChangeToFirstCommit,
            author: firstChangeToFirstCommit.Author,
            committer: firstChangeToFirstCommit.Committer,
            commitMessage: "first change to commit message"
        );

        // Not sure if required (I dont think it is)
        Repository.Reset(ResetMode.Hard, Repository.Head.Tip);

        // Reload Repository thats changed.
        // a.k.a return new Repository("the abs path of the repository");
        Repository = LoadRepository(RepositoryDirectoryInfo.FullName);

        // Get the commits again, and grab the first one like before
        List<Commit> secondCommits = Repository.Commits.ToList();
        Commit secondChangeToFirstCommit = secondCommits.First();

        // Rewrite a second time
        GitRewriter.RewriteCommit(
            repository: Repository,
            commit: secondChangeToFirstCommit,
            author: secondChangeToFirstCommit.Author,
            committer: secondChangeToFirstCommit.Committer,
            commitMessage: "second change to commit message"
        );
    }
}
public class GitRewriter
{
  public static void RewriteCommits(Repository repository, Commit[] commits, Signature author, Signature committer, string commitMessage)
  {
      RewriteHistoryOptions options = new()
      {
          OnError = (error) => ... ,
          OnSucceeding = () => ... ,
          CommitHeaderRewriter = commit =>
          {
              return CommitRewriteInfo.From(
                  commit: commit,
                  author: author,
                  committer: committer,
                  message: commitMessage
              );
          }
      };
      repository.Refs.RewriteHistory(options, commits);
  }
  public static void RewriteCommit(Repository repository, Commit commit, Signature author, Signature committer, string commitMessage)
  {
      Commit[] singleCommit = new Commit[] { commit };
      RewriteCommits(
          repository: repository,
          commits: singleCommit,
          author: author,
          committer: committer,
          commitMessage: commitMessage
      );
  }
}

If you look at my test case Test1, I'm trying to use RewriteHistory on the same commit, twice.

The first rewrite works fine.

On the second attempt, I get the exception: Can't back up reference 'refs/heads/master' - 'refs/original/heads/master' already exists

Message: 
System.InvalidOperationException : Can't back up reference 'refs/heads/master' - 'refs/original/heads/master' already exists

Stack Trace: 
HistoryRewriter.RewriteReference[TRef,TTarget](TRef oldRef, Func`2 selectTarget, Func`2 rewriteTarget, ReferenceUpdater`2 updateTarget)
HistoryRewriter.RewriteReference(Reference reference)
HistoryRewriter.Execute()
ReferenceCollection.RewriteHistory(RewriteHistoryOptions options, IEnumerable`1 commitsToRewrite)
ReferenceCollection.RewriteHistory(RewriteHistoryOptions options, Commit[] commitsToRewrite)
GitRewriter.RewriteCommit(Repository repository, Commit[] commits, Signature author, Signature committer, String commitMessage) line 29
GitRewriter.RewriteCommit(Repository repository, Commit commit, Signature author, Signature committer, String commitMessage) line 34
Tests.Test1() line 168
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

I'm aware that when a commit is changed, a new SHA is allocated to that changed commit, and when after I've changed the commit the first time, the SHA does indeed change, but when I attempt to change it the second time, using the changed SHA, I recieve the error as described above.

I've checked the examples of LibGit2 and I could not find anything specific regarding this use-case of changing the same commit twice.

I've tried 'reloading' the repository by created a new Repository but no dice.

Any help, tips or pointers to documentation would be greatly appreciated. Thank you,

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 ReferenceCollection.RewriteHistory 和 HistoryRewriter.RewriteReference 開始,按照 Test1 序列追蹤到 GitRewriter.RewriteCommit。檢查 refs/heads/master 和 refs/original/heads/master 在多次重寫之間如何備份。完成標準是確認是否支援重複重寫,並記錄現有備份參照所需的行為或解決方案。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
csharp, git
領域
devtools
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
需要釐清
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。