git checkout 删除文件

git checkout deletes files

我是 git 的新手,我想尝试分支功能。我正在使用本地存储库。问题是,如果我创建一个新分支,然后回到主分支,一些文件会丢失。

我就是这样做的:

我有两个目录:

$ ls
g_LT  LT

和LT目录下的一个源代码文件lt_mp2.F:

$ ls LT/ | grep lt_mp2.F
lt_mp2.F

另一个目录包含到此文件的相对符号链接:

$ ls -l g_LT/ | grep lt_mp2.F
lt_mp2.F -> ../LT/lt_mp2.F

如果我创建一个新分支然后返回到master 分支,这两个文件都会丢失。那么,让我展示一下:

在我创建新分支之前,让我们检查一下没有什么要提交的:

$ git status
HEAD detached from 2617e8a
nothing to commit, working directory clean here

我们还要检查一下我们是否在 master 分支中,最后一次提交是从 2016 年 10 月 13 日开始的

$ git branch -a
* (detached from 2617e8a)
master

$ git log
commit 3484261bdd585671bf7c74568542a62610c2deaf
Author: [...]
Date:   Thu Oct 13 09:25:06 2016 +0200
[...]

现在我创建一个新分支:

$ git checkout -b testbranch
Switched to a new branch 'testbranch'

源文件还在:

$ ls LT/ | grep lt_mp2.F
lt_mp2.F
$ ls -l g_LT/ | grep lt_mp2.F
lt_mp2.F -> ../LT/lt_mp2.F

现在回到master分支:

$ git checkout master
Switched to branch 'master'

但是现在源文件不见了:

$ ls LT/ | grep lt_mp2.F
(no output)
$ ls -l g_LT/ | grep lt_mp2.F
(no output)

此外,最后一次提交突然从 2015 年 12 月开始,而不是 2016 年 10 月 13 日:

$ git log
commit 634741172ed34cd687fd91f14da45004b3328f8b
Author: [...]
Date:   Tue Dec 1 18:54:57 2015 +0100
[...]

这里发生了什么,为什么我丢失了我的源文件?

你没有(丢失任何文件,也没有任何提交)。

您的这部分起始声明是错误的:

Let's also check that we are in the master branch [snip]

$ git branch -a
* (detached from 2617e8a)
master

这表明您一开始就不在分支master。相反,你有一个 "detached HEAD"。最近显式 git checkout 的原始哈希 ID 或等效项(例如标签名称或远程跟踪分支名称)签出提交 2617e8a。您的 git log 输出显示当前提交可能是 1 3484261bdd585671bf7c74568542a62610c2deaf,并且 "detached from" 措辞表明您可能自己进行了此提交(Git 当你没有移动 HEAD 时使用 "detached at",当你移动 HEAD 时使用 "detached from"。

git log 命令默认显示从当前 (HEAD) 提交开始的提交2 并向后工作。无论 HEAD 是否为 "detached" 都是如此。 (非分离的 HEAD 是引用分支名称的 HEAD,例如 master。运行 git checkout <em>branchname</em> 给你一个非分离的 HEAD,即 HEAD 现在指向 branchname,以便使用指定的分支找到提交。)

如果您想查看更多或其他提交,您可以告诉 git log 从其他地方开始。无论你告诉它从哪里开始,它都会从那里向后工作。

因此,这仅意味着分支名称 master 指向 2015 年的提交。一旦 HEAD 指向 mastergit log (没有额外的参数)从最近的提交开始并从那里向后工作。

大概如果 master 已经过时了,那么所有真正的工作都在其他一些分支上进行。

当您从 3484261... 切换到 6347411... 时文件消失(这可能是由 master 标识的提交)因为它们 在前一个提交中,在后者中不是。因此 Git 在切换提交时将它们从索引和工作树中删除。切换回 3484261...(通过 ID 或您给它的新名称检出)会将它们放回索引和工作树中。


1git log 按日期对输出进行排序,默认情况下,首先显示日期较晚的提交。这段代码在我错过的某个点有所改变,因为它曾经可以 "post-date" 提交到 2038 年左右,所以它总是显示在 git log 输出的顶部,如果它是被展示出来。我最近测试时它已停止工作。

2参见脚注 1,请注意您可以更改排序顺序,and/or 对其进行约束,例如使用 --topo-order。添加 --graph--topo-order。通常,提交的日期或多或少与它们的图形拓扑结构一致,因此这些标志不会对排序顺序产生巨大变化。