Git 如何还原带有更改的暂存文件,并在暂存文件时保留对的更改?

Git 如何还原带有更改的暂存文件,并在暂存文件时保留对的更改?,git,Git,比如说我编辑了一个文件 echo "hi" > someVersionedFile.txt //Then I staged the file git add . git status <console reads> Changes to be committed new file: someVersionedFile.txt echo“hi”>someVersionedFile.txt //然后我准备了文件 git添加。 git状态 要提交的更改 新文件:someV

比如说我编辑了一个文件

echo "hi" > someVersionedFile.txt

//Then I staged the file
git add .
git status

<console reads>
 Changes to be committed
 new file: someVersionedFile.txt 
echo“hi”>someVersionedFile.txt
//然后我准备了文件
git添加。
git状态
要提交的更改
新文件:someVersionedFile.txt
现在,我对这些文件进行其他更改

echo "hi again file" >> someVersionedFile.txt

//Then I restage the file with these changes
git add .
git status

<console reads>
 Changed but not commited
 modified file: someVersionedFile.txt
echo“hi-reach file”>>someVersionedFile.txt
//然后,我用这些更改重新格式化文件
git添加。
git状态
已更改但未提交
修改文件:someVersionedFile.txt

问题:如何还原上一阶段的版本?由于未提交,是否可以执行此操作?

您不能执行此操作。Git只能将文件恢复到以前的提交版本,而不能恢复到以前的暂存版本。这是因为在您进行提交之前,不会将文件输入git的存储库。(您可以在上阅读有关提交的最佳实践的更多信息)


也许您可以明智地使用
undo
按钮?(如果您在编辑器中编辑了代码,显然
echo
ing到文件没有撤销功能)。

您可能可以这样做,但没有一个简单的命令可以帮您完成

当您执行git add时,文件已经被添加到存储库中,但是除了索引之外,当前没有任何指向它的内容。当您执行第二个
git add
时,新的(版本的)文件将添加到存储库中,并且索引和文件的第一个版本之间的链接将替换为新链接。但是第一个物体仍然在那里

您可以使用
git fsck--dangling
获取存储库中当前未被任何对象引用的blob对象列表,但随后您必须使用
git show
git cat file
等工具逐一查看它们,以确定所需的文件。一旦找到正确的文件,就可以
git show HASH>somefile.txt
(或者
git add somefile.txt

当然,如果您在第二次
git add
之后执行了任何
git prune
git gc
等操作,那么实际上可能已经从存储库中删除了原始文件

下面是一个简单的例子:

$ git init foo
Initialized empty Git repository in foo/.git/
$ cd foo
$ echo blah > foo.txt
$ git add foo.txt
$ echo blarg > foo.txt
$ git add foo.txt
$ git fsck --dangling
Checking object directories: 100% (256/256), done.
dangling blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
$ git show 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
blah
$

您的意思是要恢复到分段版本?是的,你绝对可以做到。最简单的方法可能是提交阶段性更改,从提交中签出文件,然后重置分支:

git commit -m "Temporary commit"
git checkout HEAD -- /path/to/file_you_want_to_revert
git reset HEAD~

Edit:Oops,对不起,我没有注意到您用新更改重新设置文件的部分。对不起,但其他答案是正确的:这是不可能的(或者至少不是很容易)。我将保留此答案,以防其他人与您有类似的问题,但尚未覆盖缓存。

我非常确定这是不可能的,但我也想知道是否可能!不确定您是如何做到这一点的,但如果您现在提交,则只会提交阶段性更改。然后,您可以将该文件还原为刚才所做的提交。@andypaxo这不是问题所在。更确切地说,问题是,如果你准备了一个带有更改的文件;对其进行更多更改,然后如何将文件恢复到暂存时的状态-假定暂存文件有/有其他更改?@thatdude这就是提交的全部要点。你在做一个版本承诺。您告诉版本控制它应该跟踪文件的当前状态。如果这有助于您——将git视为一个图,那么当您提交时,您将向该图插入一个节点,并且您只能在节点(版本)之间移动,您只需通过
git checkout/path/to/file\u您想要的\u还原
即可实现同样的效果,而无需给出分支名称。感谢您提供的提示-简单地说,另一种方式
git checkout[path]
将目标文件还原为其暂存版本,但只有在存在的情况下!如果在没有阶段的文件上运行相同的命令,它将在提交时恢复为其状态。因此,如果没有一个你打算回滚到的阶段,你可能会失去工作:)