拉取请求合并父父分支后删除父分支是否安全?

时间:2015-12-07 05:39:02

标签: git github pull-request

我在GitHub上使用共享存储库模型。我创建了一个功能分支A,将一些更改推送到远程源,然后创建了一个pull请求。我想基于A进行更多更改,因此从A创建了一个新的分支B.在推送更多编辑后,我为B创建了另一个拉取请求。

接受了A的拉取请求。所以'git pull origin master'然后让我当地的主人包括A.

如果分支A有子分支,我该怎么办?B?

我明白了

$ git checkout B
$ git diff origin/master --

不再包含A diffs,如预期的那样。

•那么我可以删除分支A而不影响B吗?在接受拉取请求之后,我在master中看到A提交历史记录。

•B然后会重新成为主人吗?

•对B的现有GitHub拉取请求有什么影响?

3 个答案:

答案 0 :(得分:2)

tldr; dvcs像病毒一样提交工作

A"分支"在Git中只是一个DAG of changesets,其中HEAD提交(在该分支上)是通过分支名称访问的。如果已经提供了另一个存储库(即“推送”或“提取”)已提交的更改集,那么它们现在也存在于该存储库中。 删除本地提交与已经应用于其他存储库的提交无关。

对于从上游到工作的拉动,变更集"分支"的根。 DAG必须已经存在于上游目标上。因此,提取的数据实际上是root_from_upstream->commit(s)->head_at_pull变更集:来自上游存储库的拉动导致它将变更集应用于自身,一直到分支的头部(这是一个特定的修订版),拉请求。

删除(或者,更好,'关闭')本地分支不会删除任何变更集;它只是通过那个分支名称使它们无法访问。

即使提交被清除也是如此。从本地Git存储库(或者在Mercurial的说法中剥离')提交更改集仍然存在于推送到(或拉入)的其他存储库中。

如果从原点拉出,则将根据需要获取更改集以完成DAG。但是"分支"本身不会被重新创建,因为这样的名称是一个后来被丢弃的本地工件。

  

那么我可以删除分支A而不影响B吗?在接受拉取请求之后,我在master中看到A提交历史记录。

是。如果本地分支不再有用,则可以将其删除。提交已经传播到另一个存储库 - 即使没有,更改集仍然是分支' B' 形成的DAG的一部分。

  

然后B会重新成为主人吗?

没有。分支名称只是标识变更集图的特定提交。删除分支' A'不影响变更集/ DAG,对B'没有影响。 绝对没有隐含的重新定位。

  

对B的现有GitHub拉取请求有什么影响(如果有的话)?

没有

这就是为什么,像电子邮件一样,在推送它们之前整理提交(或者让它们被拉动)是很重要的。一旦被释放到野外,没有什么简单的方法来捕获变更集。

Mercurial的工作方式稍有不同,但提示'提示'任何特定Hg分支的工作方式与Git分支类似:它标识变更集DAG中表示当前分支HEAD的特定提交。

答案 1 :(得分:2)

让我们假设事件的顺序如下:

git checkout -b A
git commit
git commit
git commit
git checkout -b B
git commit
git commit
git checkout master
git commit
git merge A

这会给你一张如下图片:

enter image description here

在这种情况下, A非常安全,可以删除,因为您打开B的工作已包含在主数据中。

但是,B不会自动拥有新的父母;你应该考虑rebasing your branch对抗主人。这将使历史在主人的提交之后一直存在,并且将在以后减少你工作的噪音和混乱。

将其视为Dictator and Lieutenants工作流程。上游应该始终代表真理的规范来源,而且你的工作应该总是反对它。

答案 2 :(得分:0)

所以我发现我可以用脚本轻松演示user2864740和Makoto对第二个问题的回答,如下所示。

以下是答案:

+ git log --graph --oneline --branches
* a392a9d branch_B change_b2 commit
* 7c29ca6 initial branch_B change_b1 commit
| *   30591f8 merge branch_A into master
| |\
| |/
|/|
* | 34a1162 branch_A change_a2 commit
* | 2ad533b initial branch_A change_a1 commit
| * 67941a1 mergable change in master
|/
* 36d7364 initial master commit
+ git branch -d branch_A
Deleted branch branch_A (was 34a1162).
+ git log --graph --oneline --branches
* a392a9d branch_B change_b2 commit
* 7c29ca6 initial branch_B change_b1 commit
| *   30591f8 merge branch_A into master
| |\
| |/
|/|
* | 34a1162 branch_A change_a2 commit
* | 2ad533b initial branch_A change_a1 commit
| * 67941a1 mergable change in master
|/
* 36d7364 initial master commit

它表明,实际上,删除A对树没有影响。

这是脚本,其他人可能会发现有用于测试git序列的脚本:

#!/bin/bash

d=_test_`date +"%y%m%d%H%M"`
mkdir $d
cd $d
echo Testing in `pwd`

set -x  #echo on

# init and make master
git init
touch f
echo master1 >> f
git add .
git commit -a -m'initial master commit'

# make branch A
git checkout -b branch_A
echo change_a1 >> f
git commit -a -m'initial branch_A change_a1 commit'
echo change_a2 >> f
git commit -a -m'branch_A change_a2 commit'
cat f

# commit on master so we can see the branching structure
git checkout master
echo change_a1 >> f
echo change_a2 >> f
git commit -a -m'mergable change in master'

# make branch B
git checkout branch_A
git checkout -b branch_B
echo change_b1 >> f
git commit -a -m'initial branch_B change_b1 commit'
echo change_b2 >> f
git commit -a -m'branch_B change_b2 commit'

# commit on branch_A so we can see the branching structure
#git checkout branch_A
#echo change_a3 >> f
#git commit -a -m'another commit on a'

# Where's B on the tree?
git log --graph --oneline --branches

# merge branch A into master
git checkout master
git merge branch_A -m'merge branch_A into master'
cat f

# Where's B on the tree?
git log --graph --oneline --branches

# delete branch A
git branch -d branch_A

# Where's B on the tree?
git log --graph --oneline --branches