2

Let's say that we have two versions of a library X: v1 and v2

I'm a maintainer for another library Y which uses library X. I was using v1 of the library, and it is there in master.

Then library X has come up with a new version v2, which required me to change the way I use the library (only package changes, library X changed it's name). Version v1 is now deprecated.

However, because my library is currently being used by enterprise users, who are not willing to update to a newer version of my library that uses v2. Also I'm supposed to provide fixes to the old version by contract.

I had two branches now:

  • master (uses v1)
  • new_master (uses v2)

The way I made this change is by developing on master, and rebasing new_master onto master. Then I can have one commit which contains changes that change all the v1 packages to v2 packages (import lines are the only changes).

master       x----x----x----x----x----n
new_master   x----x----x----x----x----f

(after rebase)

master       x----x----x----x----x----n
new_master   x----x----x----x----x----n----f

Now, I added a new feature to my library, which needs v2 of the library X. So it will only exist in new_master. After adding the new feature, the tree became like this.

master       x----x----x----x----x----x----n
new_master   x----x----x----x----x----x----f----n

I can do the same rebase here, but the commit n in the master tree needs to be fixed also. I don't want to add one more fix after the n of new_master.

What I get if I do a regular re-base:

master       x----x----x----x----x----x----n
new_master   x----x----x----x----x----x----n----f----n----f

Second f is the new fix commit, because after second n commit, branch new_master fails to compile.

What I need to get:

master       x----x----x----x----x----x----n
new_master   x----x----x----x----x----x----n----F----n

Where commit F is the new fix commit.

What am I currently doing to achieve this?

  • I'm solving this, by creating a new branch called new_master2 from new_master, then removing the new feature there.
  • Then I'm rebasing new_master2 onto master.
  • The commit for the new feature is lost, so I'm cherry-picking it from new_master.
  • Finally I delete the new_master branch, and I rename new_master2 as new_master.
  • I finish this by doing a force push to the remote.

What I'm trying to do?

Find another way to do the same thing, without creating the temp branch new_master2.

Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91

2 Answers2

1

As I unstands it is like this. You have two branches: master (uses v1) and new_master (uses v2). Now you have added a new commit in branch new_master.

master        x----x----x----x----x----x1----n

new_master    x----x----x----x----x----x1----f----n

Now for you to achieve the result below:

master       x----x----x----x----x----x1----n

new_master   x----x----x----x----x----x1----n----f----n

You can do the rebase like this:

git checkout new_master
git rebase master
--if there are conflicts solve the conflicts
--git add files_conflicts_you_solved
--git rebase --continue

What the above command will do is: *Move the head to point to new_master branch *Find the commit that is point of divergence for the two branches. In this case is commit x1. And make a copy of all commit on top x1 (in this case it only n commit) and paste on top x1 commit in the new_master branch.

Another solution without using rebase it would be like this: *Create a branch from master name dev *Cherry pick all commits from new_master in your dev branch

Below are the commands:

git checkout  master
git  branch dev
git checkout dev
git cherry-pick f^..n 
Rando Shtishi
  • 1,222
  • 1
  • 21
  • 31
  • It doesn't generate conflicts if the only commit I have on master is adding new files. Also, most of my changes will be modifications to XML files, which are not being modified in new_master. In this case, there won't be any conflicts. However, I have to fix the imports in new files too, and I don't want the fixes to be going to yet another commit. – Sri Harsha Chilakapati Feb 24 '20 at 21:04
  • If there are no conflicts that makes the work much easier. By doing the rebase only the commit n is going to be copied on top x1 in new_master branch. – Rando Shtishi Feb 24 '20 at 21:24
  • I don't want to do this, because it involves me to create a separate branch. After searching, I learned about the edit command in the interactive rebasing. I'll add my own answer on it. – Sri Harsha Chilakapati Feb 25 '20 at 02:47
1

After hours of searching, I came across this answer by @ZelluX. Now the steps are as follows:

$ git checkout new_master
$ git rebase -i master
# Editor opens, find my previous fix commit, and change the command to 'edit'
# If there are conflicts, fix them and continue rebasing
# Git will stop after making my old fix commit. Ensure everything compiles there.
# If you made any changes, then add them and ammend the commit
$ git add .
$ git commit --amend
# Once done, continue rebasing
$ git rebase --continue

This should solve the issue of making changes to the old fixup commit.

Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91