Git 如何在分支顶端创建分支并为其创建单独的拉请求?
我正在同一个文件中进行小的功能更改。但是这些更改是不相关的,这就是为什么它们必须在单独的拉取请求中 因此,我从我的项目Git 如何在分支顶端创建分支并为其创建单独的拉请求?,git,github,Git,Github,我正在同一个文件中进行小的功能更改。但是这些更改是不相关的,这就是为什么它们必须在单独的拉取请求中 因此,我从我的项目staging分支创建了一个分支: git签出-b分支 对它做了一些工作并创建了pull请求 现在,由于我将在单独的PRs中做更多的小更改,我不想等到这些PRs得到批准,然后合并并重新设置基础,直到我可以开始开发下一个功能。此外,我希望避免基于暂存创建单独的分支,然后在批准每个PR后必须处理合并冲突(因为所有更改都在同一个文件中) 有没有办法做类似的事情 git checkou
staging
分支创建了一个分支:
git签出-b分支
对它做了一些工作并创建了pull请求
现在,由于我将在单独的PRs中做更多的小更改,我不想等到这些PRs得到批准,然后合并并重新设置基础,直到我可以开始开发下一个功能。此外,我希望避免基于暂存创建单独的分支,然后在批准每个PR后必须处理合并冲突(因为所有更改都在同一个文件中)
有没有办法做类似的事情
git checkout -b branch2 branch1
然后从这个分支创建一个PR,它只包含在branch2中完成的提交?我尝试过这样做,但它从
branch1
一开始就推送了所有提交。您可以完全按照您提到的方式创建新的分支名称,但这并没有达到您想要的效果。原因是。。。原因是Git就是这样。Git很复杂!GitHub试图简化这些复杂的问题,这样当您发出GitHub请求时,Git本身就没有这些东西;它们是特定于GitHub1的GitHub尝试向您展示一些非常简单的东西
不幸的是,正如您所看到的,这种简单性是假的。我认为GitHub实际上是在做一个dis服务,以简化类似这样的事情。不过,它在许多常见情况下都非常有效,很多人显然喜欢它的简化。但是因为你工作的方式,你不能让GitHub假装。它就是不起作用。相反,您需要进入真正的Git,以及它的所有复杂性。这些复杂性的存在是因为它们是必要的,对于这种分布式开发,至少在最复杂的情况下是必要的(有些情况你可能永远不会遇到)
1 GitHub的其他竞争对手提供自己的拉取请求,因为PRs非常有用。如果没有PRs,这些竞争对手将永远不会得到太多的利用
Git是关于提交的 首先要认识到的是Git本身与文件无关。这是关于承诺的。提交包含文件,这对我们人类很重要,但Git关心提交。Git也不是关于分支的。提交是分支的好形式,分支是分支的几种含义之一,但分支名称是分支的另一种含义,它只是帮助您和Git找到提交。这是最重要的 这意味着您需要的第一件事是牢牢掌握提交。现在,您一直在进行提交,但是人们可以在不完全了解什么是提交的情况下进行此操作,所以让我们在这里详细介绍一下。您可能已经知道了其中的一些甚至所有内容,但让我们涵盖所有内容,尽管速度很快:
- 每次提交都进行编号。这些数字是散列ID:它们看起来是随机的,但实际上是Git用来保存提交数据的内部对象内容的加密校验和。校验和算法在每个Git二进制文件中都是相同的,因此每个Git为相同的提交计算相同的ID。这就是提交如何从一个Git存储库传播到另一个Git存储库:通过hash ID commit对象是四种内部对象中的一种。其他三个是树、blob(文件数据)和带注释的标记。所有四个都由散列ID寻址。树和blob可以在任何有意义的时候重用,但提交不能。最后,提交对象始终只包含一个树对象哈希ID 您通常不需要知道提交对象的内部结构。请记住,因为散列ID是内部数据的散列,所以任何人或任何事,包括Git本身,都不可能更改任何提交的任何部分。如果您确实从内部对象数据库中取出一个提交,更改某些部分,然后将其放回,那么您得到的是一个新的、不同的提交,具有新的、不同的散列ID。旧的提交仍然存在:您只添加了另一个提交。旧提交的哈希ID仍然引用旧提交
- 这意味着每个提交都有两个部分:它的数据——所有文件的快照,由存储的树对象哈希ID表示;它的元数据,由提交对象中的内容表示。元数据包含有关提交人(姓名和电子邮件地址)、时间(某些日期和时间戳)以及原因(日志消息)的信息。对于Git本身来说至关重要的是,元数据包括一个早期提交哈希ID的列表
... <-F <-G <-H
...--G--H <-- main
...--G--H <-- feature1, main
...--G--H <-- feature1, main (HEAD)
...--G--H <-- feature1 (HEAD), main
I <-- feature1 (HEAD)
/
...--G--H <-- main
git checkout -b feature2 main
I <-- feature1
/
...--G--H <-- feature2 (HEAD), main
I <-- feature1
/
...--G--H <-- main
\
J <-- feature2 (HEAD)
J <-- feature2 (HEAD)
/
I <-- feature1
/
...--G--H <-- main
git clone <url> [<directory-name>]
git fetch origin
...--G--H <-- master (HEAD), origin/master
\
I <-- origin/feature1
...--G--H <-- master (HEAD), origin/master
\
I--J <-- origin/feature1
K <-- master (HEAD)
/
...--G--H--L <-- origin/master
\
I--J <-- origin/feature1
K <-- master (HEAD)
/
...--G--H--L <-- origin/master
\
I--J <-- origin/feature1
K ???
/
/ K' <-- master (HEAD)
/ /
...--G--H--L <-- origin/master
\
I--J <-- origin/feature1
K--M <-- master (HEAD)
/ /
...--G--H--L <-- origin/master
\
I--J <-- origin/feature1
K--M
/ /
...--G--H--L [they already have these]
\
I--J [they already have these]
K--M <-- master (HEAD), origin/master
/ /
...--G--H--L
\
I--J <-- origin/feature1
...--P--Q <-- staging
...--P--Q <-- staging, origin/staging
R <-- branch1
/
...--P--Q <-- staging, origin/staging
R <-- branch1
/
...--P--Q <-- staging
R <-- branch1
/
...--P--Q <-- staging
\
S <-- branch2
S <-- branch2
/
R <-- branch1
/
...--P--Q <-- staging