大约一个星期前,我正在将我的.gitignore文件推送到我的存储库,并且遇到了一些小问题,最后想出来了,但注意到我的所有故事板都在存储库中。在天才的推动下,我看着让他们离开那里,发现了上面的git reset命令,然后把它放到我的终端并拍拍自己的背部,生活还在继续。我刚刚意识到安装了一些cocoapods之后,我花了几周工作的所有故事板都消失了,把两个和两个放在一起。我花了最后一小时阅读了类似的问题,但在阅读了一段时间后却找不到任何东西,我想知道是否有其他xcode用户遇到同样的问题并且可以提供帮助。
我还应该补充一点,我只是将故事板添加到舞台上并且在重置时尚未提交它们,所以今天我使用git reflog命令希望它们在丢失并找到了。我读过垃圾收集一个月没有发生,所以我不想(我希望)他们刚刚离开
我今天下载了AWS SDK,而且目前所有的git reflog命令似乎都在显示。我是否需要进一步回滚git rest HEAD {}命令?
非常感谢!
答案 0 :(得分:2)
git stash
这是一个重要的信息,它改变了一切。幸运的是,它也使恢复变得更加容易。特别是它意味着你丢失的文件不是"悬空blob"并且 do 保存了原始名称。 (顺便提一下,git stash
表示git stash save
;我会使用下面的较长表格将其与其他git stash
命令区分开来。)
最简单的恢复方法是使用git stash branch
。选择新分支名称,即您尚未拥有的名称。为了说明,我将使用saveme
,这是一个可怕的名称,你应该选择一个更好的名称。
git stash branch saveme
这将使用您现有的git stash
,使用当前运行git stash save
时的提交创建新分支。然后,它会将您的索引(暂存区域)恢复为您运行git stash save
,和时的工作树状态,使其恢复到您运行时的状态{ {1}}。您现在可以提交索引:
git stash save
然后提交其余的工作树,如果还有其他事情需要提交:
git commit -m 'save index as a commit'
我将在这个答案的最后(在另一个编辑中)添加一个图表,说明整个序列发生了什么,从第一个git add --all
git commit -m 'save everything else as a commit too'
开始并经过git add
和git stash save
以及最后的git reset --hard HEAD^
。
有一点需要注意:您的索引和工作树必须干净才能使用git stash branch
。如果您有未提交的工作,您可能应该立即提交,或者使用git stash branch
将其全部删除。当然,任何一个都有后果:
如果您运行另一个git reset --hard
,则先前保存的藏匿点会被推送到#34;从git stash save
到stash@{0}
。然后你必须使用:
stash@{1}
将该存储转换为分支。
如果您选择使用git stash branch saveme stash@{1}
,则会丢失任何未提交的作品,因此请确保此操作正常。
让我们来看一个假设的终端会话,看看你工作时你的提交和分支会发生什么。
git reset --hard
此时,您正在使用Git工作树。工作树是您的文件处于正常形式的位置,计算机的其余部分(和您)可以使用,而不是Git专用表单,Git保存 的每个版本em>您或其他任何人曾提交的文件。你在某些分支上 - 让我们说$ cd my-git-project
,只是为了具体。这个分支有一些提交,以Git调用该分支的 tip 提交结束。分支名称会记住此提示提交的哈希ID:
master
每个大写字母代表一个普通的普通提交。 (换句话说,这些代表了每个提交的实际名称的难以理解的哈希ID。)提交...--F--G--H <-- master
是最新的。如果您的索引/暂存区域和工作树是&#34; clean&#34;,则其中的文件与提交H
中的文件匹配。
现在你做了一些改变,然后进行部分或全部修改:
H
暂存区域,也就是索引,现在不是&#34;干净&#34;:它不再匹配提交$ ... edit some files ...
$ git add file1 file2 ...
。相反,它包含已编辑和添加的文件的副本。
您的工作树可能与您的索引匹配也可能不匹配。如果 匹配你的索引,并且如果你要运行H
,Git会从你的索引中做出一个新的提交(那是索引/登台区域是什么)因为,主要是:构建下一个提交),然后你的索引将匹配你的提交并且是干净的。如果您的工作树与您的索引匹配,那么那也是干净的。这看起来像是:
git commit
其中...--F--G--H--I <-- master
是新提交,由您的索引构成。
相反,你跑了I
。这样做是做两个提交,两者都不在分支上:
git stash save
第一个(小写...--F--G--H <-- master
|\
i-w <-- stash
)提交是i
提交的相同的提交。它不在分支git commit
上;它是这个两次提交&#34;藏匿袋的一部分&#34;。第二个提交master
是特殊的:它看起来像Git的其余部分就像是一个合并提交,但实际上它只是提交了你的工作树状态,即使这样做也是如此。与w
中的索引状态相同。
在进行这两个存储包提交后,i
重置(清除)索引和工作树,即git stash
。所以现在你的索引和工作树匹配再次提交git reset --hard HEAD
。
接下来,你说你跑了H
。这会做三个事情:它将索引和工作树状态重置为所选提交的状态,即git reset --hard HEAD^
之前的状态;它使名称H
也指向所选的提交。所以现在您的存储库看起来像这样:
master
请注意,隐藏包仍然存在,仍然可以通过名称...--F--G <-- master
\
H [remembered in reflogs, *and* preserved via the stash]
|\
i-w <-- stash
找到。两个stash-bag提交记住了它的哈希ID提交stash
。同时,名称H
现在会记住提交master
的哈希ID,而您的索引和工作树是&#34; clean&#34;,即匹配G
的哈希值
如果您现在运行G
,这就是Git在提交方面的作用:
git stash branch saveme
从...--F--G <-- master
\
H <-- saveme
|\
i-w [abandoned]
提交重新加载索引,并从i
提交重新加载工作树。如果你现在运行w
,你会得到:
git commit
因为Git将索引保存为新提交...--F--G <-- master
\
H--I <-- saveme
。工作树保持不变;如果它在I
方面干净了,那么它现在都是干净的,如果没有,你可以I
任何剩余的更改并提交它们:
git add
现在所有内容都会永久保存(或直到您删除...--F--G <-- master
\
H--I--J <-- saveme
分支),这些普通提交可以通常的方式使用。请注意,您使用saveme
投放到回收站的提交H
已在新分支上返回。
我还应该补充一点,我只是将故事板添加到舞台上,并且在重置时还没有提交它们......
这会让事情变得更难,因为:
...今天我正在使用
git reset --hard HEAD^
命令
git reflog
仅查看已弃用的提交。
......希望他们在迷路中找到。
他们可能仍然是! &#34;迷失并找到了#34;与reflogs分开。
我读过垃圾收集一个月没发生所以我不想(我希望)他们刚刚离开
30天的宽限期专门用于在reflog中记住的 commit 对象,而这些对象不是。但是,所有对象都会获得14天的宽限期。时钟从git reflog
文件到暂存区域时开始。 (即使一旦时钟耗尽,也需要稍后git add
才能使文件消失,但很难知道何时会发生这种情况。)
实际上找到你的文件有点棘手。运行:
git gc --auto
,正如the documentation所说:
git fsck --lost-found
将悬空对象写入.git / lost-found / commit /或 .git / lost-found / other /,具体取决于类型。如果对象是blob, 内容被写入文件,而不是其对象 名称
由于你做了--lost-found
这些文件,并且他们可能从未进行过任何提交,因此他们将会&&#34;悬挂&#34;对象类型&#34; blob&#34;。 git add
命令将打印一堆难以理解的哈希名称。然后,您可以切换到git fsck
目录并检查其中的所有文件,这些文件都具有这些哈希名称。在所有这些文件中,您.git/lost-found/other/
ed的内容将会出现。
对于每个此类文件,确定是否应将其保存在合理的文件名下,并将文件从git add
区域移出到该名称之一,然后将该文件恢复。