如何在分支之间插入 git 分支(并可能重命名)而不影响其他用户?
我有一个与其他用户共享的存储库,所以我希望有一个解决方案可以最大限度地减少其他人必须做的事情,如果有一种方法可以让他们直接进行更改,我会喜欢的。
这是我当前的 git 分支:
A--B---------F (master)
\ /
C--D--E (develop)
理想目标:
A (master)
\
B---------F (stable)
\ /
C--D--E (develop)
但是如果这太难实现,特别是不会对已经拥有克隆的其他人进行复杂的更改(因为重命名),那么我不介意它看起来像这样或类似的:
A--B-------------F (master)
\ /
B'--------F' (stable)
\ /
C--D--E (develop)
简而言之:理想情况下,我很乐意创建一个新 master
空,等待来自的发布拉取请求stable
,并将old master
重命名为stable
。 新 master
应该是旧 master
的父级。
或者,如果重命名会使克隆存储库的其他人的事情变得复杂:我希望当前 master
和 develop
保持不变,但是我希望它们之间有一个名为 stable
的新分支,以便将来稳定的 develop
提交合并到 stable
,并可发布 stable< /code> 提交合并到
大师
。
我猜想替代方案最终可能看起来更像这样:
A--B---------F-------------M (master)
| |\ /
| | `---I-----L (stable)
\ / / /
C--D--E--G--H--J--K (develop)
其中 G、H、J、K 是新的开发提交,I 和 L 是来自稳定 H 和 K 的合并提交,M 是可释放的合并提交我认为我可以通过将 master
分支为 stable
轻松完成,然后确保我从 develop
合并到 <代码>稳定,并且未来,从稳定
到master
。或者说git有分支之间的父子关系的概念吗?
预先感谢您提供任何解决方案!
编辑:根据torek给出的答案,我们可以
- 签出
develop
,它不会改变 - create
stable
frommaster
- create
main< /code> 来自提交 A 处的
master
它看起来像这样:
,---------------------M (main)
/ /
/ ,-----I-----L (stable)
/ / / /
A---------F / / (deprecated master)
\ / / /
B--C--D--G--H--J--K (develop)
执行以下操作后:
git checkout develop
git branch stable master
git branch main <first commit hash>
I have a repo that I share with other users, so I'd love a solution that minimizes what others have to do, if there's a way they can just pull the changes, I'd love that.
Here's my current git branching:
A--B---------F (master)
\ /
C--D--E (develop)
Ideal goal:
A (master)
\
B---------F (stable)
\ /
C--D--E (develop)
But if that's too hard to achieve, specially without incurring complicated changes for everyone else who already has a clone (because of renaming), then I wouldn't it mind it looking like this or similar:
A--B-------------F (master)
\ /
B'--------F' (stable)
\ /
C--D--E (develop)
In short: Ideally I'd love to create a new master
that is empty, waiting for a release pull request from stable
, and rename the old master
to stable
. The new master
should be the parent of the old master
.
Alternatively, if renaming complicates things for other people who have the repo cloned: I'd like the current master
and develop
to remain unchanged, but I want a new branch called stable
between them so that stable develop
commits get merged to stable
in the future, and releasable stable
commits are merged to master
.
I guess there's a possibility that the alternative might end up looking more like this instead:
A--B---------F-------------M (master)
| |\ /
| | `---I-----L (stable)
\ / / /
C--D--E--G--H--J--K (develop)
Where G,H,J,K are new develop commits, I and L are merge commits from the stable H and K, and M is a releasable merge commit from L. This I assume I can easily do by branching off of master
as stable
, then making sure I'm merging from develop
to stable
, and stable
to master
, in the future. Or does git have a concept of parent-child relationship between branches?
Thank you in advance for any solutions!
EDIT: based on the answer given by torek, we could
- checkout
develop
which won't change - create
stable
frommaster
- create
main
frommaster
at commit A
And it would look like this:
,---------------------M (main)
/ /
/ ,-----I-----L (stable)
/ / / /
A---------F / / (deprecated master)
\ / / /
B--C--D--G--H--J--K (develop)
After doing the following:
git checkout develop
git branch stable master
git branch main <first commit hash>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Git 中的父/子关系仅与提交相关。在 Git 中,每个分支名称实际上只是该分支中最后一次提交的标签(可能是其他分支中的中间提交:
K
就是这种情况)例如,上一个示例中的L
)。分支名称可以任意移动,因此您可以在第一个示例中将
master
从F
移回到A
,在创建指向提交F
的新名称stable
后:这里棘手的部分是,拥有此存储库克隆的每个人都将拥有其克隆的
origin/master< /code> 指向提交的远程跟踪名称
F
也是。这些克隆将在git fetch origin
上更新自己的origin/master
名称,以便它们指向A
,但如果他们自己master
名称指向现有提交F
,他们 Git软件将不会移动< em>他们的master
分支名称只是因为origin/master
移动了,他们的 Git 软件将不愿意将master
从F
“向后”移动他们的返回A
,并且需要施加一些力。如果您打算将
master
重命名为main
,现在是这样做的好时机:单独保留master
,创建新名称main
指向现有提交A
,并告诉人们运行git fetch
。他们将获得一个指向A
的新origin/main
。如果他们愿意的话,告诉他们以通常的方式创建自己的main
——如果他们不使用它,他们就不需要它。告诉他们名称master
现已死亡并将被删除,一旦他们根据需要对其他分支名称进行提交,他们应该删除自己的master
。请记住,每次提交都是 100% 只读,因此您无法将现有
F
更改为将F'
作为父级。您始终可以进行新提交,并且这些提交可以包含您喜欢的任何快照,以及您喜欢的任何父哈希 ID 列表(以便它们向后指向您所在点存在的任何提交)进行新的提交)。任何分支名称都可以指向任何提交,但是:gitbranch-f
或gitreset
)来“向后”移动分支名称(提交链接实际的方式,从子项向后移动到父母)。因此,很容易获得此存储库的其他克隆来添加内容。这会自动发生:人们无论愿意与否都会获得新的提交。但让人们收回分支是很困难的:这需要每个人的手工工作。
关于您的编辑:
一旦您进行了更多提交并进行了合并
M
,它最终会出现,是的。 (要从一开始就到达那里,您只需运行:并在任何 GitHub 风格的服务器上,使用 Web 界面将“默认分支”设置为
main
现在,还可以选择删除master
完全设置默认分支,GitHub 将运行git symbolic-ref HEAD refs/heads/main
或他们正在使用的任何软件中的等效项。)The parent/child relationships in Git are tied solely to the commits. Each branch name, in Git, is really just a label for the last commit in that branch (which may be a middle commit in some other branch: that's the case with
K
andL
in your last example, for instance).Branch names can be moved arbitrarily, so you could move your
master
back fromF
toA
in your first example, after creating new namestable
pointing to commitF
:The tricky part here is that everyone who has a clone of this repository will have their clone's
origin/master
remote-tracking name pointing to commitF
too. Those clones will update their ownorigin/master
names ongit fetch origin
, so that they point toA
, but if they have made their ownmaster
name pointing to existing commitF
, their Git software will not move theirmaster
branch name just becauseorigin/master
moved—and their Git software will be reluctant to move theirmaster
"backwards", fromF
back toA
, and will require some application of force.Should you be inclined to rename
master
tomain
, this is a good time to do it: leavemaster
alone, create new namemain
pointing to existing commitA
, and tell people to rungit fetch
. They will get a neworigin/main
pointing toA
. Tell them to create their ownmain
in the usual way, if they wish—they don't need one if they're not using it. Tell them the namemaster
is now dead and will be removed and they should remove their ownmaster
once they have their commits on some other branch name(s) as necessary.Remember that every commit is 100% read-only, so you can't change the existing
F
to haveF'
as a parent. You can always make new commits, and those can contain whatever snapshot you like, and whatever list of parent hash IDs you like (so that they point backwards to any commit(s) that exist at the point you make the new commit). Any branch name can point to any commit, but:git branch -f
orgit reset
) to move a branch name "backwards" (the way the commit linkages actually go, from children backwards to parents).So it's really easy to get other clones of this repository to add on stuff. That happens automatically: people get the new commits whether they want to or not. But it is hard to get people to retract branches: that takes manual work by each person.
Regarding your edit:
It would eventually, once you've made more commits and made the merge
M
, yes. (To get there from what you start with, you'd just run:and on any GitHub-style servers, use the web interface to set up the "default branch" as
main
now, optionally also deletingmaster
entirely. To set the default branch, GitHub will rungit symbolic-ref HEAD refs/heads/main
, or whatever is equivalent in whatever software they're using.)