git:看起来不像分支的分支

时间:2018-11-06 08:42:57

标签: git github merge phpstorm

我从来没有掌握过git的窍门,而且我只从事断断续续的编程工作,所以我忘记了项目的状态。目前,我不了解git告诉我的有关旧分支的信息。

git branch -a说:

  dashboard
* master
  php7
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/php7

因此它说除了master之外,我还有两个分支:dashboardphp7。我清楚地记得php7-涉及很多提交,这是一项很大的工作。我不记得dashboard,但是名字告诉我它与哪个文件有关。

git branch --merged说:

  dashboard
* master
  php7

因此,显然两者都合并了。但是php7在远程是已知的,而dashboard在远程是未知的。我不记得我为达到这一点做了什么git命令。

当我查看PHPStorm中的日志(或使用git log --graph)时,这两个看起来与我希望分支看起来的样子不一样-上面没有提交行。这是日志的最新部分: enter image description here

奥秘(至少对我来说):

  • 我记得在php7分支上所做的提交都与master在同一橙色线上。如果我合并然后删除了分支(逻辑分支),为什么它仍仍列为分支?
  • 为什么php7分支的最后一个额外的“起源”标签?我认为最近的推送会导致远程看起来像本地,在最近的提交中只有一个“来源”标签。当然,远程不会认为php7尚未合并-这将是可怕的,因为该代码很关键。
  • dashboard根本不为远程用户所了解(https://github.com/OsakaWebbie/kizunadb)-怎么可能?

另一方面,在日志的前面,有一个非常明显的分支,该分支具有两次提交然后被合并,但不在分支列表中: enter image description here 我很乐意删除它(我不会保留旧的分支机构来留恋),但是git branch -d texlabels说:error: branch 'texlabels' not found.日志中看起来最分支的东西不是分支吗?我的头很痛。

我确定您git gurus会立即知道这一切的含义以及如何清理它-我期待您的澄清。

更新:

感谢卡塔的彻底回答(很可能会被接受)。但是我有一些后续问题,很难在很小的注释中阅读(我希望注释可以更长,格式更多),所以请耐心一点。我想可以通过评论或通过添加任何答案的Kata来回答这些问题。

  

因为不确定过去的php7是否已合并为master。

如果不确定php7是否已合并,为什么将其列在--merged中? (git对任何事情都“不确定”的想法让我担心...)我不知道以后如何移动分支头,因此这种情况不太可能发生。但是,有一段时间我在本地做某事导致Github拒绝推送(我想我可能已经将文件修改为已经推送的提交)-有人帮助我查看了一下,最后我做了{{1} }(我是唯一的开发人员)。也许这导致了指针错位...

无论如何,我知道 push -f代码是我当前代码库的一部分,因为它现在很高兴在PHP7上运行。我认识到在该分支上已经完成了一些提交。实际上,从创建php7到合并之前的所有 all 次提交都可能在该分支上完成(即,没有回滚到master来修复bug)。与此同时)。这样可以解释为什么DAG中的主行旁边没有多余的行吗?

如果是这样,那么php7可能是我打过的唯一一个要修复master上的错误的分支,因为它是DAG中唯一的额外行。另外,没有其他分支具有“合并某某”的条目-是因为没有任何主提交,合并就不需要更改任何内容(只需移动指针)?

  

因为texlabels是在本地创建的,并且从未推送到远程。

哦,我没有意识到基本的推送不包含分支信息。显然Github知道dashboard,因为毫无疑问我在签出时进行了推送。 (是吗?)

我现在还了解了标签,并且在将项目部署到具有PHP7和其他差异的新服务器上时创建了标签。只要我当前的代码库仍然是我的当前代码库,我将很高兴不再拥有php7php7分支。但是,如果您说它们的合并状态存在一些不确定性,那么删除它们是否安全? (删除东西听起来很吓人,但是如果只是指针...)

更新#2:

在卡塔(Kata)提到没有dashboard的情况下,我可能看不到所有内容,因此在使用/不使用该标志之间进行了区分。我发现在--all工作的一开始,就重复了前四次提交,首先是在“看上去很粗an”的分支上(仅在php7中看到),然后在主行上其他一切。这是来自--all的相关代码段:

git log --graph --decorate --all --oneline

