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
develop
which won't change stable
from master
main
from master
at commit AAnd 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>
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
and L
in your last example, for instance).
Branch names can be moved arbitrarily, so you could move your master
back from F
to A
in your first example, after creating new name stable
pointing to commit F
:
git switch develop # so that we're on one that doesn't move
git branch stable master
git branch -f master <hash-of-A>
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 commit F
too. Those clones will update their own origin/master
names on git fetch origin
, so that they point to A
, but if they have made their own master
name pointing to existing commit F
, their Git software will not move their master
branch name just because origin/master
moved—and their Git software will be reluctant to move their master
"backwards", from F
back to A
, and will require some application of force.
Should you be inclined to rename master
to main
, this is a good time to do it: leave master
alone, create new name main
pointing to existing commit A
, and tell people to run git fetch
. They will get a new origin/main
pointing to A
. Tell them to create their own main
in the usual way, if they wish—they don't need one if they're not using it. Tell them the name master
is now dead and will be removed and they should remove their own master
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 have F'
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
or git 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:
... And it would look like this:
,---------------------M (main) / / /,-----I-----L (stable) / / / / A---------F / / (deprecated master) \ / / / B--C--D--G--H--J--K (develop)
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:
git branch main <hash-of-A> # or git branch main master~2
git branch stable master
and on any GitHub-style servers, use the web interface to set up the "default branch" as main
now, optionally also deleting master
entirely. To set the default branch, GitHub will run git symbolic-ref HEAD refs/heads/main
, or whatever is equivalent in whatever software they're using.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.