命令 `git checkout 有什么作用。 path/to/file.php`怎么办?

What does the command `git checkout . path/to/file.php` do?

我有几个修改过的文件,我的git status看起来像

$ git status
On branch loyalty-module
Your branch is up-to-date with 'origin/loyalty-module'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   this/is/a/path/to/AFile.php
    modified:   this/is/another/file/A.php
    modified:   this/is/another/file/B.php

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    system/logs/test.log
    system/logs/test-api.log

no changes added to commit (use "git add" and/or "git commit -a")

一不小心,我运行这个命令git checkout . this/is/a/path/to/AFile.php。注意句号!

当我再次 运行 git status 时,我得到的只是 未跟踪的文件

$ git status
On branch loyalty-module
Your branch is up-to-date with 'origin/loyalty-module'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    system/logs/test.log
    system/logs/test-api.log

no changes added to commit (use "git add" and/or "git commit -a")

git checkout . 是做什么的?我怎样才能再次检索那些 modified 文件?

像这样的点本身通常是 Git 中的 pathspec。它表示 当前目录 ,通常——因为 Git 大多数人不相信 folders/directories1——意味着 当前目录及其所有子目录下的所有文件。所以:

git checkout .

是对Git的指示:请毁掉我刚刚所做的一切努力2

And how can I retrieve those modified files again?

你不能,无论如何在 Git。您的编辑器,或 macOS Time Machine,或其他一些外部-Git 方法可能提供一种让它们恢复的方法。

这里要吸取的教训是 git checkout 有两种模式:

  • git checkout <em>branch-name</em> 在“安全模式”下运行,首先检查它是否会破坏数小时(或数分钟,或数天,或其他)的工作。如果是这样,它会说:不,那会破坏你的辛勤工作,你有机会先保存它。

  • git checkout <em>path-spec</em>运行在“不安全模式”,立即清除您在任何指定路径中所做的任何工作。

有时,与.一样,很明显此路径规范不能是分支名称(. 不是合法的分支名称),但有时根本不清楚:git checkout devdev 是一个包含很多文件的 目录 ,还是 分支名称? 所以你可能想要使用新奇的 git switchgit restore 命令,自 Git 版本 2.23 起可用:

  • git switch 采用分支名称并在安全模式下运行。

  • git restore 采用路径规范并在不安全模式下运行。

关于 git _____ dev 是安全还是不安全从来没有任何问题,因为您填写的空白 - 用 switchrestore - 告诉你。


1这有点夸大其词:Git当然对文件夹了如指掌;它 ,因为你的 OS 需要这个。但是 Git 不会 在存储在提交中的文件中使用 它们:提交中的文件只有带有嵌入正斜杠的长名称。名称 path/to/file 不是包含目录 to 的目录 path,目录 to 包含文件 file,它只是一个字面上名为 path/to/file.

的文件

从技术上讲,这就是 Git 的 索引 中显示的内容,也称为 暂存区 ,但是由于所有内容都必须通过 Git 的索引/暂存区,这就是 Git 不存储目录的原因,并且您不能让它保存一个空文件夹。另见 How can I add a blank directory to a Git repository?

2从技术上讲,这是将文件从索引复制到工作树中的请求。但是,由于您没有暂存这些文件以进行提交,所以效果是这样的。