我猜这很奇怪,这是由于我不小心在我的VM上使用命令行执行了四个操作中的两个(“删除.idea ...”和“较小的编辑”)而不是其余的OsakaWebbie而造成的。其中。 (用户没有显示在* 3b1c25a Removal of .html files (won't work with the new server config) and $client in db connect file * dccc3f3 minor edits * 20a1aab remove .idea files from repo * 629d891 Second day of cleanup for PHP7: various things, hacking away at errors one at a time (note: I * a669fa0 First day of cleanup for PHP7: * mysql_ to mysqli_ (major functions, anyway) * convert my | * 51738d1 (refs/original/refs/heads/php7) minor edits | * f1aa0f9 remove .idea files from repo | * 38aef9b (refs/original/refs/remotes/origin/php7) Second day of cleanup for PHP7: various things, ha | * cfcaa51 First day of cleanup for PHP7: * mysql_ to mysqli_ (major functions, anyway) * convert |/ * 294ef21 Feature: batch category delete 中,但是您可以在Github上看到它。)但是无论如何发生,我都假设删除分支后第一组(cfcaa51至51738d1)将消失。 ,但是由于它们是重复的(而且我知道我当前的代码库反映了那些提交中的更改),所以应该可以,对吧?

2 个答案:

答案 0 :(得分:3)

您最好将分支视为(或指针)。 git log向您显示的是DAG个提交和一个指向特定提交的标头列表。您当前所看到的类似于:php7头指向此提交。您过去无法知道php7头的移动情况,因为git允许我们自由移动头。

对于git branch --merged [<commit>],查看其document,该命令仅显示可以从<commit>到达的所有磁头。在您的情况下,<commit>HEAD,表示master。因此结果很明显:dashboard可以访问masterphp7HEAD请注意,默认情况下git branch不显示远程磁头,为此添加-a选项

现在,我认为您的问题可以得到解答。

  

我记得在php7分支上所做的全部与master相同。如果我合并然后删除了分支(逻辑分支),为什么它仍然仍列为分支?

因为不确定以前的php7是否已合并到master中。即使是这样,也可能总是在某个时刻以后php7 被移动了,所以我们看不到php7引起的合并的痕迹。

  

为什么在php7分支的最后一个额外的“原始”标签?我认为最近的推送会导致远程看起来像本地,在最近的提交中只有一个“来源”标签。当然,远程不会认为php7还没有被合并-这将是可怕的,因为该代码很关键。

该标签仅表示当前有2个标头-php7origin/php7-指向该提交。

  

完全不知道仪表板(https://github.com/OsakaWebbie/kizunadb)-怎么可能?

因为dashboard是在本地创建的,并且从未被推送到远程。

  

我很乐意将其删除(我不会保留旧的分支来留恋),但是git branch -d texlabels说:错误:找不到分支'texlabels'。日志中看起来最分支的东西不是分支吗?我的头很痛。

您知道texlabels头的存在是因为您在提交消息中看到了它的名称。但是实际上该磁头是过去删除的,因此您现在不能再次删除它。

更新:

要回答@OsakaWebbie的更多问题

--merged选项的命名基于以下事实,即在正常开发中(例如,您不会异常移动磁头,例如使用git reset),如果头child可以到达头parent,这意味着parent在过去的某个时候已合并到child中。换句话说,child确实继承了parent

----------------------- child
         /
        /
     parent

但是我对此很同情,实际上complaints是关于git命令及其选项的命名的。

回到您的php7头的故事中,我认为现在情​​况应该很清楚。

合并不一定会导致两条路径合并为一条。确实,正如您所告知的,由于您切换到php7并附加了46个提交,因此您没有对master附加任何提交,因此合并之前的历史记录如下:

----------------- master
                    \
                     ----------------- php7

然后,您切换回master并进行合并:git merge php7。因为php7master的子代,所以合并的结果应该恰好是php7。因此,git会简单地向前移动master并将其指向php7所指向的提交。这种合并称为快进。然后,您将拥有:

-------------------
                    \
                     ----------------- php7, master

本质上是:

-------------------------------------- php7, master

但是texlabels头的合并并没有实现快进。您创建了头部,切换到头部,进行了编码并附加了一些提交。然后,您切换回master,也进行了编码并附加了一些提交。所以你有:

----------------- master
     \
      ----------- texlabels

如您所见,texlabels不是master的子级。因此,这不能算是快进,将texlabels合并到master中将导致:

----------------- (old master) -- master
     \                         /
      ----------- texlabels

这就是为什么它是历史上唯一看起来像树枝的东西。

关于您的最后两个问题:

  

哦,我没有意识到基本的推送不包含分支信息。显然Github知道php7,因为我无疑在签出时进行了推送。 (是吗?)

git push <remote> [<head>]仅推送提供的<head>(当然还有其祖先提交)。如果未提供<head>,那么将使用HEAD所指向的头部-在您的情况下为php7。要推动所有操作,请使用--all选项。

  

但是,如果您说它们的合并状态不确定,是否可以安全删除它们? (删除东西听起来很吓人,但是如果只是指针...)

是的,heads只是指针,但请注意:删除head后,某些提交可能会被放弃-即,无法从任何head到达它们-并且将由{{1清除(删除)) GC中的}}。如果您确定要删除什么,请继续。


更多注意事项:

  1. git与此处无关,它会在远程(例如losing some commits)而不是本地引起意外情况。
  2. 默认情况下,push -f仅显示可以从git log到达的提交,请使用HEAD选项显示所有提交。

更新#2:

关于4个额外提交

很有可能您在提交--all时发布了51738d1 minor edits command,以对这4个提交进行大量修改(我猜是修改作者的名字)。然后您创建了4个新的提交(从a669fa0到3b1c25a)。 4个旧提交(从cfcaa51到51738d1)仍然存在,因为仍然可以从头git filter-branch到达它们。这些头是由refs/original/...的备份机制创建的。

delete those 4 extra commits绝对安全。它们与4个“主要”提交完全无关。

答案 1 :(得分:0)

git merge命令默认使用fast forward合并分支。这就是图表看起来像这样的原因。如果要在图形中查看单独的分支,请在合并时使用git merge --no-ff <branch-name>。这样会阻止快速转发。