【问题标题】:Looking to incorporate changes from sub-branch into branch but both contain same commits希望将子分支的更改合并到分支中,但都包含相同的提交
【发布时间】:2019-12-15 17:47:15
【问题描述】:

绝对是 git 的新手,因此这里可能是一个非常愚蠢的问题:

我有一个 master 分支,我开始在其中进行增强。 大约 20 次提交后,我意识到我应该创建一个单独的分支并完成我的工作。

所以我从 master 创建了一个新的 main/dev 分支,然后我将 master 分支指针重置为指向初始 repo 提交,这是我开始工作之前的点:

$ git reset --hard <commit hash>

在我这样做之后,我立即想到了以下工作流程(不确定从哪里来--lol):

我的想法是沿着我自己的“主”分支而不是在 master 上进行所有主要开发。然后我会从这个主分支创建新的功能/增强分支,我猜是开发分支?然后我最终会将新的增强工作重新合并到“主”分支中,然后当我自己的所有“主”工作完成后将其合并到主分支中(不确定这是否是一个好的工作流程......似乎不是所以)。

因此,在这个好主意之后,我立即想到“嗯……让我从 main 中创建另一个单独的特定“增强”分支。

我想我可能错误地创建了“子”增强分支。 在“主要”上,我刚刚使用了

$ git checkout -b enhancement

不是

$ git checkout -b enhancement main

现在当我在“main”分支上运行时:

$ git merge enhancement

我得到以下信息:

Already up to date.

当我跑步时

$ git show-branch 

据我了解,它用于显示所有分支及其所有提交,我得到以下输出:

! [enhancement] Test enhancing, fixing, and cleaning.
 * [main] Test enhancing, fixing, and cleaning.
  ! [master] Grammar improvements
---
+*  [enhancement] Test enhancing, fixing, and cleaning.
+*  [enhancement^] Bug Fix: addition of path id to updateTodo method.
+*  [enhancement~2] Additon of tests to TodoTest.java and TodoResourceTest.java for ValidForUpdate Todo annotation.
+*  [enhancement~3] Refactoring: moved all custom validation messages to properties file and all associated changes. Also cleaned up imports here and there.
+*  [enhancement~4] Refactoring: moved PastOrPresentValidator to an inner class of the PresentOrPast annotation class.
+*  [enhancement~5] Addition of ValidForUpdate custom constraint Todo object annotation and freinds.
+*  [enhancement~6] Fixed problem of same four tests failing when run with all tests in class but passing individually. Changed init from 'BeforeClass' to 'BeforeEach' fixed it.
+*  [enhancement~7] Added properties to enable forked & threaded test processing in surefire plugin.
+*  [enhancement~8] Added propertey for maven surefire plugin version.
+*  [enhancement~9] Refactoring of tests. Move of mian Todo template test object and friends to central location of TestTodoCreater.
+*  [enhancement~10] Refactoring to get PresetntOrPast validation error message from properties file. Also some slight refactoring by replacing validation error message string literals in tests with string constant.
+*  [enhancement~11] Addition of new 'PresentOrPast' validator and accompanying test changes. Also a little bit of test clean-up/refactoring.
+*  [enhancement~12] Addition of 'updateTodo' api method and accompanying tests. Tightening up of validation annotations in TodoResource. Addition of Todo field validations and all accompanying tests. Major refactoring of TodoResourceTest.
+*  [enhancement~13] Backed out previous commit's changes and updated dropwizard version to 1.3.13. Changes backed out due to what appears to be lack of Hibernate Validator 6 support in the dropwizard-testing library.
+*  [enhancement~14] Moved ValidationMessages.properties file. Still not yet using.
+*  [enhancement~15] updated hibernate-validator and java validation-api to latest versions.
+*  [enhancement~16] Changes required to add 'update' method to TodoDAO and some code cleanup.
+*  [enhancement~17] Changes in order to get maven to run ALL (Junit5) tests with 'mvn test'. Specific changes to get TodoIntegrationSmokeTest to run by adding test-config.yml.
+*  [enhancement~18] Completion of TodoIntegratoinSmokeTest for pre-existing api methods.
+*  [enhancement~19] Initial commit of TodoIntegratoinTest with working testCreateTodo method.
+*  [enhancement~20] Some minor code cleanup up and refactoring.
+*  [enhancement~21] completed tests for pre-existing api methods.
+*  [enhancement~22] Cleaned up TodoResource test and TestUtils.
+*  [enhancement~23] All API methods test-covered 'except' for deleteTodo.
+*  [enhancement~24] Validation for TododResource#getTodos and accompanying test changes .
+*  [enhancement~25] Began shoring-up code with parameter validation and accompanying test changes.
+*  [enhancement~26] Completed bulk of TodoDaoTest but missing update implementation and some odds and ends.
+*  [enhancement~27] A little more clean up/refactoring of TodoDAO associated test classes.
+*  [enhancement~28] Clean up of TodoDAOTest2
+*  [enhancement~29] Slight modification to server rootPath value.
+*  [enhancement~30] Addition of beginning of Todo DAO test classes. Creates a PostgresSQL Docker container and laods the schema with flyway.
+*  [enhancement~31] Replaced TodoResource string literal test path values with static UriBuilders.
+*  [enhancement~32] Changes in this commit are in support of getting the TodoResourceTest completed by covering all original api methods(given with task).
+*  [enhancement~33] Small change. Renamed Todo JSON test class to 'TodoRepresentationTest' to use Dropwizard-specific terminology. Removed non-used import.
+*  [enhancement~34] Conversion of Todo class into an immutable 'value' class. Added tests for serializing and deserializing Todo objects to and from JSON.
+*+ [master] Grammar improvements

