Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
git rebase:rebase提交仍在索引中?_Git_Git Rebase - Fatal编程技术网

git rebase:rebase提交仍在索引中?

git rebase:rebase提交仍在索引中?,git,git-rebase,Git,Git Rebase,当我读到这篇文章时,我明白了重定基础的提交应该会丢失。我之所以说应该,是因为我注意到,知道了重定基址的commit sha,我可以回忆起它。 假设我有以下三个提交 A -> B -> C 其中C的sha是cshaid。然后,如果我使用git-rebase-I HEAD~2将修复C重新设置为B,然后使用git log检查结果,我会得到预期的结果,这意味着 A -> B' 其中B'的sha与B的sha不同。 但是,再次显示运行git log cshaid A -> B -

当我读到这篇文章时,我明白了重定基础的提交应该会丢失。我之所以说应该,是因为我注意到,知道了重定基址的commit sha,我可以回忆起它。
假设我有以下三个提交

A -> B -> C
其中
C
的sha是
cshaid
。然后,如果我使用
git-rebase-I HEAD~2
修复
C
重新设置为
B
,然后使用
git log
检查结果,我会得到预期的结果,这意味着

A -> B'
其中
B'
的sha与
B
的sha不同。
但是,再次显示运行
git log cshaid

A -> B -> C
问题:这是已知的行为吗?我试图阅读git rebase--help,但找不到相关信息。为什么不简单地忘记重定基础的提交?我的意思是,rebase是一种危险的操作,只有在您知道自己在做什么并且能够做到的情况下才能执行,这就是使用脏索引的意义所在(或者在保存这些无用提交的地方)?我错过什么了吗?
复制的步骤(以及更好地理解我的疑问)。如果您愿意再现这种情况,请尝试:

  • mkdir-sampledir&&cd-sampledir&&git-init
  • touch file&&git add-A.&git commit-m“Initial”
  • 编辑文件,然后
    git提交-am“第一次修改”
  • 编辑文件,然后提交git-am“第二次修改”
  • git日志
    ,您将看到三次提交,记住第二次修改的sha
  • git-rebase-i头~2
    ,将
    修复
    第二次修改
    转化为
    第一次修改
  • git log
    ,您将看到两个提交,其中
    第一次修改的sha现在与步骤5中的不同
  • 但是,“第二次修改”的git log sha将显示与此列表中第5点完全相同的树

  • 是的,这是预期的行为。未引用的提交最终将被垃圾收集,从而从磁盘中清除。它们会保留数天(默认为14天),但在14天计时器开始计时之前,对象也必须从reflog中过期(默认情况下,无法访问的对象在30天后过期)

    相关问题:


    git-rebase
    与其他以破坏性方式改变历史的命令一样,删除对过时提交的引用,但不会导致立即删除它,它在正常操作过程中定期自动执行,将(最终)从
    .git/objects
    中删除实际提交数据(尽管将在一段时间内保持对提交的引用处于活动状态)

    这是一个安全特性;使用git确实很难丢失数据。如果您确实想确保某些内容已丢失(例如,如果您意外提交了一个巨大的文件,并且希望收回磁盘空间),则需要使reflog条目过期并手动运行
    git gc

    git reflog expire --expire=now --all
    git gc --aggressive --prune=now
    
    我知道重新设定的提交应该丢失

    没有。不要迷路。在繁忙的repo中,git最终将垃圾收集那些从任何ref都无法访问并且已经存在一个月或更长时间的内容,但是除了
    git gc
    ,git操作只会添加到历史图中

    移动标签对回购协议中的实际历史记录没有任何影响

    。。。我知道重新设定的提交应该丢失

    他们没有迷失,他们(故意)“被抛弃”(我的术语)

    确实,
    rebase
    复制了旧提交的内容。事实上,除了特殊的优化等,它基本上与执行
    git cherry pick
    相同(并且交互式rebase脚本对每个“pick”操作使用
    git cherry pick
    ,对“squash”和“fixup”操作修改样式提交)

    然而,存储库中的提交何时以及是否可见完全取决于其他因素。通常,
    git log
    以您所在分支的名称开头,如
    HEAD
    中所记录的(在
    .git
    目录中有一个名为
    HEAD
    的文件,其中包含字符串
    ref:refs/heads/master
    ,这就是git知道您“在分支主机上”的原因。1

    给定一个分支名称,git通过“读取引用”将其转换为(单个)提交:

    然后,
    log
    命令可以通过其SHA-1读取提交对象。该提交对象有一些父SHA-1,并且
    git log
    也读取这些SHA-1,依此类推,直到它到达一个没有父SHA-1的提交(“根”提交)

    因此,给定根提交
    a
    ,第二次和第三次提交
    B
    C
    ——加上指向
    C
    的标签
    master

    A <-- B <-- C   <-- HEAD=master
    
    使
    B'
    git log
    一起显示的是标签
    master
    ,是commit
    C的“剥离”和“粘贴到”commit
    B'
    。更准确地说,分支
    主文件
    .git/refs/heads/master
    )2的文件将使用
    B'
    的新SHA-1重写:

    A <-- B <-- C   [no label, "abandoned"]
     ^
      \
        B'   <-- HEAD=master
    

    A删除了这些。我接受了你的回答,获得了额外的信息(如天数)和链接。默认的reflog过期时间是30天和90天(请参阅)。这属于30天类别。当然,无论哪种方式,您都不希望只假设reflog将永远保持不变。:-)@托瑞克:关于30天,你说得对,谢谢。更新了答案。
    reflog
    为+1。我忘了在问题中提到,但当然,由于
    reflog
    过期,仅仅在重定基址后进行垃圾收集是不够的
    A <-- B <-- C
     ^
      \
        B'
    
    A <-- B <-- C   [no label, "abandoned"]
     ^
      \
        B'   <-- HEAD=master