在git中将文件从Stage复制到工作目录

4

在git中,通常有多种方法可以完成一件事情。Git主要涉及三个区域:工作目录,暂存区(索引)和本地仓库。通常,git中的每个命令都会将文件从这些区域之一移动/复制到另一个区域。虽然从工作目录到暂存区和仓库中移动文件很常见,但我想知道如何从暂存区复制/移动文件到工作目录。我知道的一个命令是git checkout -- filename。该命令会放弃对该文件所做的更改,并用文件最后暂存版本替换它们。我想知道是否还有其他不同的命令可以完成相同的功能?

4个回答

1

您可以使用以下命令取消暂存文件(将文件从暂存区移回工作目录):

git restore --staged <file>

这是在您的代码库上运行 git status 时,从git(版本 >= 2.23)中提出的建议方法。


请注意,git restore --staged <file>git checkout -- filename不等同,因为第二个命令无法将文件从暂存区撤销。 - pol92
但是 git restore <file> 相当于 git checkout -- filename,对吧?因为当我尝试这个命令时,它用该文件的最后一个暂存版本替换了工作目录中对该文件所做的更改。 - Dhruv Deshmukh
没错,你提到的命令(在 git restore 中不带 --staged 参数)是等价的。 - pol92

0

运行 git reset 命令会移除你在索引中(也包括仓库)所做的更改,但会将它们保留在工作目录中。

例如,假设你添加了一些文本到一个文件并使用 git add 命令将其添加到暂存区。如果现在运行以下命令:

git reset HEAD^

那么添加的文本将不会在暂存区(事实上也不会在仓库中)中,但它仍然存在于工作目录中。然而,这与git checkout -- <file>不同,因为此命令将文件恢复到最后记录的状态并丢弃更改,无法再次获取。这被认为是一条风险命令,所以在运行它时一定要知道自己在做什么。


如果您在互联网上查询(上面的网站只是一个示例),则会发现Git reset命令虽然可以撤销git add,但它实际上是将文件从最后一次提交复制到了暂存区。但是,有没有提及到在暂存区和工作目录之间进行移动/复制?这个应该考虑吗? - Dhruv Deshmukh

0

在 Git 中,通常有多种方法来完成一件事情。

没错:Git 有一大套工具,它们之间存在重叠。

广义上讲,Git 有三个相关的区域:工作目录、暂存区(索引)和本地仓库。

这也是正确的。

Git 中的每个命令通常都会将文件从其中一个区域移动/复制到另一个区域。

我认为这有点夸张,因为 Git 的许多工具并不会这样做,例如 git branch 只是操作分支名称,git tag 只是操作标签名称等等。但肯定有一些工具会进行这种复制操作。

... 我想知道如何将文件从暂存区移动/复制到工作目录中

在 Git 2.23 之前,这方面的工具有些分散和笨拙。

在 Git 2.23 中,git checkout 命令被拆分为两个独立的、设计更好的工具:git switchgit restoregit restore 命令有将文件复制到索引/暂存区和工作树的工具。这些工具可以独立使用或同时使用。 git checkout 命令只有一种形式,用于从索引/暂存区复制到工作树,就是你提到的那个:

我知道的一个命令是 git checkout -- filename

git reset 命令类似于旧的(仍然存在的)git checkout,因为它执行了太多的任务并且没有很好地打包,但它也可以将文件从索引复制到工作树。问题在于,为了这样做,它必须首先将文件从提交复制到索引。 (还值得注意的是:它只能通过 git reset --hard 来实现,并且当您使用该模式时,您正在调整整个工作树,而不仅仅是单个文件。因此,该模式仅适用于非常特定的用例,尽管它们有些常见。)

git checkout-index命令可以从索引复制到工作树。它并不经常使用:它被称为所谓的“管道命令”,用于编写新的面向用户的工具。

git showgit cat-file命令可以提取任何内部对象,包括索引中的对象。您可以使用命令行重定向来处理这些数据,例如:git show :0:README.md > index-copy-of-README.mdgit cat-file -p :Makefile | wc -l,以便让您的常规工具与数据一起使用。


如果您查看网上的内容(上面的网站只是一个例子),它说尽管git reset命令撤消了git add,但它实际上将文件从上次提交复制到了暂存区。但是在暂存区和工作目录之间没有提及移动/复制,所以应该考虑吗? - Dhruv Deshmukh
git reset 命令很复杂:在几种模式下,它只从 HEAD 复制到索引/暂存区,但是使用 git reset --hard 时,它会同时复制到索引和工作树。问题在于,这只能在“整个提交”模式下使用,而不能在“单个文件”模式下使用。因此,它偶尔有用,但只是非常偶尔。 - torek

0
如果您只想取消暂存特定文件,可以使用以下命令:
git rm --cached <file>. 

当然,这将从索引中删除文件,但OP的问题是如何将文件从索引/暂存区移动/复制到工作区。为了自己验证,先在工作区中有一个 certainFile,然后将其添加到暂存区/索引中。然后执行 rm certainFile 以将其从工作区中删除。现在文件在暂存区,但不在工作区。现在执行 git rm --cached certainFile文件在哪里?...有任何副本吗? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接