Git子分支删除父分支的更新

Git子分支删除父分支的更新,git,merge,bitbucket,pull-request,Git,Merge,Bitbucket,Pull Request,好的,我对git(使用BitBucket)有一个奇怪的问题 我有以下(示例) 发展分部 子分支 现在在子分支中,我做了大量的返工,但在同一时期,我还修复了一些错误,即通过从开发分支中的另一个子分支拉取请求进行合并。现在,当我从子分支向开发分支发出拉取请求时,它希望删除对开发分支的修复。但是,当我想将开发分支合并到子分支中时,对开发分支所做的修复不会合并到子分支 我是否在流程中做错了什么?有没有一种方法可以在不手动检查每个文件中的差异的情况下修复此问题?TL;博士 分支名称的工作方式与您认

好的,我对git(使用BitBucket)有一个奇怪的问题

我有以下(示例)

  • 发展分部
    • 子分支
现在在
子分支
中,我做了大量的返工,但在同一时期,我还修复了一些错误,即通过从
开发分支
中的另一个子分支拉取请求进行合并。现在,当我从
子分支
开发分支
发出拉取请求时,它希望删除对
开发分支
的修复。但是,当我想将
开发分支
合并到
子分支
中时,对
开发分支
所做的修复不会合并到
子分支

我是否在流程中做错了什么?有没有一种方法可以在不手动检查每个文件中的差异的情况下修复此问题?

TL;博士 分支名称的工作方式与您认为的不同

考虑到您想要做的事情,您可能需要一个面向再基础的工作流程,例如。请记住,rebase意味着将一些提交复制到新的和改进的提交,然后移动分支名称以使用新的和改进的提交,放弃现在旧的和糟糕的提交。这意味着每个使用重基分支的人都必须准备好放弃旧的提交

长的 分支,或者更准确地说,分支名称,没有父/子关系。分支名称只是附加到(或指向)特定提交的标签

但是,提交确实具有父/子关系。特别是,用于进行新提交的命令序列如下所示:

git checkout somebranch
[edit various files]
git add file1.ext file2.ext
git commit
                I'-J'
               /
...--F--G--H--K   <-- develop
            \
             I--J
git checkout
步骤意味着选择命名的分支,通过这样做,选择分支名称选择的提交。这会将提交的内容复制到索引(也称为暂存区域)和工作树或工作树中,该内容在Git中是所有文件的完整快照,以特殊、只读、Git压缩格式存储。1

当然,编辑步骤可以处理工作树中的那些文件

git add
步骤将您所做更改的更新工作树文件复制回索引/暂存区域,最后一步,
git commit
从索引中的副本创建一个新的快照,并将其冻结为文件的所有时间副本。您没有使用
git add
覆盖的任何文件仍然与以前的
git签出时的文件相同,因此新快照包含所有未更改的文件,以及任何已更改的更新文件(视情况而定)

但是,新提交是先前标记为提交的子级。以前的提交没有改变任何东西,即使是Git本身,都不能在提交完成后改变它,但是现在它有了一个子提交。刚刚进行的子提交记录了其父提交的原始哈希ID。所以这种联系只有一种方式,向后,从孩子到父母。由于子项是一个新的提交,因此它将获得一个新的、唯一的哈希ID

git commit的最后一个关键步骤是将新的提交哈希ID写入分支名称。也就是说,标签不再指向上一个父提交,而现在指向子提交

这意味着我们从一系列提交开始,每个提交都有一个唯一的(大而难看的)散列ID,我将在这里用一个大写字母替换:

... <-F <-G <-H   <-- develop
我们现在需要一种方法来记住您使用的分支名称。为此,我们将特殊名称
HEAD
附加到一个分支。如果您
git checkout develope
,我们将名称
HEAD
附加到
develope

...--F--G--H   <-- develop (HEAD), feature
...--F--G--H--K   <-- develop (HEAD)
            \
             I--J   <-- feature
无论哪种方式,您都在使用commit
H
,但您是通过附加到/指向commit
H
的两个名称之一来实现的。(同时commit
H
指向commit
G
作为其父级,而
G
指向
F
,依此类推。)

现在,您可以修改工作树中的一些文件,
git add
将它们复制回索引/暂存区域,
git commit
进行新的提交
I
。下面是当您使用
功能时发生的情况:

...--F--G--H   <-- develop
            \
             I   <-- feature (HEAD)
名称
develop
功能之间没有父/子关系。它们只是标识特定提交的标签

Git中的分支和标记名就是这样工作的:它们标识提交。分支名称和标记名称之间的区别是:

  • 分支名称会随着时间的推移而移动。事实上,它们是自动移动的!标记名不应移动

  • 分支名称是特定存储库的本地名称。其他存储库可以看到它们,但当您收到某人的提交时,您的Git会将它们的分支名称(如
    master
    )复制到远程跟踪名称(如
    origin/master
    )中。标记名更具全局性:如果它们具有
    v1.2
    ,并且您从中获得了提交,那么您的Git可能会创建与之匹配的
    v1.2
    。3

  • 当然,分支名称是分支名称,标记名称是标记名称:有一些较小的连锁反应,但上面两点是重要的区别


1工作树包含您和计算机上所有其他非Git程序可以使用的常规普通格式的实际文件。Git不使用这些实际文件。它使用压缩的、只读的、仅Git提交的文件,并使用索引/暂存区域进行新的提交,如上所示

2可以通过强制或删除标签然后重新创建来移动标签。但是,其他软件可能希望标签不会移动。例如,Go模块系统可以缓存标记的哈希ID,如果以后移动
...--F--G--H--K   <-- develop (HEAD)
            \
             I--J   <-- feature
...--F--G--H--K   <-- develop
            \
             I--J   <-- feature (HEAD)
                ?--?   <-- feature (HEAD)
               /
...--F--G--H--K   <-- develop
                I'-J'
               /
...--F--G--H--K   <-- develop
            \
             I--J
                I'-J'  <-- HEAD
               /
...--F--G--H--K   <-- develop
            \
             I--J   <-- feature
                I'-J'  <-- feature, HEAD
               /
...--F--G--H--K   <-- develop
            \
             I--J   [abandoned]
                I'-J'  <-- feature (HEAD)
               /
...--F--G--H--K   <-- develop