【问题标题】:Forgot to rm refs/original after git filter-branch在 git filter-branch 之后忘记 rm refs/original
【发布时间】:2016-01-07 11:36:02
【问题描述】:

我在git filter-branch 之后忘记了rm refs/original 并做了git gc,它清除了refs。我还提交了新的 repo,并希望保留这些提交。

提取的分支大小为几千字节,但.git 的权重仍为 80 MB,就像过滤之前一样。

现在refs 是空的,我不能再轻易删除refs/original。我怎样才能删除原件?如果可能的话,我想避免再次filter-branch

【问题讨论】:

    标签: git git-filter-branch git-gc


    【解决方案1】:

    您的裁判已打包(git gc 运行 git pack-refs)。这不会对 refs 本身进行任何更改,除了不是将每个 refs 放在单独的文件中,它们都在“打包”文件中。

    您只需删除 refs/origina/ 引用。理论上在每一个上使用git update-ref -d 应该可以工作,但如果有很多,在编辑器中打开.git/packed-refs 并手动删除所有refs/original/ 行可能更容易。

    您可能还需要清除 reflog。

    请参阅this StackOverflow answer 了解更多信息。

    【讨论】:

      【解决方案2】:

      git gc 运行 git pack-refs

      如果您开始删除 refs,请确保使用 Git 2.24+(2019 年第三季度):“git pack-refs”可能会丢失在运行时创建的 refs,这正在得到纠正。

      参见Sun Chao (sunchao)commit a613d4f(2019 年 7 月 31 日)。
      (由 Sun Chao -- sunchao -- 合并于 commit a613d4f,2019 年 8 月 2 日)

      pack-refs:获取锁文件后总是刷新

      当一个打包的引用被删除时,整个打包引用文件被重写以省略不再存在的引用。
      但是,如果另一个gc 命令正在运行并同时调用pack-refs --all, 刚刚更新的 ref 有可能丢失新创建的提交。

      通过这些步骤,可以证明在新更新的 ref 上丢失提交:

        # step 1: compile git without `USE_NSEC` option
        Some kernel releases do enable it by default while some do
        not. And if we compile git without `USE_NSEC`, it will be easier
        demonstrated by the following steps.
      
        # step 2: setup a repository and add the first commit
        git init repo &&
        (cd repo &&
         git config core.logallrefupdates true &&
         git commit --allow-empty -m foo)
      
        # step 3: in one terminal, repack the refs repeatedly
        cd repo &&
        while true
        do
          git pack-refs --all
        done
      
        # step 4: in another terminal, simultaneously update the
        # master with update-ref, and create and delete an
        # unrelated ref also with update-ref
        cd repo &&
        while true
        do
          us=$(git commit-tree -m foo -p HEAD HEAD^{tree}) &&
          git update-ref refs/heads/newbranch $us &&
          git update-ref refs/heads/master $us &&
          git update-ref -d refs/heads/newbranch &&
          them=$(git rev-parse master) &&
          if test "$them" != "$us"
          then
            echo >&2 "lost commit: $us"
            exit 1
          fi
          # eye candy
          printf .
        done
      

      虽然我们有打包引用锁定文件和松散引用锁定文件以避免更新冲突,但如果发生packed-refs 文件的 racy stat-validity ,引用将丢失其新提交。
      最好的前进路径是在获取packed-refs文件的锁定文件后总是刷新。

      【讨论】:

        猜你喜欢
        • 2011-12-01
        • 2017-12-07
        • 2012-05-22
        • 2013-03-29
        • 1970-01-01
        • 2020-07-22
        • 2012-04-29
        • 2011-03-10
        • 2018-10-10
        相关资源
        最近更新 更多