【问题标题】:Understanding Git Graphs了解 Git 图
【发布时间】:2013-04-27 14:53:03
【问题描述】:

我是 Git 新手,需要帮助理解 Git 历史图表,即提交和合并之间的关系,因为它们在 SmartGit 或 GitGui 等工具中显示在图表上。在下图中,红色提交之间的关系是什么,特别是“IA-481”和“合并分支IA-481(Release2)......”我主要是因为“IA-481”打算去在一个名为“IA-481(Release2) 的分支中,而不是在 Master 中。

所以这里有更多细节:

  1. 我最初在一个名为“IA-481(Release)”的分支中签入了我的文件。
  2. 然后我切换到 Master,从 Master 分支调用 merge,将“IA-481(Release)”中的文件与 Master 合并。我又做了一些更改,但意识到现在提交给 Master 还为时过早,所以我没有提交给 Master。
  3. 相反,我创建并切换到另一个名为“IA-481(Release2)”的新分支,并将合并的文件提交到第二个新分支(而不是 Master)。
  4. 其他人切换到 IA-481(Release2) 分支来检查我的工作,并进行了一些检查。

后来我们发现我最初对“IA-481(Release2)”分支所做的 IA-481 提交不知何故在主分支中结束了。我正试图弄清楚它是如何到达那里的。是由另一个人将它与 Master 合并的名为“Merge branch IA-481(Release2)”的提交,还是在我的 IA-481 签入时已经在 Master 中。哪个提交出错了?

【问题讨论】:

标签: git version-control git-merge git-commit revision-history


【解决方案1】:

IA-481 是在与 master 分开的分支上的提交。然后在您突出显示的合并提交处将该分支合并到 master 中。

【讨论】:

  • IA-481 不应该被合并。有人有意识地这样做还是以某种方式自动发生?所有合并的文件都没有出现在我突出显示的合并提交下。它们出现在 IA-481 提交下,这使得它们看起来像是在 IA-481 提交中合并的。这是真的吗?
  • @John git log -1 <sha of "Merge branch 'IA-481(Release2)'"> 告诉您谁提交了合并? (或者,突出显示 gitk 或任何存储库浏览器中的合并提交,并查看提交消息 - 它应该告诉您谁将包含 IA-481 的分支合并到 master 中。)此外,通常,唯一出现的文件由合并提交本身修改的是那些必须解决的冲突。
  • "Merge branch 'IA-481(Release2)" 提交显然是由其他人完成的,而不是我。但是因为不需要的文件在我的签入(IA-481)下,而不是他的,所以我被指责为错误。有道理?我试图自信地证明那不是我。
  • 嗯,合并到master 的人是对master 进行更改的人。在此之前,这些更改仅存在于 IA-481 分支上。他们是否应该有一个不同的问题(这些文件真的需要更改/添加/删除/无论如何?)。如果您没有进行合并提交,那么您就不是“破坏构建”或任何问题的人......
  • “在此之前,这些更改仅存在于 IA-481 分支上”——该图是否确实证实了这一点?由于 IA-481 签入出现在上面 Master 分支的图表中,其中我的名字和不需要的文件作为提交的一部分,另一方的论点是我是将它们签入 Master 的人。
【解决方案2】:

提交引入了变化。当在同一个分支上一个接一个地提交时(正常情况),更改是累积的。创建分支时,在一个分支中所做的更改不会出现在其他分支中。需要合并才能合并独立的更改。

考虑以下简单的历史。提交修改单个文件。每次提交后的文件内容以双引号显示。 commit 0是第一次commit,commits 1到4加上他们commit number的英文名,commit 5合并commits 3和commits 4引入的变化。

*   commit 5: "one two three four"
|\  Merge: 3 4
| | 
| |   
| * commit 4 "one two four"
| | 
| |   
* | commit 3 "one two three"
|/   
|  
* commit 2: "one two"
| 
|  
* commit 1: "one"
| 
|  
* commit 0: ""

提交 4 是在不同的分支上进行的。它对应于提交 IA-481。大概这个提交引入了一些更改,并且在提交“Merge branch IA-481(Release2)....”中,这些更改已集成到主分支中。这是处理多个事情时的正常工作流程:分支,提交更改,然后将它们合并到主分支中。如果没有合并,更改只会放在单独的分支中,不做任何事情。