除非我误解了该命令的输出,否则“main”似乎包含与“enhancement”相同的所有提交,这使得我对增强分支所做的任何提交看起来也以某种方式被提交到主分支。

看起来我一直在工作并同时向两个分支提交相同的内容。

运行后也是

git show-ref --head

我明白了:

b43e3c2b3d19a4a19497cf78e3909727f25796a2 HEAD
b43e3c2b3d19a4a19497cf78e3909727f25796a2 refs/heads/enhancement
b43e3c2b3d19a4a19497cf78e3909727f25796a2 refs/heads/main
...

这表明 HEAD 同时指向两个分支? 这是怎么发生的???

当我运行命令以显示两个分支之间的不同提交时:

$ git log --left-right --graph --cherry-pick --oneline main...enhancement

没有输出。 所以这就是说这两个分支之间根本没有区别。 所以我真的很想知道我在这里做了什么。

我喜欢 git,但她又让我感到困惑 :(.

我已经阅读了 git 中的“分支”,据我所知,分支只是指向特定提交的指针,而 HEAD 指向的任何分支都是您当前工作的分支,因此在提交时将只需在 HEAD 顶部添加连续提交,同时将 HEAD 推进到该分支中的最新提交。

所以我的增强分支的 HEAD 应该在包含提交 main 的主分支的 HEAD 之前。

我不明白的是,如果我在过去 17 次提交中一直在增强分支中工作,那么当我切换到任一分支时,HEAD 为何会指向同一个提交。

所以我期望看到的是不同的提交历史,增强包含更多的提交,但我没有,他们有相同的提交!

请有人怜悯并通过向我指出我在这里做错了什么来提供一些启发。我一直在努力解决这个问题。

任何和所有的帮助都无法估量!

【问题讨论】:

  • 只是对我的情况的跟进:在阅读了@torek 最慷慨的信息回复后,我决定在“主”分支上做一个git reset --hard master,一个基于“增强”分支来清理提交历史,然后,在找到一篇关于 rebase here 的好文章后,决定在“main”上使用“enhancement”执行“rebase-and-merge”工作流程。非常非常感谢@torek 的贡献。希望这也能帮助许多其他人。干杯! -卢克

标签: git branch branching-strategy


【解决方案1】:

你的问题的根源是分支不是分层的。

提交有一个图结构。特别是,几乎每个提交都有一个父级,有些有两个父级。一些古怪的提交可能有三个或更多,并且至少有一个——存储库中的第一个提交——必然有没有个父节点。

正是这种父/子关系构成了图形结构。我们可能会从一个很小的存储库开始,只有三个提交:

A <-B <-C

三个提交的实际名称是三个丑陋的哈希 ID,但是我们可以使用单个大写字母来代替这些哈希 ID,只要我们不进行超过几十个提交(我们有多少'会得到取决于你的字母表中有多少个字母:例如,你有O和Ö吗?)。最后一次提交 C 包含提交 B 的实际哈希 ID,因此我们说 C 指向 BBC 的父级。提交B 包含A 的哈希ID 作为B 的父级,所以B 指向AA 是第一次提交,所以它不能指向任何更早的东西,也没有;到这里,动作就停止了。

要向此存储库添加新提交,我们将保存新的源代码快照,添加我们的姓名和电子邮件地址以及日期和时间戳,保存日志消息,并保存 C 的哈希ID,全部到一个新的提交中,它会自动分配它自己的新的、唯一的哈希 ID,我们称之为 D,现在我们有了:

A <-B <-C <-D

但是分支名称在哪里出现在这张图片中?好吧,请记住,每个提交都有一些大而丑陋的随机散列 ID。以下是按某种顺序排列的四个实际哈希 ID:

7c20df84bd21ec0215358381844274fa10515017
14fe4af084071803ab4f16e6841ff64ba7351071
c62bc49139f1d18e922fc98e35bb08b1aadbcafc
9b274e28871b3e4a4109582a34625df5fddc91c8

其中哪一个我应该调用commit A,哪一个我应该调用B,等等?如果我想从 end 开始——在 latest 提交时,就像 Git 那样,我是从 14fe... 开始,还是从 9b27... 开始,还是什么?

我们可以查看这四个提交中的每一个,以查看它们存储的父哈希 ID。例如:

$ git cat-file -p 9b274e28871b3e4a4109582a34625df5fddc91c8 | sed 's/@/ /'
tree c921299d1381a3bd6486ef999e3cc432118d1d72
parent e46249f73ebddca06cf16c01e8de1f310360c856
parent f3eda90ffc10f9152e7492a34408a9f5e4c28b0f
author Junio C Hamano <gitster pobox.com> 1564776722 -0700
committer Junio C Hamano <gitster pobox.com> 1564776722 -0700

Merge branch 'jc/log-mailmap-flip-defaults'

Hotfix for making "git log" use the mailmap by default.

* jc/log-mailmap-flip-defaults:
  log: really flip the --mailmap default
  log: flip the --mailmap default unconditionally

告诉我提交 9b274e28871b3e4a4109582a34625df5fddc91c8两个 父级,e46249f73ebddca06cf16c01e8de1f310360c856f3eda90ffc10f9152e7492a34408a9f5e4c28b0f,它们都不是我列出的四个之一。如果我查看存储库中的每个提交,并收集他们所有的parent 行,我可以 -最终,经过大量工作 - 找出哪些提交在 结束。但这很慢。

Git 对此的回答是分支名称。分支名称仅包含一 (1) 个提交的哈希 ID:

$ git rev-parse master
7c20df84bd21ec0215358381844274fa10515017

啊哈,这是我上面列出的四个提交之一!该提交是 Git 应该考虑成为 master 一部分的 last 提交。如果我们往里面看:

$ git cat-file -p 7c20df84bd21ec0215358381844274fa10515017 | sed 's/@/ /'
tree 8858576e734aa4f1cd9b45e207e7ee2937488d13
parent 14fe4af084071803ab4f16e6841ff64ba7351071
author Junio C Hamano <gitster pobox.com> 1564776744 -0700
committer Junio C Hamano <gitster pobox.com> 1564776744 -0700

Git 2.23-rc1

Signed-off-by: Junio C Hamano <gitster pobox.com>

我们看到这个提交恰好有 一个 父级 14fe4af084071803ab4f16e6841ff64ba7351071,这是我的四个哈希 ID 中的另一个。所以master 是链的末端,而另一个以14fe... 开头的又大又丑的哈希ID 是下一个:

...--G--H   <-- master

H7c20... 提交,G14fe... 提交。让我们看看G 的父母,这次使用git rev-parse 及其特殊的“打印所有父哈希ID”语法:

$ git rev-parse 14fe4af084071803ab4f16e6841ff64ba7351071^@
c62bc49139f1d18e922fc98e35bb08b1aadbcafc
d61e6ce1dda7f4b11601a0de549feefbcec55779

c62b... 是我四个列表中的第三个;还有一个不在我的列表中。这个提交是一个合并提交,我们可以看看它的其余部分:

$ git cat-file -p 14fe4af084071803ab4f16e6841ff64ba7351071 | sed 's/@/ /'
tree 06a0b1de4cb3857cdd23a939a857dc720240496b
parent c62bc49139f1d18e922fc98e35bb08b1aadbcafc
parent d61e6ce1dda7f4b11601a0de549feefbcec55779
author Junio C Hamano <gitster pobox.com> 1564776723 -0700
committer Junio C Hamano <gitster pobox.com> 1564776723 -0700

Merge branch 'sg/fsck-config-in-doc'

Doc update.

* sg/fsck-config-in-doc:
  Documentation/git-fsck.txt: include fsck.* config variables

我们可以调用c62bc49139f1d18e922fc98e35bb08b1aadbcafc 提交F。对于d61e6ce1dda7f4b11601a0de549feefbcec55779,我们可能需要E 以外的其他字母;让我们使用I:

...--F--G--H
       /
 ...--I

现在让我们放入分支name master。该名称本身标识了提交H,并且只有直接 意味着提交H,所以:

...--F--G--H   <-- master
       /
 ...--I

我们可以从 G 的日志消息中看到 Junio Hamano G 通过运行:

git merge sg/fsck-config-in-doc

所以让我们也使用那个名字,指向提交I

...--F--G--H   <-- master
       /
 ...--I   <-- sg/fsck-config-in-doc

有趣的是,提交 FGH 都在 master 上......但是它意味着提交是“on一个分支”是我们可以从最后开始——在这种情况下是在提交H——然后向后工作并到达那个提交。因此,从H 开始,我们只能退一步,然后看到G。从G,我们可以退回到FI。因此,不仅在 master 上提交 F,而且在提交 I 上也是如此。

同时,sg/fsck-config-in-doc 是一个分支名称。它标识提交I。所以提交I 不仅在master 上,它也在sg/fsck-config-in-doc 上。

这是关于分支名称的第一件事。它们只是标签。它们只是作为让 Git 开始查看图表的方式。分支名称标识一个特定的提交,我们称之为该分支的 tip commit。该提交标识了一些父提交或提交,并且这些提交也在分支上。通过移动或查看父母,我们会找到更多的父母;那些也在树枝上。

要在某个分支上进行新的提交,我们首先让 Git 选择那个特定的分支名称作为 当前 分支。为了创建一个新的分支名称,我们让 Git 选择一些提交(默认为当前提交)并创建一个新名称,指向那个特定的提交。所以如果我们有:

...--F--G--H   <-- master
       /
 ...--I   <-- sg/fsck-config-in-doc

并要求 Git 创建一个新名称 topic,我们得到:

...--F--G--H   <-- master, topic
       /
 ...--I   <-- sg/fsck-config-in-doc

通过I 提交的内容以及通过I 提交的内容现在都在both master topic 上。如果我们选择topic 作为当前分支,Git 会根据需要提取提交H 并将名称HEAD 附加到名称topic

...--F--G--H   <-- master, topic (HEAD)
       /
 ...--I   <-- sg/fsck-config-in-doc

当我们进行新的提交时,它的父级将是 H——topic 的前一个提示——新的提交将成为名称 topic 标识的那个:

             J   <-- topic (HEAD)
            /
...--F--G--H   <-- master
       /
 ...--I   <-- sg/fsck-config-in-doc

注意HEAD仍然附加到分支名称,但分支名称已经移动

移动分支名称不会影响存储库中的任何提交!它们在您移动名称之前都存在,并且在您移动名称后它们继续存在。无论 何处 您将名称移动到哪里,图形本身都保持不变(尽管为了使来自名称的箭头指向正确的提交,您有时可能希望以不同的方式绘制图形) .

假设我们决定让topic 指向I 而不是J

             J
            /
...--F--G--H   <-- master
       /
 ...--I   <-- sg/fsck-config-in-doc, topic (HEAD)

提交J 仍然存在,但现在很难找到。如果你从master 开始并向后工作,你会得到H,然后是G,然后是FI,以此类推。你无法到达J:箭头指向错误的方向。如果你从topic(现在是I)的尖端开始,然后向后工作,你将无法到达J。提交 J 实际上已被放弃。

特定命令使用这些名称执行特定操作

如你所见,git checkout -b:

  • 创建一个新的分支名称,指向某个现有的提交,然后
  • 对新名称执行 git checkout,以便 HEAD 附加到该名称,并且现有提交成为您当前的提交。

同时,git reset --hard

  • 接受一个可选的名称或哈希 ID,或者任何 git rev-parse 可以处理的东西,真的,然后将其 变成一个哈希 ID,然后

  • 采用当前分支名称——附加的HEAD——并使其指向那个特定的提交。

  • 因为这个是--hard,它也重新设置了索引和工作树。 git reset 的其他风格的工作方式不同。事实上,有一些git resets永远不会移动当前分支名称,但git reset --softgit reset --mixedgit reset --hard 可以。

    但是,请注意,如果您使用名称 HEAD,或者让 git reset 使用其默认值 HEAD,则 git rev-parse 步骤将与 当前提交一起出现。然后git reset 将当前分支从其当前提交 ... 移动到其当前提交,毕竟它不会移动它。这就是为什么git reset --hard 是重置您对索引和工作树所做的任何更新但未提交的好方法。

git merge 命令有点复杂——并不是说git reset 更好,它有许多不同的操作模式——但它的作用始于查看提交图。你选择一些提交——可能是通过分支名称,分支名称标识提示提交——然后git merge 检查提交图,以确定如何从当前提交和你命名的提交向后工作,以便达成一个共同的、共享的提交。

在这种情况下,您已经进行了如下设置:

...--F--G--H   <-- master
            \
             I--J--...--N   <-- main (HEAD), enhancement

然后运行git merge enhancement。名称 enhancement 标识提交 N。当前分支名称main 也是如此。因此,both 分支上的共享提交是提交 N。因此没有什么可做的。

你现在可以移动名称main指向提交H,使用:

git reset --hard master

和以前一样,--hard 将重置索引和工作树,因此请确保您没有尚未保存的内容;最终结果可绘制为:

...--F--G--H   <-- master, main (HEAD)
            \
             I--J--...--N   <-- enhancement

如果你现在运行git merge enhancement,Git 将从H 向后走,并且从N 向后走,以找到第一个共享提交。这就是提交H 本身,它位于所有三个分支上。然后,如果您允许,Git 将裁定这种合并太琐碎而无法努力工作,只需移动名称 main 以便它标识提交 Ngit checkout 提交 N同时。

Git 将此称为快进操作,最后,图片为:

...--F--G--H   <-- master
            \
             I--J--...--N   <-- main (HEAD), enhancement

这是你刚才所在的地方!

但是,您可以强制 Git 进行真正的合并。在我们开始之前,让我们看一下 Git 本身必须进行真正合并的情况。

真正的合并

假设你不是从上面开始的,而是从:

...--F--G--H   <-- master (HEAD)

然后你运行:

git checkout -b branch

添加一个新的分支名称branch,标识当前提交H,并将HEAD附加到它:

...--F--G--H   <-- master, branch (HEAD)

现在你做出一个新的提交II 的父级将像往常一样是 H。当前的名称br1,被重写为指向新的提交I,作为git commit操作的最后一步:

...--F--G--H   <-- master
            \
             I   <-- branch (HEAD)

为了好玩(或者写出我想要的M,真的),让我们进行第二次提交,该提交仅在branch 上进行,而不是所有以H 结尾的共享提交:

...--F--G--H   <-- master
            \
             I--J   <-- branch (HEAD)

现在让我们git checkout master,检查提交H 并重新附加HEAD

             I--J   <-- branch
            /
...--F--G--H   <-- master (HEAD)

然后在master 上进行两次新的提交。出于某种难以理解的原因,我会将它们绘制在新的顶行上(这实际上没有必要):

             K--L   <-- master (HEAD)
            /
...--F--G--H
            \
             I--J   <-- branch

现在我们运行git merge branch(或git merge <em>hash-of-J</em>,除了提交日志消息之外,它将执行相同的操作)。 Git 必须从L 开始并向后工作,并从J 开始并向后工作,以找到最佳共享提交,即H

此共享提交称为合并库。现在 Git 知道哪个提交是合并基础,它会检查合并基础 是否 当前提交 L 和/或另一个提交 J,因为这些是特殊的简单情况.不是,所以这不是一个简单的合并。

合并的目标合并更改,但提交HLJ 都只有快照时间>。所以 Git 首先必须将 LJ 转换为更改。通过从最佳共同起点(合并基础)开始,两组更改都应应用于该共同起点。为了获得更改,Git 实际上运行 两个 git diff --find-renames 命令:

  • git diff --find-renames <em>hash-of-H</em> <em>hash-of-L</em> 告诉 Git 我们在 master 上所做的更改;
  • git diff --find-renames <em>hash-of-H</em> <em>hash-of-J</em> 告诉 Git 他们(好吧,我们)在 branch 上所做的更改。

合并过程现在尝试合并更改,将合并后的更改应用到来自合并基础H 的快照。如果一切顺利——如果变化结合得很好——Git 从结果中创建一个新的快照。此新快照有 两个 父级。第一个是通常的。我们在master,这意味着提交L,所以新合并的第一个父级是L。我们命名的另一个提交是J,所以新合并的第二个父提交是J。提交后,Git 像往常一样将其新的哈希 ID 写入当前分支名称。

如果一切顺利的话,最终的结果是:

             K--L
            /    \
...--F--G--H      M   <-- master (HEAD)
            \    /
             I--J   <-- branch

我们已经产生了真正的合并。

强制与--no-ff 真正合并

让我们回到这个设置:

...--F--G--H   <-- master, main (HEAD)
            \
             I--J--...--N   <-- enhancement

然后运行git merge --no-ff enhancement--no-ff 告诉 Git:即使合并基础是 H,也要进行真正的合并。

Git 现在将继续进行这两个差异(内部)。第一个比较 HH。当然,这会产生一个空的变更集。第二个比较 HN。当然,这会产生将H 中的快照转换为N 中的快照所需的所有更改。

然后,Git 将第一个变更集(即“什么都不做”)与第二个结合起来。结果只是第二个变更集。将此应用于H 中的快照,Git 将获取N 中的快照。不过,合并工作正常,所以现在 Git 进行了一个新的合并提交,我们称之为 OO 的第一个父节点是H,它的第二个父节点是N,我们有:

             ,------------------O   <-- main (HEAD)
            /                  /
...--F--G--H   <-- master     /
            \                /
             I--J----...----N   <-- enhancement

你应该使用哪个?

有时,快进是要走的路。有时,真正的合并是要走的路。让我们再看一下我之前使用的 Git 的实际 Git 存储库的图表:

...--F--G--H   <-- master
       /
 ...--I   <-- sg/fsck-config-in-doc

我们现在可以删除名称sg/fsck-config-in-doc。它所做的只是让我们直接访问提交I,但我们可以从H 到达那里。所以让我们删除名称:

...--F--G--H   <-- master
       /
 ...--I

这里的想法是分支名称无关紧要(除了查找最终提交)。只有提交很重要。 fast-forward 操作通常使两个名称标识同一个提交。如果您打算在未来取消一个或两个名字,您将永远不会知道快进曾经发生过。

这是好事还是坏事?好吧,假设你以后真的想知道O,你强制与--no-ff 的合并是一个合并 动作。这意味着通过N 的提交是一些副业,而副业终于准备好迎接黄金时间并一次性添加。那么你确实想要一个合并提交,即使git merge 会默认进行快进。

另一方面,也许你在未来不会关心通过N 提交是某种副业。副业与主要工作都无关紧要:只有你在工作。也许N 之前的某些特定提交也无关紧要。也许您希望将所有提交连续提交,以便于查看,或者您可能希望这样做:

...--F--G--H   <-- master, main (HEAD)
            \
             I--J--...--N   <-- enhancement

并把它变成:

...--F--G--H--O--P   <-- main

并丢弃所有I-through-N 提交,保留两个 提交OP,它们紧凑地表示“正确地做第一件事”然后“正确地做第二件事”,而不是您在IJK 等中所做的漫无边际的事情。在这种情况下,您根本不想要合并。

您未来将拥有的是一个提交图表,其中包含一些指定的提示提交。这就是您将拥有的全部。您今天可以确定提交图中的提交集;你明天可以决定保留哪些名字;和未来——你会祝福或诅咒今天——你和明天——基于你在这个计划中做得有多好……或者,也许,根本不在乎。由您决定在计划提交时要多谨慎。

但无论如何,names 只对 finding 提交很重要。真正重要的是提交及其结果图。

【讨论】:

  • 哇,感谢@torek 所做的一切。因此,在我执行git reset --hard master 以使 main 基本上指向与 master 相同的提交之后,我现在想知道在这种情况下,rebase 是否会更好?你能对此发表评论吗?还是您认为我应该进行真正的合并?再次感谢!
  • 通读你应该使用哪个部分来决定未来——你会喜欢现在——如果你合并、变基等,你会更好。但请注意,作为旧的也许——荷兰谚语说,很难预测,尤其是关于未来。
  • 好吧,我只记得所有这些中的一个小细节......大约 15 或 16 次提交到我推送到远程存储库的“主”分支中,然后添加了大约 17 次未推送的提交在那之后。我刚刚完成了硬重置,所以“main”现在指向与 master 相同的位置。这是一个问题吗?如果不是现在,如果我决定将我的“增强”更改重新设置在“主要”之上,那会是一个问题吗?我未来的自己会讨厌现在的自己吗?不幸的是,这似乎经常发生在这一行:(。
  • 啊:当您将一些提交推送到 另一个 Git 存储库时,其他 Git 存储库具有这些提交,由它们的哈希 ID 存储,并且 found由其他 Git 存储库中的某个 name 命名。通常,您将使用相同的名称来标识相同的最后(提示)提交,或者只是在该提示提交之后添加新提交,以便两个存储库可以最轻松地重新同步。但是,如果您控制两个存储库,则可以做任何您喜欢的事情。如果控制另一个仓库的人足够友好,你仍然可以为所欲为,只是现在需要协调。
  • 我几乎是唯一为远程 repo atm 做出贡献的人,所以我想这不是问题。只是我读到的所有关于 rebase 的内容(这个词由于某种原因听起来是非法的,这让我也想起了 Richard Pryor)提到永远、永远、永远不要强制推送到远程仓库,所以我只是我想现在有点偏执了,哈哈。不想养成任何“坏习惯”:)。再次非常感谢你!我猜真正的 git "master" 是指向你的指针,先生!干杯!
猜你喜欢
  • 2015-10-02
  • 2018-03-08
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 2019-05-20
  • 2018-05-29
相关资源
最近更新 更多