- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近习惯了水银后开始使用git。
通常,如果我对某些文件进行hg add
编码,然后对hg diff
进行编码,那么我会得到一个补丁,然后可以用理论上简单的patch -p1
对其进行应用,并获得完全相同的本地副本。
现在,使用git,情况有所不同:在git diff
之前先使用git add
。但是,如何使git diff
也覆盖所有未跟踪的文件,例如hg diff
ing之后的hg add
?
最佳答案
TL; DR:添加所有内容,然后运行git diff --cached
Mercurial和Git在这里有不同的哲学。 Git显式公开了Git所谓的索引。 Mercurial没有索引(它在内部具有相似的东西,但是不公开它,因此您甚至不必知道它的存在)。许多喜欢Git的人认为暴露指数非常好,并且许多诅咒Git的人都认为可怕。 :-)尽管如此,这就是您遇到的问题,如果您使用的是Git,那么您正在使用索引,因此现在该学习它的含义和如何处理它了。
因此,让我们定义“索引”。 Git的索引(也称为暂存区,有时也称为缓存)是一个复杂的小野兽,具有许多Git通常不会暴露的隐藏方面。但是,它确实有一个简单的定义,您需要知道:在此构建下一次提交。
这里值得一提的是Git和Mercurial之间的另一个区别。 Mercurial存储更改(技术变更集),而Git存储快照。在大多数情况下,这并没有真正的区别。快照很容易转换为变更集:只需将快照与其父对象进行比较即可。给定父级快照,更改集可以轻松转换为新快照:只需应用更改集即可。但是,应用很长的变更集链很慢,因此Mercurial会定期存储快照。它在幕后完成所有这些操作,您无需了解它。像往常一样,Git公开了所有内容(这种方式有点像flasher或streaker,赤裸裸地跑着,暴露出没人真正想看到的悬空碎片)。
运行git commit
时,Git会将索引中的内容转换为提交快照。因此,git add
将文件放入索引。如果文件已经存在,则git add
用工作树中获取的新版本替换现有副本。如果文件尚不存在,git add
将工作树版本作为新文件放入索引中。无论哪种方式,索引版本现在都可以更新(暂存)并准备好进入下一个快照。
要从索引中取出文件,可以运行git rm
。这将从索引和工作树中删除文件。或者,您可以运行git rm --cached
,它仅将其移出索引,而将其保留在工作树中(但请注意,因为这可能会成为将来的陷阱)。
现在,由于索引/登台区域/缓存是这样暴露的,因此您可以对其进行git diff
编码。为此,请使用git diff --cached
或git diff --staged
(它们具有完全相同的含义;我通常坚持使用--cached
,因为git rm
具有--cached
而不是--staged
)。
问题在于,这仅差异索引中已更新的文件。更确切地说,它运行的等效项为git diff HEAD <index>
,即,它将当前提交与索引的内容进行比较。这意味着您在工作树中已修改但尚未暂存的任何文件都不会进行比较。但是,解决方案很简单:只需git add
这些文件。
撇开:.gitignore
和未跟踪vs被忽略
一次添加一堆文件很麻烦,因此您可能想使用git add .
或git add -A
(它们有些微不同;请参阅其他StackOverflow问题和答案,并请注意,围绕Git 2.0版进行了很大的更改,影响了-A
选项这里)。但是,您的工作树通常包含您不想添加的文件,这是我们进入未跟踪文件与未跟踪并忽略的文件的时候。
现在我们知道索引是什么了,对于Git而言,对未跟踪的文件有一个非常简短的定义。未跟踪的文件是不在索引中的文件。就是这样,仅此而已。如果在索引中,则会对其进行跟踪。如果不是,则不是。
但是,当然有一个复杂的问题(Mercurial中也有):如果您有一堆未跟踪的文件,则版本控制系统会对它们产生很多抱怨。要关闭它,可以将文件名或全局模式添加到.gitignore
。请注意,与Mercurial不同,您不能将正则表达式添加到.gitignore
,而只能添加glob模式。这既好(全局模式更容易正确实现)也很差(全局模式不如完整的正则表达式强大),但是无论如何,它就是它。1.gitignore
中列出的文件不会自动与git add -A
或git add .
添加。但是,在.gitignore
中列出文件并不会使其无法跟踪。 使文件无法跟踪的唯一原因是它不在索引中。如果您不小心将文件放入了不应跟踪的索引中,则必须从索引中对其进行git rm
编码。
撇开:强大的索引功能可以为您提供
从Mercurial迁移到Git的人们通常最初确实讨厌指数。使得它对许多人来说更可口的一件事是git add -p
。某些人对此根本没有用,但是对于那些这样做的人,这实际上是相当不错的。
Git为您提供的“添加到索引中的内容,将在下一次提交中”和“工作树中的内容”之间的分隔意味着您可以 checkout 分支,出于调试目的而修改某些项目,其他项目(在相同或单独的文件中)以解决问题或添加功能,然后有选择地仅添加错误修复或新功能,而不添加调试更改。
当您用git commit
结果时,您将获得仅具有错误修复或新功能而没有额外调试的提交。
通常,这既有优点也有缺点。例如,很难确保您刚刚提交的内容确实有效。也许只有额外的调试才能使它工作。也许您忘记了对它的某些部分进行git add
。但是,由于Git鼓励
“修改”和重写commits2,使提交和分支确实便宜,在Git中工作的方式与在Mercurial中不同。 Mercurial分支较重,其提交和重新设置以及hg histedit
明显较慢,这不鼓励这种快速而松散的commit-recommit-rebase-fixup-squash工作。 Git强烈鼓励这样做。您应该以不同的方式使用Git,在许多临时分支上进行大量临时提交。您不必这样做,但是尝试一下是个好主意。
1Mercurial在.hgignore
中支持glob模式和正则表达式。不幸的是,在实践中,正则表达式(很难正确使用)比全局模式要快得多。我曾让同事将glob改为regexp以提高速度,但后来弄错了。如果要将glob模式转换为正则表达式,请记住将其 anchor 定,并注意.
!
2在Mercurial和Git中,提交都是永久性的。但是,两者都提供了历史记录编辑和commit --amend
。它们以不同的方式到达那里:Git通过复制旧提交来提交新提交,并移动分支名称以指向新提交。这将在存储库中创建“废弃”对象。 Git使用所谓的reflog保留它们一段时间,以便您可以在需要时对其进行恢复,然后最终使reflog条目到期,并“垃圾收集”剩余的垃圾以完全清除它。
Mercurial实际上无法做到这一点,因此,它“剥离”变更集,将其放入剥离备份导出的变更集文件中。然后,如果您想将它们重新导入,则可以将其重新导入。这比Git的“重写历史记录”方法的松散-松散的“提交,重新提交,移动分支指针,放弃旧对象”方法要慢得多。由于Git的方法在时间和空间上花费更少,因此您可以重写的临时提交通常非常接近于免费,尽管这确实取决于“松散对象”文件的大小,这样做更有意义。在Git中。
关于git - Git相当于 Mercurial 添加+ Mercurial 差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41825958/
我时不时地输入“git”,然后想到别的东西,然后输入例如“git checkout master”。当然,这给我留下了 $ git git checkout master git: 'git' is
我做到了 git 克隆 git://foo.git 光盘富 ...编辑文件.. 现在我想重新开始。我不在乎我已经做出的任何改变,但我不想再次克隆整个巨型 foo.git,只是丢失我所有的更改。我怎
我在我的电脑上开发代码,我的计算节点很少。 为了让我的程序保持同步,我决定使用 git。以前,我以一种单向模式使用它来“下推”从 PC 到计算节点的更改。但是时不时遇到计算节点特有的小bug,现场修复
虽然它似乎什么也没做,但它没有给出任何警告或错误消息。有什么想法吗? 最佳答案 来自 Git 源的注释: /* * Read a directory tree. We currently ignor
我知道如何为这样的 HTTPS 请求提供用户名和密码: git clone https://username:password@remote 但我想知道如何像这样向 Remote 提供用户名和密码:
Git GUI、Git Bash 和 Git CMD 之间有什么区别?我是初学者,为了进行安装,我发现自己通常同时使用 git bash 和 git CMD 最佳答案 Git CMD 就像使用 git
有人能告诉我git中文件索引被删除是什么意思吗?这些文件在我的 VS Code 中标记为红色,但我仍然可以修改文件并将更改推送到将反射(reflect)这些更改的远程存储库。我认为这一切都是在我使用命
我通过 git 子树将 GLFV 库添加到项目中,但出现此警告“看起来您的 git 安装或您的 git-subtree 安装已损坏”。还描述了几个原因,为什么这可能是: 如 git --exec-pa
我有需要外部 git 项目的 repo,但我不想使用子模块,因为我想在 github 上存档所有文件,所以我认为我只是将具有 git repo 的整个目录添加到 git 但它不t 添加里面的 .git
我有需要外部 git 项目的 repo,但我不想使用子模块,因为我想在 github 上存档所有文件,所以我认为我只是将具有 git repo 的整个目录添加到 git 但它不t 添加里面的 .git
我一直在阅读一篇文章,作者在其中指示:在现有存储库中创建一个新存储库,并想知道这是否是他忽略的错误。稍后我会与他核实。 这些是我要检查的条件: 将现有目录制作成仓库的条件,并且已经 checkin 主
我确实在不同的计算机上处理相同的项目,我想知道是否有一种方法可以跟踪该 .git 文件夹,这样我就不必在所有本地文件中重新配置配置文件。 我将所有工作推送到 bitbucket。 最佳答案 不,没
这个问题在这里已经有了答案: How does git store files? (3 个答案) 关闭 9 年前。 我为我的许多项目创建了一个远程存储库,所以它是我的push 的目的地。与 git
应该如何在 git 中查看文件内容的完整历史记录? 一个文件在 git 中的历史很短,存储库通过 git-svn 同步,但在 svn 中的历史很长。 git 中的历史记录到达文件移动的位置。要查看历史
我是confused here ... 如何对修改后的文件进行git commit,以及如何对新文件进行git commit? 还有,你如何在git中单独提交文件? 最佳答案 git 提交过程分为两个
正在搜索 throw SO 来寻找答案。遇到这个似乎没有给出任何答案的旧线程。重新触发此线程,希望有人知道! 有人能告诉我 git subtree 和 git filter-branch 的区别吗?为
我想知道是否有一种方法可以避免在每个 Git 命令的开头键入单词 git。 如果有一种方法可以在打开命令提示符进入 “Git 模式” 后只使用一次 git 命令就好了。 例如: git> 之后,我们键
当您修改工作目录中的文件时,git 会告诉您使用“git add”暂存。 当您向工作目录添加新文件时,git 会告诉您使用“git add”开始跟踪。 我对这两个概念有点困惑,因为我假设跟踪文件的更改
为什么 git://有效 $ git clone git://github.com/schacon/grit.git Cloning into 'grit'... ... Checking conne
我在以下沙箱中练习 git:https://learngitbranching.js.org/?NODEMO 我在两个单独的 session 中运行了两组命令。第一组命令顺序如下: git clone
我是一名优秀的程序员,十分优秀!