我今天发现了一个非常奇怪的问题。我们有两个团队正在处理同一个回购,但不同的分支。
让我们说,团队A在分支 AA 上工作;和团队B在分支 BB 上工作。
幽灵般的事情刚刚发生,没有任何迹象,我发现很多提交都是由团队成员从 BB 带到 AA 以及他的一个特定提交下方。
这是团队成员的提交,但父字段指向属于 BB 的提交(在我看来这是不可能的)。这可能是这个提交从另一个分支提交了大量提交的原因。
我刚跟团队成员谈过,他从不结账 BB (我看到他的回购,没有本地分支 BB ),有谁知道怎么可能呢发生?为什么?
是否可能是Git
或WebStorm
的错误? Team-A成员正在使用git 1.9.1
和WebStorm Build #WS-162.1121.31, built on July 9, 2016
。
编辑:
到目前为止,在执行git reflog
时,我发现一个有问题的命令已执行13579cd8d HEAD@{202}: reset: moving to 13579cd8
。我很确定这个团队成员不会这样做(他从来不知道有一个分支 BB ,不知道它上面的提交13579cd8
)。并且他使用WebStorm作为工具,因此可能是WS的bug,或者他有一些误操作
答案 0 :(得分:1)
一个原因可能是BB
的提交与remote/master
合并,然后team-A
的任何成员将remote/master
拉入AA
。
或者,如果team-A
成员将分支BB
直接拉入AA
(git pull origin BB
),则BB's
提交将在{{{}}中提供1}}。
答案 1 :(得分:1)
你已经剪断了太多,以至于无法判断有问题的提交是否是合并提交。我怀疑是:有人运行git merge
,可能是通过运行git pull
(git pull
运行git fetch
并在完成提取后运行git merge
或{ {1}},默认为错误的 - 我建议新用户避免使用git rebase
,因为它的便利性更像是一个陷阱而不是帮助。)
新提交的默认(单个)父级是当前提交。分支名称与此过程的这一部分无关;重要的是当前的提交。
使用git pull
进行新的普通提交时,通常会按以下顺序进行:
git commit
提交的内容不同。 (这是为了防止您意外地进行琐碎的提交,与之前的提交没有区别。)HEAD
)作为父提交ID。请注意,除了步骤5 - 更新当前分支的部分,以便现在在分支的提示处的新提交 - 当前分支的名称不要在这里进入图片。 (当然,最后一步 很重要,最后。)
有多种方法可以修改上述步骤,例如,git rev-parse HEAD
将新提交的父级设置为与当前提交的父级相同,并执行常规合并是冲突的,或者在提交之前停止(通过git commit --amend
),留下了使下一个提交记录多个父级的跟踪。当然,常规(成功)合并会使用至少两个父项写入提交,即合并提交。
除了上述内容之外,还可以通过配置项(--no-commit
和{设置两个项目符号和提交者以及相应的时间戳 - 设置为提交者喜欢的任何内容。 {1}})或通过环境变量(user.name
,user.email
等)。 GIT_COMMITTER_NAME
命令甚至还有标记GIT_AUTHOR_DATE
和git commit
来覆盖它们。
因此,有多种方法可以解决这些问题,并且分支名称是错误的重点。重要的不是名称,而是提交ID。当然,新提交 - 无论是来自--author=
的普通提交,还是来自--date=
的合并提交 - 都会在当前分支上进行,所以这里名称确实如此物质
我上面提到了几次 merge commit 。合并提交只是一个包含两个或更多父项的提交。两个以上是不寻常的 - 它被称为章鱼合并,并且大多数是在人们运行git commit
时错误地制作,因为git merge
没有做人们期望它做的事。
任何合并提交的第一个父级的处理方式与任何普通的非合并提交的 only 父级的处理方式相同:它是提交的当你合并时是最新的。 第二个父级和任何其他父级都是您作为git pull
的参数传递的所有其他提交。
请注意,如果您错误地执行了操作:
git pull
Git将其翻译成实际上: 1
git merge
第二个命令,将两个分支合并到当前分支中,是章鱼合并的原因。你有可能不希望这样。
(从这里恢复是令人烦恼和困难的,一旦它被推回。在那之前,它不是太糟糕:只要你把错误存放在你自己的Git存储库中,你可以使用git pull origin branch1 branch2
将其支持给其他人而不会产生任何后果。)
1 在git fetch origin &&
git merge origin/branch1 origin/branch2 # DANGER
步骤中存在一些细微的技术差异,因为它实际上是由git reset
中记录的提交ID和显式合并提交完成的使用例如" branch' branch1'的消息。远程'起源'"作为它的字符串,而不是"远程跟踪分支" origin / branch1'"作为它的字符串。但的想法是一样的。