【问题标题】:How to update the working tree to a commit while keeping the index?如何在保留索引的同时将工作树更新为提交?
【发布时间】:2019-09-17 00:27:08
【问题描述】:

我做了一些更改并将它们全部放入索引中。现在我想扔掉工作树,让它看起来完全像提交的HEAD,而不扔掉索引。如何实现?

我所看到的一切都朝着相反的方向发展:在操作索引的同时保留工作树,或者同时操作两者。

例如,是否有某种方法可以存储该索引,然后在不对工作树做任何事情的情况下暂存这些已存储的更改?

作为参考,下面的 hacky 实现了效果,至少在涉及的材料是可修补的文本文件时。假设所有更改都已使用git add 进行:

# apply the staged diff to the working tree, in reverse; i.e. undo it.
git diff --cached | git apply -R

此后,git diff --cached 继续显示阶段性更改,git diff 显示反向差异:这些更改相对于索引被撤消。

这个问题的答案必须重现上述命令管道的效果。

【问题讨论】:

  • git checkout -- . 应该只重置您的工作目录,保持舞台不变。
  • @TimBiegelsen 你读过文档吗?如果没有 参数,这会将工作副本重置为索引。由于我已经上演了所有内容(索引 == 工作),因此没有效果。使用 参数,它会影响索引!
  • 使用git write-tree 将索引写入提交。保存生成的哈希 ID,执行破坏索引的操作,然后使用写入树中的 git read-tree 修复它。
  • @TimBiegeleisen:不是重复,因为目标是在此操作中保存 index
  • 我想我觉得这部分的问题有点令人困惑:“我想丢弃工作树,让它看起来与提交的 HEAD 完全一样,而不丢弃索引。”然后在评论中写下“因为我已经完成了所有内容(索引 == 工作)”。如果 index == 有效,那么简单的存储不能解决您的问题吗?如果 index == working 你所说的“扔掉工作树,让它看起来和提交的 HEAD 完全一样,而不扔掉索引”是什么意思?

标签: git


【解决方案1】:

有一种方法可以使用git stash 执行此操作。我碰巧真的不喜欢git stash,但无论如何我都会写出来:

  1. 运行git stash:这将保存索引和工作树,名称为refs/stash。然后它运行git reset --hard,所以现在你的索引和工作树看起来像你想要的那样。

  2. 用你的工作树做任何你喜欢的事情

  3. 要将索引恢复到它们在步骤 1 中的状态,请运行 git stash apply --indexgit stash branch <em>branch-name</em>。后者将使用存储的父级(在您进行存储时处于活动状态的提交)的哈希 ID、git checkout 该分支创建一个新分支,然后运行 ​​git stash apply --index

    李>

请注意,这也会恢复您不一定想要的工作树。它使用git apply --index 恢复索引,并使用git-merge-recursive 恢复工作树。一个或两个步骤都可能失败,除非应用于与原始提交匹配的内容(因此git stash branch 总是成功)。

既然你只是真的想保存和恢复索引,我们可以去低级:

  1. hash=git write-tree:将索引写为新的(或重复使用的)Git tree 对象并保存生成的哈希
  2. git reset --hard:工作树和索引现在都匹配提交
  3. git read-tree $hash:更新索引以匹配给定的哈希值,而不触及工作树。

read-tree 命令相当复杂,可以做很多其他事情,但这个特殊的操作不是。

【讨论】:

  • 我会试试的;我将我的方法归结为:git diff --cached | git apply -R!就是这样。但它涉及生成一个从 git 和返回长号的补丁,所以它有点难看,可能无法很好地处理二进制内容(在我的场景中不是问题)。
  • 顺便说一句,我完全不清楚为什么你想这样做。对索引真正能做的唯一事情就是提交它,其中git write-tree 是第一步(剩下的就是git commit-treegit update-ref)。
  • 我在 HEAD 中有新添加的文件,并希望简化这些文件,同时保留完整的定义以进入新的提交。我认为也可以这样做:将更改提交到新的提交中。然后提交该提交的还原。然后以交互方式变基,压缩两个较旧的提交。
【解决方案2】:

git stash --keep-index 有帮助吗?类似的东西:

git stash --keep-index # stash working tree without the index
git stash # stash just the index
git stash drop <stashid-of-wt-without-index>

编辑:很抱歉造成混乱。我从 GUI (magit) 中使用它,你需要哪个更清楚。

【讨论】:

  • --no-keep-indexstash 中的唯一记录效果是覆盖由-p/--patch 设置的隐式--keep-index
猜你喜欢
  • 2019-07-29
  • 2017-03-12
  • 2015-01-03
  • 2015-04-18
  • 2016-01-19
  • 2023-03-16
  • 2020-01-13
  • 2011-03-24
相关资源
最近更新 更多