Here you should use git rebase --onto and specify a range.
(see git rebase man page :
transplant a topic branch based on one branch to another to pretend that you are forking a topic branch from the last branch using rebase --onto .
)
Of course, this will move your bug10 branch over the legacy branch, which does not fit your needs.
Thus, one way would be to do this reboot in the cloned repo, and then merge this extended legacy branch (the one in the cloning repository, with bug10 to) for the local and current legacy branch (the one you want to change, leaving bug10 only).
Now:
- this is due to an additional repo (which may lead to limited disk space)
- in general, this is quite equivalent to defining a patch and applying it to the
legacy branch, so that the other answers (patch) are valid (and easier). - The only advantage that I see in this method is the ability to define an outdated environment in which you reinstall what you want (e.g.
bug10 ) before pushing only this legacy branch to the original repo (you do not bug10 since it the story would be completely rewritten!)
I just wanted to see if it works, so ... Let me check this approach.
(Git1.6.5.1, on old XP SP2, with Powershell 1.0 session due to Start-Transcript command)
PS D:\> mkdir git PS D:\> cd git PS D:\git> mkdir tests PS D:\git> cd tests PS D:\git\tests> git init mainRepo
I like how I no longer need to make a git repo directory, and then type git init ! Starting from version 1.6.5 :
" git init " learned mkdir / chdir in the directory when it was given an additional argument (ie, " git init this ").
This is BIG!
Let me create 3 files for three different purposes.
(For an example, I will store file changes separately for each branch: no conflicts during merge or redirection here.)
PS D:\git\tests> cd mainRepo PS D:\git\tests\mainRepo> echo mainFile > mainFile.txt PS D:\git\tests\mainRepo> echo contentToBeFixed > toBeFixedFile.txt PS D:\git\tests\mainRepo> echo legacyContent > legacy.txt PS D:\git\tests\mainRepo> git add -A PS D:\git\tests\mainRepo> git ci -m "first commit" PS D:\git\tests\mainRepo> echo firstMainEvol >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "first evol, for making 1.0" PS D:\git\tests\mainRepo> git tag -m "1.0 legacy content" 1.0
At this point, a git log --graph --oneline --branches returns:
* b68c1f5 first evol, for making 1.0 * 93f9f7c first commit
Let build legacy branch
PS D:\git\tests\mainRepo> git co -b legacy PS D:\git\tests\mainRepo> echo aFirstLegacyEvol >> legacy.txt PS D:\git\tests\mainRepo> git ci -a -m "a first legacy evolution"
We will return to the wizard, make another commit, which we will mark "2.0" (release, which will require bug fixes!)
PS D:\git\tests\mainRepo> git co -b master PS D:\git\tests\mainRepo> git co master PS D:\git\tests\mainRepo> echo aMainEvol >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a main evol" PS D:\git\tests\mainRepo> echo aSecondMainEvolFor2.0 >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a second evol for 2.0" PS D:\git\tests\mainRepo> git tag -m "main 2.0 before bugfix" 2.0
We have:
* e727105 a second evol for 2.0 * 473d44e a main evol | * dbcc7aa a first legacy evolution |/ * b68c1f5 first evol, for making 1.0 * 93f9f7c first commit
Now we create the bug10 :
PS D:\git\tests\mainRepo> git co -b bug10 PS D:\git\tests\mainRepo> echo aFirstBug10Fix >> toBeFixedFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a first bug10 fix" PS D:\git\tests\mainRepo> echo aSecondBug10Fix >> toBeFixedFile.txt PS D:\git\tests\mainRepo> git ci -a -m "a second bug10 fix"
Add add final commit on main branch
PS D:\git\tests\mainRepo> git co master PS D:\git\tests\mainRepo> echo anotherMainEvol >> mainFile.txt PS D:\git\tests\mainRepo> git ci -a -m "another main evol"
Final state of our main repo:
* 55aac85 another main evol | * 47e6ee1 a second bug10 fix | * 8183707 a first bug10 fix |/ * e727105 a second evol for 2.0 * 473d44e a main evol | * dbcc7aa a first legacy evolution |/ * b68c1f5 first evol, for making 1.0 * 93f9f7c first commit
At this point, I will not do any further manipulations in mainRepo. I will only clone it to do some tests. If this fails, I can always go back to this repo and clone it again.
The first clone is actually required to execute our git rebase --onto
PS D:\git\tests\mainRepo> cd .. PS D:\git\tests> git clone mainRepo rebaseRepo PS D:\git\tests> cd rebaseRepo
In our cloned repo, we need two mainRepo branches:
PS D:\git\tests\rebaseRepo> git co -b bug10 origin/bug10 PS D:\git\tests\rebaseRepo> git co -b legacy origin/legacy
Allows you to reinstall only error10 (this is all fixed after the 2.0 tag to the HEAD branch of bug10 ) :
PS D:\git\tests\rebaseRepo> git co bug10 PS D:\git\tests\rebaseRepo> git rebase --onto legacy 2.0 First, rewinding head to replay your work on top of it... Applying: a first bug10 fix Applying: a second bug10 fix
At this point, bug10 was played on top of legacy without any other intermediate commits .
Now we can forward HEAD from legacy to the beginning of the replayed bug10 branch.
PS D:\git\tests\rebaseRepo> git co legacy Switched to branch 'legacy' PS D:\git\tests\rebaseRepo> git merge bug10 Updating dbcc7aa..cf02bfc Fast forward toBeFixedFile.txt | Bin 38 -> 104 bytes 1 files changed, 0 insertions(+), 0 deletions(-)
The content corresponds to what we need:
- We have all the outdated content:
PS D:\git\tests\rebaseRepo> type legacy.txt legacyContent aFirstLegacyEvol
- for the
main branch, there is only a 1.0 tag (root for the legacy branch) and no more .
PS D:\git\tests\rebaseRepo> type mainFile.txt mainFile firstMainEvol
- and
bug10 fixes are here:
PS D:\git\tests\rebaseRepo> type toBeFixedFile.txt contentToBeFixed aFirstBug10Fix aSecondBug10Fix
What is it.
The idea is to pull this “extended” legacy branch into your original repo, which will still remain without bug10 (i.e., still starting with the 2.0 tag and not being replayed anywhere, as we did on rebaseRepo .
In this cloned repo, I track the origin/legacy branch to merge the legacy branch of another remote source on it: rebaseRepo .
PS D:\git\tests\rebaseRepo> cd .. PS D:\git\tests> git clone mainRepo finalRepo PS D:\git\tests> cd finalRepo PS D:\git\tests\finalRepo> git co -b legacy origin/legacy
In this original repo (I only cloned it so as not to mess with the state of mainRepo, in case I had other experiments), I will rebaseRepo as remote and select its branches.
PS D:\git\tests\finalRepo> git remote add rebasedRepo D:/git/tests/rebaseRepo PS D:\git\tests\finalRepo> type D:\git\tests\finalRepo\.git\config [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = D:/git/tests/mainRepo [branch "master"] remote = origin merge = refs/heads/master [branch "legacy"] remote = origin merge = refs/heads/legacy [remote "rebasedRepo"] url = D:/git/tests/rebaseRepo fetch = +refs/heads/*:refs/remotes/rebasedRepo/* PS D:\git\tests\finalRepo> git fetch rebasedRepo remote: Counting objects: 8, done. remote: Compressing objects: 100% (6/6), done. remote: Total 6 (delta 3), reused 0 (delta 0) Unpacking objects: 100% (6/6), done. From D:/git/tests/rebaseRepo * [new branch] bug10 -> rebasedRepo/bug10 * [new branch] legacy -> rebasedRepo/legacy * [new branch] master -> rebasedRepo/master
Now we can update legacy without touching bug10 :
PS D:\git\tests\finalRepo> git merge rebasedRepo/legacy Updating dbcc7aa..4919b68 Fast forward toBeFixedFile.txt | Bin 38 -> 104 bytes 1 files changed, 0 insertions(+), 0 deletions(-)
You can repeat the process as many times as you want, whenever you need to run a new bug10 , you need to replay over the old legacy branch, not including all intermediate commits.