为什么从另一个分支签出的文件已经暂存?

5

关于我们的Git工作流程,我们会从主分支创建一个用于特定迭代的分支,每个迭代中的工作项都从该分支创建。因此,分支/合并流程实际上是:

master
  |   \
  |    sprint42________
  |       |    \       \
  |       |     item1   item2
  |       | ___/       /
  |       |/          /
  |       | _________/
  |       |/
  | _____/
  |/
  |

现在,在这个流程中,我发现我对item1中的一个文件所做的更改也需要在item2中进行(可以想象为我添加了一个方便函数的实用程序文件)。
因此,基于这个问题的被接受的答案,我检出了item2分支,并按照以下方式从item1分支拉取实用程序文件:
git checkout item2
git checkout item1 utilities.xyzzy

然而,在检查git status时,发现该文件已被放入暂存区,而我认为将其视为新修改的文件可能更有意义:

pax> git status
On branch item2
Your branch is up-to-date with 'origin/item2'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
        modified:   utilities.xyzzy

为什么要这样做?当我从不同的分支拉取文件到当前分支时,如何使它成为一个修改后的文件,并在准备好时进行暂存?


我曾经也犯过类似的错误,但记住拉取是获取/合并/提交(在快进中),而检出最多只是该操作的三分之一,这对我很有帮助。是的,我知道你没有使用“pull”,但你最初的措辞暗示了一个动词可能会溢出到另一个动词上。 - msw
2个回答

6

顺便提一下:当我读原始主题行"Why is file pulled from ..."(现已修复)时,我认为你是在指git pull脚本。我认为值得强调的是,你在这里特别指的是使用形式为:git checkout branch pathgit checkout

查阅git checkout文档,我们可以找到以下内容:

git checkout [-p|--patch] [<tree-ish>] [--] ...

当给出<paths>或--patch时,git checkout不会切换分支。它会从索引文件或命名的<tree-ish>(通常是提交)更新工作树中的指定路径。在这种情况下,-b--track选项无意义,给出其中任何一个都会导致错误。<tree-ish>参数可用于在更新工作树之前为给定路径更新索引而指定特定的树对象(即提交、标签或树)。

我在此将关键部分加粗了:git首先从给定的“tree-ish”写入到索引中(如果不直接从索引中检出),然后从索引复制到工作树。这就是为什么新文件被暂存的原因。要撤消暂存,必须在同一路径上使用git reset

有一种方法可以将文件放入工作树中,而不是通过索引进行复制,使用git show

git show item1:utilities.xyzzy > utilities.xyzzy
< p > git show 命令会将指定的对象(在这种情况下是该文件)以漂亮的方式打印到标准输出,并重定向输出以捕获文件。然而请注意,这将绕过任何会在正常检出时修改文件内容的 smudge 过滤器。


1
你和我同时发了同一秒的帖子;)但你总是得到我的自动+1。 - VonC
1
好的,你通常也会从我这里得到一个。相互欣赏的社团,或者什么? :-) (我不太擅长点赞问题和答案,我偶尔会这样做...) - torek

5

正如我在 "git reset vs git reset HEAD" 中所提到的,对于 git checkout <tree-ish> -- <paths> 命令。

git checkout <tree-ish> -- <pathspec>

当给定路径时,git checkout命令不会切换分支。它从索引文件或命名的(通常是提交)中更新工作树中的指定路径。
由于索引直接被更新,你得到一个准备提交的文件。因此,出现了git status的"Changes to be committed:"。

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