I did the following:
git checkout -b v1
<made some changes in the working directory, created commit c1 and push>
git checkout -b v2
<made some changes in the working directory, created commit c2 and push>
git checkout -b v3
<made some changes in the working directory, created commit c3 and push>
git checkout -b v4
<made some changes in the working directory, created commit c4 and push>
So now I have the following git tree structure:
M --- v1 --- v2 --- v3 --- v4
.
.
I made some more changes on v1 and did the following:
git checkout v1
<made some changes on working directory>
git add .
git commit --amend
git push origin v1 --force
Now when I check out on v4 I do not see the changes to commit c1 I pushed on v1... Where are the changes and how do I fix this mess?
Here's what happened.
You did what you did and had this:
M --- v1 --- v2 --- v3 --- v4
Actually, this is not entirely correct, you had this:
c1 --- c2 --- c3 --- c4 --- c5
^ ^ ^ ^ ^
M v1 v2 v3 v4
You have 5 commits, and 5 branches that each refer to their respective commit.
Then you checked out v1 and amended that commit, which in turn gave you this picture:
c1 --- c2 --- c3 --- c4 --- c5
^ \ ^ ^ ^
M \ v2 v3 v4
c2'
^
v1
Amending a commit does not change other branches or tags or commits that still refer to the old commit. It just creates a new commit and points the branch to this one.
What you have to do is rebase v2 on top of the new v1, then v3 on top of the new v2, and finally v4 on top of the new v3.
Step by step this would be the results of rebasing v2 on top of v3:
c1 --- c2 --- c3 --- c4 --- c5
^ \ ^ ^
M \ v3 v4
c2' --- c3'
^ ^
v1 v2
As you can see here, c3
is kept because c4
still refers to it and thus this commit will still be a part of both v3 and v4.
Finally, after rebasing both v3 and v4 you're left with:
c1 ( --- c2 --- c3 --- c4 --- c5 )
^ \
M \
c2' --- c3' --- c4' --- c5'
^ ^ ^ ^
v1 v2 v3 v4
Note that on disk, c2-c5 still exist, but since no branch or tag or other commits holds in the end of this line of commits, they're now not visible in the log, and they're eligible for garbage collection, which happens now and then. Once GC has executed, this is what you're left with:
c1
^ \
M \
c2' --- c3' --- c4' --- c5'
^ ^ ^ ^
v1 v2 v3 v4
which of course is the same as this:
c1 --- c2' --- c3' --- c4' --- c5'
^ ^ ^ ^ ^
M v1 v2 v3 v4