0

I have two branches, ServerA and ServerB. The code in both is nearly the same, but not identical. ServerB branched off of ServerA in the past. I want to create a new dev branch with code changes that will be merged into both of the server branches.

I could create dev by branching ServerA, but I don't want ServerA's differences to go to ServerB or vice versa.

Or I could create a separate devA and devB branches, but then changes common to both would have to be done twice, once in each dev branch.

Is there a way to create a single dev branch that I can merge into both server branches, that also allows me to continue to make server specific changes on each of the server branches?

I have tried merging, maybe an orphan branch or rebasing the new branch?

Biffen
  • 6,249
  • 6
  • 28
  • 36
  • 1
    Are the 2 branches related? (As in, they share some ancestors). If they are _not_ related, is the layout of the name-space similar? (Same directories/files, even if there are differences). – eftshift0 Dec 14 '22 at 21:20
  • 1
    If I understand correctly, and if the answer to @eftshift0's question is they do share ancestors, then you could make your branch from the merge-base of the two server branches, e.g. `git switch -c new-branch $(git merge-base ServerA ServerB)` – TTT Dec 14 '22 at 21:31
  • 1
    _or_ even from the tip of one of the branches and then rebase `--onto` the other branch. But the technique to use depends on the answers. – eftshift0 Dec 14 '22 at 21:47
  • Yes, they all they all come from ServerA originally. – Wisconsin Wes Dec 14 '22 at 22:01
  • Is the premise stated at the top of my answer correct? If so, I'd like to update your question so that it is easier to understand and more easily found by people in a similar situation. – Inigo Dec 18 '22 at 18:19

1 Answers1

0

Sounds like you want to retroactively implement a "master" or "main" branch that contains all the common code, and have your "server" branches be branches off of it containing server-specific code.

Since ServerA was the original branch, it was the master branch up until you created ServerB. So that's where we'll start:

  1. Back up your repo in case this process goes wrong somewhere.
  2. Find the commit in the commit history where ServerB branches off from ServerA.
  3. Create a new master branch at this point:
git branch master <SHA-1 or other ref for last common commit>
  1. Incorporate changes common to both server branches into master. You can do this a number of ways:
    • Manually cherry-pick commits from ServerA that have equivalent commits on ServerB. Use this method if you want recreate the history of common changes in master. If the commit cherry-picked from ServerA also includes changes specific to ServerA, you can use git cherry-pick -n to give you a chance to remove those specifics, or you can use git commit --amend to fix them after each cherry-pick.

      This option will recreate your original commit history in master. But the longer your commit history since "the split", the longer this will take. It may or may not be worth it to you.

    • Use your IDE or Git GUI frontend to do a diff between ServerA and master, then use the GUI to copy/merge individual changes into master that belong in master. Commit those changes into master.

      This option will result in all your common changes since the fork point to be represented in master as a single commit.

    • Copy the latest state from ServerA into the worktree for master, remove all the ServerA specific stuff, and then commit this to master:
      1. git checkout master
      2. git checkout master -- . to update the state of your worktree to the head of master without switching branches
      3. git add -p to selectively add only the common changes to the index.
      4. git commit perhaps with a message stating that the commit includes all common changes since the ServerA/ServerB split.

      This option will result in all your common changes since the fork point to be represented in master as a single commit.

  2. Make the git history reflect the fact that all of the changes in the master branch have already been made in the server branches. Here are two ways:
    • Merge master into both server branches. If you did the previous steps accurately, you can safely tell git to resolve all conflicts by accepting what's already in the server branch:
      git checkout ServerA
      git merge -s ours master
      
      Since all the changes in master should already be in each of the server branches, it should be an empty commit, even with the conflict resolution above.
    • Rebase both server branches onto master. Do this if this is also what you place to do for the server branches going forward. If not, do the merge described above.
  3. Confirm that the final state of each branch is right.
    • Diff the head of ServerA with its last commit before this process. It should be an empty diff. Do the same for ServerB.
    • Diff each server branch with master. You should see nothing in the diff that should be common to both servers.
  4. Have a or some .
Inigo
  • 12,186
  • 5
  • 41
  • 70