之间的区别.git中的(点)和*(星号)通配符 [英] Difference between . (dot) and * (asterisk) wildcards in git

查看:152
本文介绍了之间的区别.git中的(点)和*(星号)通配符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个本地存储库并试图放弃自上次提交以来的所有更改

I have a local repository and trying to discard all changes it it since the last commit via

git checkout HEAD -- *

命令.一切正常,即使更改位于某个子目录中.但是当我添加一些未跟踪的文件(满足 .gitignore 中的掩码)时,对存储库的根目录说Ignored.txt",上述命令失败并显示消息

command. Everything works fine, even if the changes were at some subdirectory. But when I add some untracked file (satisfying a mask in .gitignore), say 'Ignored.txt' to the root of the repository, the above command fails with the message

error: pathspec 'Ignored.txt' did not match any file(s) known to git

相反,

git checkout HEAD -- .

按预期工作.所以我想知道:

works as expected. So I want to know:

git中.*通配符有什么区别?

What is the difference between . and * wildcards in git?

推荐答案

主要区别不在于 Git.

因为它不在 Git 中,所以它是否有任何区别,如果有,有什么区别,取决于您使用的非 Git 命令解释器.

Because it's not in Git, whether it makes any difference, and if so, what difference, depends on the not-Git command interpreter you are using.

在类 Unix 系统(包括 Linux)上,命令解释器(或shell")为您扩展了 *.各种 shell,例如 bashzshfishtcshdash依此类推(其中大多数的名称以 sh 结尾),将 * 解释为当前工作目录中的大多数文件".这种扩展称为globbing.

On a Unix-ish system (including Linux), it's the command interpreter (or "shell") that expands * for you. The various shells, such as bash and zsh and fish and tcsh and dash and so on (most of them have names ending in sh), interpret * to mean "most of the files in the current working directory". This kind of expansion is called globbing.

这些shell不会以任何方式解释和扩展..这意味着:

These shells do not interpret and expand . in any way. This means that:

git xyzzy -- .

使用三个参数调用 gitxyzzy--..但是:

invokes git with three parameters, xyzzy, --, and .. But:

git xyzzy -- *

使用七个参数调用 git:xyzy--abcde,如果有名为a的文件当前工作目录中的 bcde.

invokes git with, say, seven parameters: xyzy, --, a, b, c, d, e, if there are files named a, b, c, d, and e in the current working directory.

Git 主要对存储在存储库中的 提交 感兴趣.为了构建提交,Git 使用其索引,也存储在存储库中.索引实际上以一种特殊的、仅限 Git 的压缩格式保存文件——本质上与提交中的内容相同.

Git is primarily interested in commits, stored in a repository. To build new commits, Git uses its index, also stored in the repository. The index actually holds the files, in a special, Git-only, compressed format—essentially the same as what's in the commits.

文件的索引副本是可写的,而任何文件的提交副本都是只读的.(从技术上讲,Git 只是将 objects 保存在其主对象数据库中,索引和提交副本都只是对这些对象的引用.您不能覆盖任何对象,但您可以添加一个 new 对象并切换索引引用;您无法更改提交的引用.效果是提交中的文件被冻结,而索引中的文件解冻/可写.)

The index copy of a file is writable, while the committed copies of any file are all read-only. (Technically, Git just keeps objects in its main object database, and both the index and commit copies are just references to these objects. You cannot overwrite any object, but you can add a new object and switch the index reference around; you cannot change the commits' references. The effect is that files in commits are frozen, while files in the index are thawed / writable.)

这种仅限 Git 的内部文件格式对您、用户以及您计算机上的大多数程序都没有用.所以这些文件必须被扩展.它们被扩展到您的工作树中,它位于一个目录(或文件夹)中,该目录(或文件夹)可能有子目录(子文件夹).您可以将当前工作目录设置为这些工作树目录中的任何一个.然后,shell 会将 * 扩展为在工作树中的当前目录中找到的文件的名称.

This internal Git-only file format is not useful to you, the user, nor to most programs on your computer. So these files have to be expanded. They get expanded into your work-tree, which lives in a directory (or folder) that may have subdirectories (sub-folders). You can set your current working directory to any of these work-tree directories. The shell will then expand * to the names of the files found in this current directory within the work-tree.

Git 主要使用您当前的工作目录来查找存储库数据库,其中存在 Git 的真实文件.工作树副本仅供您随意摆弄.

Git primarily uses your current working directory to find the repository database, where Git's real files live. The work-tree copies are just for you to fiddle with as you please.

当然,git checkoutgit add 都以各种方式使用工作树.但是请注意,由于工作树供使用,您可以将存储库本身中不存在的文件放入其中.

Of course, git checkout and git add both use the work-tree in various ways. Note, however, that since the work-tree is for your use, you can put files into it that do not exist in the repository itself.

文件可以在您的工作树中,但不能在您的索引中.(实际上,索引存在于工作树和正确的存储库之间",并为 Git 提供了一个位置来存储将进入 next 提交的文件.)这种状态——在你的工作树中,但不在你的索引中——被称为未跟踪.

A file can be in your work-tree, but not in your index. (The index lives, in effect, "between" the work-tree and the repository proper, and provides a place for Git to store files that will go into the next commit.) A file that is in this state—in your work-tree, but not in your index—is said to be untracked.

Git 本质上不知道未跟踪的文件.但是它们在您的工作树中(根据定义),因此如果这也是您当前的工作目录,并且您使用 * 并让 shell 将 * 扩展到这些文件名,你会向 Git 传递一个它当前不知道的文件名.

Git inherently does not know about untracked files. But they are in your work-tree (by definition), so if that is also your current working directory, and you use * and have the shell expand the * to these file names, you'll pass to Git a file name that it doesn't currently know about.

如果您使用的命令是 git add,您将告诉 Git:将此文件从工作树复制到索引中. 这将在索引,以便它现在将在您进行的下一次提交中.Git 没问题!

If the command you use is git add, you will tell Git: copy this file from the work-tree into the index. That will create the file in the index, so that it is now going to be in the next commit you make. Git is fine with that!

但是如果你使用的命令是 git checkout,你会告诉 Git:将此文件从索引复制到工作树中. Git 不会找到文件在索引中,所以它会抱怨.(它不会触及工作树中的文件.)

But if the command you use is git checkout, you will tell Git: copy this file from the index into the work-tree. Git won't find the file in the index, so it will complain. (It won't touch the file in the work-tree.)

请注意,未跟踪的文件可以但不一定也被忽略(这不是一个很好的术语,但它是 Git 使用的术语).你告诉 Git 不要通过在名为 .gitignore 的文件中列出它们的名称或它们名称的模式来抱怨未跟踪的文件.在这种情况下,git add 将警告您忽略未跟踪和忽略的文件:Git 不会将该文件复制到索引中,即使您使用 git add *.

Note that a file that is untracked can be, but isn't necessarily, also ignored (this is not a very good term, but it's the one Git uses). You tell Git not to complain about untracked files by listing their names, or patterns for their names, in files named .gitignore. In this case, git add will warn you that an untracked-and-ignored file is ignored: Git won't copy that file into the index, even if you use git add *.

如果您使用 git add .git checkout -- .,shell 根本不会扩展.Git 看到 . 并且知道这意味着当前工作目录",所以如果它合适——例如,对于 git add——Git 将读取当前工作目录.它可以将它在那里找到的文件与索引中已经存在的文件进行比较,并知道如何为 git add 更新它们,包括添加 (1) 未跟踪和 (2) 列在 .gitignore 中.(根据定义,已经在索引中的文件不会被忽略,因此这些文件也会从工作树更新到索引中.)

If you use git add . or git checkout -- ., the shell does not expanding at all. Git sees the . and knows that this means "the current working directory", so if it's appropriate—e.g., for git add—Git will read the current working directory. It can compare the files it finds there to those that are already in the index, and know how to update them for git add, including to not add files that are (1) untracked and (2) listed in .gitignore. (Files that are already in the index aren't ignored, by definition, so those also get updated from the work-tree into the index.)

