在执行git diff时删除的文件模式是什么意思?

时间:2014-04-09 22:12:51

标签: git

我已经获取了原点,我在执行git diff origin / master时看到以下内容:

diff --git a/flash/controllers b/flash/controllers
deleted file mode 120000
index 350cadb..0000000
--- a/flash/controllers
+++ /dev/null
@@ -1 +0,0 @@
-/home/testapp/www/homedir/flash/controllers
\ No newline at end of file

我很困惑这是什么意思。这是否意味着如果我进行合并,文件将被删除?这令人困惑,因为我在gitignore中有/flash/controllers/

1 个答案:

答案 0 :(得分:3)

TL; DR版本:虽然下面的所有内容都很清楚,但查看合并的最简单方法是进行合并。只需确保一切都干净(例如,git status没有任何东西供您办理登机手续),然后运行合并,看看它做了什么。如果您不喜欢结果,请中止合并(如果它失败并需要帮助)或退出(如果成功,但您不喜欢结果),请使用以下方法之一:

git merge --abort  # after merge fails and asks you for help

或:

git reset --hard HEAD^  # after merge succeeds but you don't like the result

Deleted表示在比较两个文件树时,"左侧的树"比较的东西,和#34;右侧的树"不再拥有它。

mode标识文件对象的类型,120000具体表示"符号链接"。这意味着将版本a与版本b进行比较,过去在版本flash/controllers中有一个名为a的符号链接,在版本b中,不再了。

如果你只是运行git diff origin/master,左边的树(树a)是你当前的工作目录(不是特定的提交!),右边是树(树{{1} } {}是由b标识的提交中的一个(使用origin/master来查看此提交的实际SHA-1)。如果您命名两个提交,例如在git rev-parse origin/master中,则左侧的树是第一个SHA-1命名的树(再次使用git diff master origin/master来查看原始SHA-1)和树在右边是由第二个命名的那个。

  

这是否意味着如果我合并将删除该文件?

也许;也许不吧。确定合并是否删除文件的原因是 merge-base 与要合并的项目之间的差异。

例如,让我们说,上面的git rev-parse代表当前分支顶端的树,可能名为a,而master代表该树的树。您的分支的提示名为b(这是一个"远程分支",但它实际上是您的存储库中的一个分支;您只是从origin/master)复制了它。

我们不知道的是originmaster之间的合并基础。这将是一些承诺 - 我们只是不知道哪一个。

让我们说提交图,如果我们要把它画出来,看起来像这样:

origin/master

在这里,您在...-o-o-B-u <-- HEAD=master \ t <-- origin/master 分支上进行了一次提交。我为master标记了u。同时&#34;他们&#34; (无论他们是谁)在他们的分支上做了一个提交,他们称之为us并且你正在呼叫master;我为origin/master标记了此提交t。共同的出发点 - 您和他们分歧的点 - 是标记为我在此处标记为them的提交。

您可以使用B命令找到此提交的SHA-1 ID:

git merge-base

如果你这样做:

git merge-base HEAD origin/master

(假设git diff -M --name-status $(git merge-base HEAD origin/master) origin/master sh样式命令行), 1 git会告诉你哪些文件&#34;他们&#34;在提交bash中添加,修改,删除和重命名。也就是说,这会将提交t与提交B的{​​{1}}提示进行比较。

如果您将origin/master与当前分支的提示进行比较,即针对t提交,则您将看到在提交中所做的事情{ {1}}。

如果你这样做:

B

git将尝试合并&#34;你做了什么&#34;和&#34;他们做了什么&#34;。 以下是符号链接的关键,或者对于任何文件而言。一般有三种可能性,尽管只有两种可能:

  • 如果HEAD中存在符号链接,那么您可能什么都没做,他们就删除了它。在这种情况下,u会将其删除:您什么也没做,他们删除了它,结合起来很容易:删除它。

  • 如果符号链接<{1}}中存在,那么您添加了它,它们可能什么也没做。在这种情况下,git merge origin/master 将添加(好吧,保留)它。同样,这很容易合并:你补充说,他们没有做任何事情,两者的结合是&#34;添加&#34; (或者真的,&#34;保持&#34;)。

  • 如果B中存在符号链接,但已更改,并且已删除git merge将声明冲突并让你自己解决问题。这对于git来说并不容易组合,就像你不知道该做什么一样,如果你和他们都以不同的方式改变了它。 2

(我们知道,或者无论如何基于原始的B输出,与提交git merge相关联的树具有符号链接,并且与提交B关联的树不具有,所以我们不必担心&#34;两者都被创造了&#34;或者#34;两者都被修改了#34;案例。)

  

令人困惑,因为我在gitignore中有git merge

但那个git diff,带有一个尾随斜线(前面的斜线并不重要,无论如何,我认为 - 尽管忽略规则仍然让我感到困惑)。 gitignore documentation包含此位:

HEAD

(还有一个问题是,如果已经跟踪了某个文件,将其添加到origin/master并不会使其无法跟踪。/flash/controllers/内容仅用于保存来自意外地跟踪,并避免flash/controllers/抱怨他们。)


1 事实上,针对合并库获取差异具有特殊的 • If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in Git). 语法,从gitrevisions重新利用三点.gitignore语法。要查找.gitignoregit status之间的合并基础并将其与提交git diff的内容进行比较,您可以编写A...B。与往常一样,省略一端相当于指定A,因此B将合并基础(Bgit diff A...B)与HEAD进行比较;并且git diff ...origin/master将合并基础(相同的两个提交)与HEAD进行比较。添加origin/master以检测重命名,您可以进行origin/master使用的比较。

(我故意省略一些额外的细节&#34;递归定义&#34;虚拟合并基础在这里。在两个&#34;同样有效&#34;合并基础祖先的情况下,{{1将随意选择一个,但git diff origin/master...使用HEAD策略将构建一个虚拟合并库。这些有点复杂。)

2 对于大多数常规文件,如果您和他们都修改了它们,git会尝试通过决定哪些更改是独立的来组合更改(git保留每个此类更改的一个副本)以及哪些更改是相同的(git也保留这些更改的一个副本,而不是放入两个副本)。是否以及当git实际上正确关于此 - 具体来说,关于哪些更改是&#34;相同&#34;哪个&#34;不同&#34; - 是另一回事。它通常做得很好,但它只是一个计算机算法,它有时会出错,所以你,用户,必须以某种方式检查结果(例如,&#34;它仍然构建,是否通过测试,看起来没问题,无论你有什么测试,都要确定它。