I have a local tracking branch named develop. This branch contains some local commits that I am not ready to push (call it change_1). In other words HEAD -> develop is ahead of origin/develop, origin/HEAD.
I have another local branch, taken from a previous incarnation of develop, which has an unrelated set of commits that I would like to release, say change_2.
Would there be a preferred way of doing this? I'm thinking of maybe checking out another remote tracking copy of develop (which would not contain change_1) and rebasing that with change_2. So something like:
git checkout -b develop_with_no_change_1 --track remotes/origin/HEAD
git checkout change_2
git rebase develop_with_no_change_1
git checkout develop_with_no_change_1
git rebase change_2
git push
git checkout develop
git pull --rebase
CodePudding user response:
Branches in git are just names pointing at commits. They have no permanent identity, and can be moved and renamed at will. So if you ignore their current names, you want to have three branches:
- A branch that represents the "released" code
- A branch with one set of changes
- A branch with another set of changes
And what you want to do is make sure branches 2 and 3 are up to date with 1, but otherwise independent.
Right now, if I understand correctly, branch 1 and 2 are both called "develop", which is confusing. So, start off by renaming your local "develop" branch as "change_1", because that's what it actually is; you can also stop it tracking the remote "develop", because that's not the same branch:
git branch -m develop change_1
git branch --unset-upstream change_1
Now, you can make a local branch whose only purpose is to track the remote "develop". Never commit directly to this!
git fetch origin
git branch develop --track origin/develop
That gives you three branches:
- "develop", identical to the remote "develop", representing the released code
- "change_1", with one change
- "change_2", with a different change
To make sure each of the "change" branches is up to date with "develop", rebase them onto it:
git switch change_1
git rebase develop
git switch change_2
git rebase develop
Finally, when you want to release one change or the other, you merge it to develop, and then push the result (or, you use a remote UI with "Pull Request" / "Merge Request" functionality, like GitHub, GitLab, or BitBucket).
git switch develop
git merge change_2
git push origin develop
When you merge, you can choose whether to have a "fast-forward merge", create a "merge commit", or "squash" the changes; there are plenty of explanations of the differences out there.
What you almost certainly don't want to do is rebase develop onto anything else - your released code should generally be moving "forwards" in the commit history, not backwards or sideways.