使用 git checkout -- .,Git 直接查看索引,根本看不到未跟踪的文件.

With git checkout -- ., Git looks directly in the index, and doesn't see files that are untracked at all.

以上内容相当简单,但有几个特殊情况使其复杂化:

The above is fairly simple, but there are several special cases that complicate it:

  • 大多数 shell 在扩展 时匹配点文件(例如 .profile.gitignore)*.所以,如果你在当前目录下有 .gitattributes.gitignore 文件,并且使用 git checkout -- *,你可能不会将这些文件的索引版本复制到工作树中.

  • Most shells do not match dot-files (such as .profile or .gitignore) when expanding *. So, if you have files .gitattributes and .gitignore in the current directory, and use git checkout -- *, you probably won't copy the index version of these files into the work-tree.

如果当前目录中根本没有文件,或者没有与 *.asdf 之类的 glob 模式匹配的文件,一些 shell 会抱怨并中止命令,但其他人只是通过模式——*.asdf 甚至 *——到你正在运行的程序上.

If there are no files at all in the current directory, or none that match a glob pattern like *.asdf, some shells complain and abort the command, but others just pass the pattern—*.asdf or even *—on to the program you're running.

DOS 风格的 CMD.EXE 不会扩展 *.

DOS-style CMD.EXE does not expand *.

对于最后两种情况,Git 本身确实看到了*.现在 Git 有机会进行 glob 扩展,在 Git 的情况下,Git 确实 匹配 . - 文件,如 .gitattributes.gitignore.因此,如果当前工作目录没有非点文件,但有 .gitattributes.gitignore,并且您运行:

For the last two cases, Git itself does see the *. Now Git gets a chance to do glob expansion, and in Git's case, Git does match .-files like .gitattributes and .gitignore. So if the current working directory has no non-dot-files, but does have .gitattributes and .gitignore, and you run:

git checkout -- *

然后在这种特殊情况下,Git 会将 .gitattributes.gitignore 从索引复制到工作树.

then in this particular case, Git will copy .gitattributes and .gitignore from the index to the work-tree.

这篇关于之间的区别.git中的(点)和*(星号)通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