【讨论】:

  • 谢谢,你说的很有道理。问题/问题是提交 IA-481 中的文件不应该合并到 Master 中。他们是怎么到那里去的?在名为“合并分支 IA-481(Release2)....”的第二次提交之前,IA-481 的文件是否已经在 Master 中,或者它们仍然在自己的分支中?哪次提交出错了?
  • 提交 IA-481 中的更改看起来像是在提交“合并分支 IA-481(Release2)....”中合并到 Master 中。我认为在此之前他们不可能最终进入 Master,但您应该通过查看 IA-1617 并查看来验证这一点。考虑使用git revert(或等效的GUI)撤消合并。
  • 我实际上检查了 IA-1617(IA-481 之后的那个),并且不需要的文件不是该检查的一部分。问题是所有不需要的文件仍然出现在 GUI 中的 IA-481 提交(我的提交)下(参见上面的第二张图片),所以这似乎是我的错误。实际的合并提交只包含 1 个正确属于 Master 分支的文件
  • 请系统地检查提交。对于每个连续提交 IA-1617、IA-481、IA-1617、与分支合并 IA-481(Release2) 和 IA-1535,(a) 检查提交并查看是否出现不需要的文件和 (b)告诉我们你是否做出了那个承诺。
  • 您的回答非常有帮助。我试图为您的回答投一些票,但我是这个网站的新手,距离能够投票还有 2 个声誉点。
【解决方案3】:

这些图表很容易解释。不同的提交是点,所以如果您只是更改某些内容并进行提交,您会得到另一个与前一个提交相关联的小点。

如果你进行分支,你可以获得多个点连接到上一个提交。

如果您合并多个以前的提交,将连接到您的新点。

所以 IA-481 是在与 master 不同的分支上的提交(但它是按时间顺序排序的,这就是为什么它显示在作为 master 提交的 IA-1617 和 IA-1617 之间)并且它被合并到 master 分支在倒数第二个亮点。

您最后一个突出显示的点是另一个合并,但这次是远程分支。

还有什么不清楚的地方吗?

【讨论】:

  • 尚不清楚为什么 IA-481 会成为大师。我将它检查到一个分支,但我被指责为它成为大师。那么是我的错,还是签入“合并分支 IA-481(Release2)”的人的错? IA-481 的所有不需要的文件都出现在 IA-481 提交下,而不是“合并分支 IA-481(Release2)”提交下。由于这是 Master 分支的图表,看来是检查 IA-481 提交的那个(我)的错,这些文件才提交给 Master。真的是我的错吗?查看其他图表。
  • 好吧,是的,它到达那里是因为您突出显示的合并提交,并且它是(1)您将它检查到最终将在 master 中的分支的错误(2)的错误合并的人(用于合并不应合并到 master 的分支)(3)您的流程中的错误 :)
  • 我签入的内容应该签入分支,而不是 Master(至少现在还没有),据我所知,我签入的是分支,而不是 master。图表是否证实了这一点?
  • 据我所知,您需要显式调用 git merge 来合并两个分支。但我当然不知道你是否有某种工具可以为你完成它。然而,应该有一些与该合并提交相关联的名称。
  • > 我签入了一个分支,而不是 master。图表是否证实了这一点? 它既不证实也不相反。您需要知道谁是第一个将不需要的文件带入 master 的提交者。我不知道您使用的图形工具,但在命令行git cat-file commit <sha-1> 会显示原始信息。但请注意:提交者信息可由用户配置,如果有人想伪造它,git 不在乎。也可以重命名分支。所以昨天的分支 foo 现在可能是分支主。这些问题可以通过签名来预防/追踪。
【解决方案4】:

其他答案似乎冗长。

从另一个分支合并会带来来自该分支的更改。您似乎认为您必须合并,然后提交合并。这是不正确的 - 合并本身一个引入其他分支更改的提交。

编辑:@tom 是正确的。如果存在合并冲突,则必须在将冲突标记为已解决后主动提交合并。

【讨论】:

  • 这对我来说是个新闻。我的印象是您必须提交合并。那么合并后提交的意义何在???
  • @John 如果没有冲突,合并会创建一个提交。如果存在冲突,您必须解决它们,然后手动提交。
  • 我不确定您使用的是哪个工具,但使用 SmartGit,合并文件只有在您主动调用 commit 时才会提交,无论是否存在冲突。
  • @John 我指的是git merge
  • @John - 我不使用任何特殊工具。我正在解释 git 本身的功能,bu 默认。值得一提的是,无论您使用哪种工具,合并提交 合并。如果你不提交它,它就永远不会发生,相反,如果有一个合并提交,那就是在引入合并的更改时。
【解决方案5】:

你试过@gary 提到的吗?我觉得您可能错过了很多 cmets,但这应该根据您的问题和 cmets 有所帮助。

git 日志链接:git log manpage

--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]] 
Select only files that are Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have   their type (i.e. regular file,
symlink, submodule, …) changed (T), are Unmerged (U), are Unknown   (X), or have had their pairing Broken (B). Any combination 
of the filter characters (including none)   can be used. When * (All-or-none) is added to the combination, all paths are 
selected if   there is any file that matches other criteria in the comparison; if there is no file that matches   other 
criteria, nothing is selected. 

所以这个命令会告诉你添加 newAddedFile.c 文件的提交

git log --diff-filter=A -- newAddedFile.c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-31
    • 2023-04-04
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    相关资源
    最近更新 更多