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>
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.)