Reputation: 5360
Suppose the structure of the commits is like the one below:
B'---C' X'
/ \ / \
A---B---C---D---...---X---Y---Z(master)
And now I need to strip all the commits between A and X,
X'
/ \
A---X---Y---Z
AFAIK, there are at least 2 way to achieve this:
But there are always some conflicts that I need to manually handle.
Since I only would like to purge all the commits after A and before X and I don't need to change any git tracking results after each commit(for instance, the newly generated commits X share the same contents as the old X commit), is there an easier way to do so?
Upvotes: 4
Views: 433
Reputation: 48428
Note: This solution will squash the commits you want to "strip" into X, so that the new X commit and all following commits have their files in the exact same state that they are now. If this isn't what you wanted, see my other answer.
git checkout -b temp A
git merge X --squash
git commit -C X # Create new x commit
git checkout master
git rebase --preserve-merges --onto temp X # Rebase onto new X commit (should produce no conflicts)
git -d temp
Upvotes: 1
Reputation: 48428
Edit: This solution will remove the old commits (including any changes made in them) from the repository. This aparently isn't what the op was asking but I'll leave the answer here anyway for future readers.
git checkout master
git rebase --onto A X~
I can't guarantee there won't be conflicts, but if you do run into any you can resolve them manually, git add
the files with the conflicts, and then type git rebase --continue
.
Alternately, you could force git rebase
to automatically resolve any conflicts by applying the more recent changes over the top of any conflicting changes made in A (or before):
git checkout master
git branch backup # Just to be safe
git rebase -s theirs --onto A X~
git branch -D backup # When you're sure master has everything you need
Upvotes: 0
Reputation: 12273
I'd try something like:
git checkout -b new_X X
git rebase -i A # set everything to 'squash'
git checkout master
git rebase --preserve-merges --onto new_X X
This hopefully should keep commit changes the same, so there would be conflicts. If this fails, I would probably resort to low-level commands like git commit-tree
and some script to create the new structure from original trees.
Upvotes: 0