tot*_*amp 3 git github pull-request
我已经在GIT上挣扎了一段时间,因为它做了一些奇怪的事情。
我有一个初始代码的基本提交。
好的,接下来我创建一个分支来进行编辑,提交和推送:
git checkout -b feature/feature1
git commit -m "added feature1"
git push origin feature/feature1
Run Code Online (Sandbox Code Playgroud)
现在,我对该功能进行拉取请求。
之后,我更改分支并更新例如:
git checkout -b chore/update-framework
git commit -m "updated framework"
git push origin chore/update-framework
Run Code Online (Sandbox Code Playgroud)
在这一点上,当我尝试第二次推送的请求时,它包含了所有功能的第一次提交。因此,该提交中所有更改的文件都在新的请求中,而旧的请求仅包含功能文件。
我究竟做错了什么?
当您这样做时:
git checkout -b chore/update-framework
Run Code Online (Sandbox Code Playgroud)
你没签上主面前。
要从所需的提交开始一个新分支(例如master):
git checkout -b chore/update-framework master
Run Code Online (Sandbox Code Playgroud)
要么:
git checkout master
git checkout -b chore/update-framework
Run Code Online (Sandbox Code Playgroud)
要么:
git branch chore/update-framework master
git checkout chore/update-framework
Run Code Online (Sandbox Code Playgroud)
要更正错误,您可以执行以下操作:
git rebase --onto master feature/feature1 chore/update-framework
Run Code Online (Sandbox Code Playgroud)
Git会选择您所有由feature / feature1指向的杂项/更新框架提交,然后将它们提交到master上,最后更新您的杂项/更新框架分支。
我认为你的问题归结为理解提交在分支上(或者最好说包含在分支中)意味着什么。这在 Git 中与许多传统版本控制系统不同。
\n\n在 Git 中,每个提交都位于(或包含在)许多分支上,至少可能如此。它可以没有分支、1 个分支、2 个分支等等。这是因为,在 Git 中,分支名称只是指向一个特定提交的可移动指针。可以将其更多地视为黄色便签纸。创建新的分支名称意味着抓住一张空白的便签并在上面写下名称,feature/feature1。
但是附注在哪里呢?好吧,在这里绘制(部分)提交图很有帮助。
\n\n在 Git 中,每个提交“指向”其前任(或父提交)。对于线性提交链,这基本上是一系列向后指向时间的箭头:
\n\n... <- o <- o <- o <- ... <- o\nRun Code Online (Sandbox Code Playgroud)\n\n这里的每个o提交都代表一个提交,每个提交都指向其(一个)父级。
合并提交指向两个父级,这实际上就是合并提交的原因。当仅限于 StackOverflow 上的纯文本时,用箭头绘制这些要困难得多:
\n\n o--o\n / \\\n... --o--* M--o\n \\ /\n o--o\nRun Code Online (Sandbox Code Playgroud)\n\n想象一下所有线条上都有箭头,以便它们都指向左(向上和向左,或向下和向左,如果需要)。 M这是合并提交及其两个父项。我在这里标记了另一个提交, commit *。它不是合并提交,但它确实有两个子项(两个指向它的提交)。这有时会让事情变得更有趣。
事实上,在我们进行合并提交之前,*提交是特别有趣的。让我们画出它(通过擦除和一些s):Mo
o\n /\n... --o--*\n \\\n o--o\nRun Code Online (Sandbox Code Playgroud)\n\n这是分支真正受到关注的地方。让我们添加名称和更长的<--箭头:
o <-- bra1\n /\n... --o--*\n \\\n o--o <-- bra2\nRun Code Online (Sandbox Code Playgroud)\n\nBranchbra1指向(或者等效地,是粘贴在其上的黄色便签)上面的最尖端o提交,并bra2指向下面的最尖端提交o。
我们在两个分支上*按原样调用该提交(就像其左侧的每个提交一样)。
这个特殊的谜题还有两块。一是名称HEAD,另一个与我们添加新提交并编写新分支名称时发生的情况有关。
HEADGit 中的名称HEAD告诉我们当前的提交和当前的分支。Git 执行此操作的方式几乎简单得可笑:HEAD通常只包含分支的名称。把它想象成另一个便利贴(可能是亮粉色、绿色或紫色,只是为了让它明显有点不同)。它可以直接指向一个提交\xe2\x80\x94,这是你毫无疑问见过的“分离的头”东西\xe2\x80\x94,但通常它只写有一个分支名称:
o <-- HEAD->bra1\n /\n... --o--*\n \\\n o--o <-- bra2\nRun Code Online (Sandbox Code Playgroud)\n\n这意味着我们在分支上bra1。
让我们在运行时进行新的提交bra1。
当进行新的提交时,Git:
\n\nHEAD(它说branch bra1)。bra1(这是一些又大又难看的 SHA-1a1c397f...或其他什么)。git add,指向该父 ID。新提交将获得新的唯一 SHA-1(例如0bc3112...)。bra1。第 4 步导致bra1指向新的提交,现在我们有:
o--o <-- HEAD->bra1\n /\n... --o--*\n \\\n o--o <-- bra2\nRun Code Online (Sandbox Code Playgroud)\n\n为了完整起见,让我们看看进行合并提交。
\n\n进行合并的过程本身可能很混乱,但实际上进行合并提交很简单:它只是与两个父级的提交。请注意,我们仍然处于bra1. 我们跑git merge bra2。Git 启动合并机制来完成工作树中的工作。如果存在冲突,就会留下混乱,我们必须手动修复它,但如果没有,它会自动启动新的提交。
新的提交与以前一样,只有一个小变化。在步骤3中,它没有写入一个父ID(来自现有的bra1),而是写入两个父ID:第一个是通常的,第二个是从读取中获得的ID bra2。
第 4 步照常进行,将新提交的 ID 写入bra1(因为HEAD仍然显示“使用分支bra1”):
o--o\n / \\\n... --o--* M <-- HEAD->bra1\n \\ /\n o--o <-- bra2\nRun Code Online (Sandbox Code Playgroud)\n\n因为M是合并(有两个父级),这意味着以前专门进行的所有提交bra2现在也都进行了bra1!
提交*曾经在两个分支上进行,现在仍然如此。而且,*我们仍然可以通过从左开始bra2并向左工作来实现这两个后期提交。
我们只允许向左移动,因此从 开始bra2,我们不允许移动到M,这意味着我们无法到达提交的顶行。我们只能从那里开始,或者从 开始,才能到达那里M。然而,我们不仅被允许,而且实际上被要求遵循像这样的合并的所有M父级。所以从 开始bra1,我们得到M,然后我们得到分支结构的两边,一直回到 commit *,并从那里继续向左走。
如果计算节点数,您将看到现在有 3 个提交包含在 中,bra1但不包含在bra2...中,但所有包含在 中的提交bra2都包含在 中bra1。
这里HEAD又开始发挥作用了。
您可以用来git branch创建一个分支:
$ git branch bra3\nRun Code Online (Sandbox Code Playgroud)\n\n默认情况下,这会HEAD读取我们现在所在的位置。 HEAD说bra1,里面bra1有\的ID。M所以这bra3表明M:
o--o\n / \\\n... --o--* M <-- HEAD->bra1, bra3\n \\ /\n o--o <-- bra2\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,HEAD它仍然指向它以前的位置,并且没有其他分支受到干扰,我们只是添加了一个新的可移动标签bra3。如果我们现在移动bra1或bra2,bra3继续指向M。
由于HEADstill 指向bra1,新的提交将会做出bra1改变。
但是,如果我们使用git checkout -b创建新分支,我们会得到以下结果:
o--o\n / \\\n... --o--* M <-- bra1, HEAD->bra3\n \\ /\n o--o <-- bra2\nRun Code Online (Sandbox Code Playgroud)\n\n这看起来几乎一模一样。不同的是,除了添加新的分支名称之外,我们还更改了HEAD. 现在它指向bra3.
让我们回到git branch,它只是创建了分支并且没有改变HEAD。该git branch命令还需要一个可选参数:
$ git branch bra4 bra2\nRun Code Online (Sandbox Code Playgroud)\n\n这不是bra4指向与 相同的提交,而是“指向与 相同的提交”。所以现在我们有:HEADbra4bra2
o--o\n / \\\n... --o--* M <-- bra1, HEAD->bra3\n \\ /\n o--o <-- bra2, bra4\nRun Code Online (Sandbox Code Playgroud)\n\n现在让我们git checkout bra4看看它的作用(就图 xe2x80x94 而言,当然它也会检查文件):
$ git checkout bra4\n\n o--o\n / \\\n... --o--* M <-- bra1, bra3\n \\ /\n o--o <-- bra2, HEAD->bra4\nRun Code Online (Sandbox Code Playgroud)\n\n同样,任何分支标签本身都没有发生任何变化。在图中,我们只需更改HEAD点即可。
(我们本来可以使用我们bra4现在已经有了的组合形式\xe2\x80\x94,所以现在已经太晚了,但是通过执行 ,这将是一个命令而不是两个\xe2\x80\x94 git checkout -b bra4 bra2。)
这意味着每当我们创建新分支时,我们都可以选择新分支指向哪个提交。默认值是“wherever HEADpoint”,这通常意味着读取另一个分支名称。我们可以HEAD先在某个有用的地方指出一点,或者我们可以将其添加到分支创建器中,然后让这一切一起发生。
这就留下了一个问题,而且并不总是有一个正确的答案:我们应该将新分支指向哪里?
\n\n也许我们想将其指向类似origin/masteror的东西origin/feature1。有时,选择其他一些起点更有意义,甚至可能是没有标签指向的起点。
origin/master是标签吗?是的,这些东西也是分支标签\xe2\x80\x94指向提交\xe2\x80\x94的可移动指针。它们只是不能移动的标签。当你运行时,你让它们移动git fetch(或拉动,但拉动只是获取,然后是另一步骤)。换句话说,它们“跟踪遥控器”(您git fetch origin并origin/*在需要时移动);所以它们是远程跟踪分支。
当我们绘制上面的图表时,我们可能应该包含这些标签......也许是这样的:
\n\n o <-- HEAD->feature1\n /\n... --o--* <-- origin/feature1\n \\\n o--o <-- feature2\nRun Code Online (Sandbox Code Playgroud)\n\n如果你想制作一个新的东西feature3,*也git checkout -b feature3 origin/feature1可以这样做。然后,提交*将包含在四个分支中:feature1、origin/feature1、feature2和feature3。
| 归档时间: |
|
| 查看次数: |
2057 次 |
| 最近记录: |