0

There are two remote git branches. One named "stable" and another one named "develop". When it was created, the "develop" branch was based on the "stable" branch. After some time a lot of new features were added to the "develop" branch, code was changed and files were added and deleted. The "develop" branch now looks a lot different compared to the "stable" branch.

Meanwhile some of these new features got backported to the "stable" branch.

stable --> backport of the new features
 \
  \- develop --> new features, huge changes to the code

Now, after some time, the "develop" branch has to become the new "stable" branch, while the "stable" branch has to become the "old_stable" branch.

I managed to create "old_stable" which is based on "stable", but I'm unsure how to move the "develop" branch to the the "stable" branch. Basically, if they were just files, I want to do this:

cp stable old_stable      # done
cp develop stable         # looking for the best way to do this

I'm looking for some git commands to just 'replace' the "stable" branch with the "develop" branch, without manually resolving any conflicts, merging commit history, etc.

Everything in the "stable" branch can be lost and be completely replaced with what is currently in the "develop" branch.

ilis
  • 3
  • 2
  • So you want to delete old_stable, then rename stable to old_stable. And finally rename develop to stable. Right ? So just `git remote remove old_stable && git remote rename stable old_stable && git remote rename develop stable`. – konoufo May 26 '21 at 12:32
  • @konoufo "old_stable" should be a copy of the current "stable". "development" should become "stable". If the commands you mentioned will accomplish this, I will gladly accept that as the answer. I'm new to git branch administration and have just been using it from a developer's point of view. – ilis May 26 '21 at 12:37
  • 1
    @konoufo `git remote remove old_stable` will remove the remote repo named `old_stable`. It does not have any effect on a branch. Given that we don't know what the remotes are named, it is likely the OP is asking about a branch on the remote named 'origin'. – William Pursell May 26 '21 at 13:22
  • Some good answers already, but here's a quickie: `git checkout stable` followed by `git reset --hard develop` (or origin/develop if your local copy of develop is out of date) and then force push it back out. – TTT May 26 '21 at 16:06
  • Note that you're really just *renaming* a branch, which is trivial. The problem with renaming a branch is that *other people might not know you did that* and think that the new branch (using the old name) is to be combined with the old branch (using the old name). *They* then mess everything up. Hence the key to doing what you'd like to do is *communicating with everyone using this repository*. Renaming branches is trivial technically; it's those darn humans that get in the way. :-) – torek May 27 '21 at 00:09
  • I hope this isn't too confusing, but it's worth pointing out another reason that *humans* get confused here. In my comment above, I said "rename a branch" and then used phrases like "new branch" and "old branch". What exactly do I mean by the word *branch* here? That's the other human problem: the word *branch* sometimes means *some set of commits*. But it also sometimes means *a branch name*. When we think it means one, but it means the other, we get confused and mess things up. – torek May 27 '21 at 00:11
  • See also [What exactly do we mean by branch?](https://stackoverflow.com/q/25068543/1256452) – torek May 27 '21 at 00:12
  • @WilliamPursell Haha yeah I was half asleep; just replace "remote" with "branch". – konoufo May 27 '21 at 09:26

2 Answers2

1

Consequences

Before doing this you should be aware of the consequences. If anyone else is using the same remote and also has a local copy of stable, them pulling the new branch will lead to a merge of your new stable and their local version of the old stable, resulting in a combination of the changes from both branches (supposedly with huge merge conflicts).

Probably the best solution to this problem is that everyone who is using that remote deletes the stable branch in their local repository as soon as you have replaced the old version and then fetches the updated version of stable from the remote:

git checkout develop
git branch -D stable
git fetch
git checkout stable

This first makes sure something different than stable is checked out as the branch currently checked out cannot be deleted. Then the local stable is deleted, the current changes from the remote are fetched and the new stable is checked out.

Solution

First you should create a local stable branch with the content of the previous develop branch by deleting the old local stable branch and then creating a new one:

git checkout develop
git branch -d stable
git checkout -b stable

Trying to push this branch to the remote will fail as the remote branch contains changes your local branch does not contain. You will receive some message like this one:

Updates were rejected because the tip of your current branch is behind its remote counterpart. Integrate the remote changes (e.g. 'git pull ...') before pushing again.

There are two ways to work around this. They both lead to the same result, deleting the old stable from the remote and replacing it with your local new version of stable.

git push --force

You can tell git to ignore and discard the remote changes by using the parameter --force.

git push --force stable

Delete the remote branch first

Alternatively you could manually delete the remote branch and afterwards push the new version:

git push :stable
git push origin stable

The first parameter of git push is where to push something and the second parameter is what to push where, divided by a colon. git push origin a:b would push your local branch a to origin using the name b on origin. By leaving out the a part "nothing" will be pushed to stable, leading to deletion of stable on the remote.

Process improvement

It might be a good idea to change your process such that develop and stable stay closer together so you don't need to discard the old stable but can merge your changes from develop to stable.

Maybe you could do regular merges of stable to develop to keep them in sync. To simplify this you could also do fixes and changes required in both versions in stable and then merge them to develop. However how good this might work depends heavily on your processes and how far stable and develop drift apart.

lucash
  • 1,982
  • 17
  • 25
0

Attention The proposed solution is destructive. Please try in on test or copied repository only!


# Update your local refs

git fetch --all

# Create the "old_stable" branch from current "stable" and push it

git checkout stable
git branch old_stable
git push old_stable --set-upstream origin old_stable

# Create a new "stable" branch from "develop"

git checkout develop
git branch -D stable
git branch stable

# Force remote "stable" branch recreation

git push stable --force

Antonio Petricca
  • 8,891
  • 5
  • 36
  • 74