My colleague did a series of careless pull/push operations. He end up in a situation where his local commit becomes missing
I recovered his commit using git reflog
. But I couldn't figure out why his operations lead to the situation. Can someone shed some lights?
See git reflog
output and comments below:
#######
# reflog is in reverse manner, most recent operation first
# test is like our "develop" branch, MTX-65 is the feature branch
# Both are remote-tracking
#######
39261b7 (HEAD -> MTX-65, origin/feature/MTX-65) HEAD@{0}: checkout: moving from test to MTX-65
7f66c72 (test) HEAD@{1}: checkout: moving from MTX-65 to test
39261b7 (HEAD -> MTX-65, origin/feature/MTX-65) HEAD@{2}: pull: Fast-forward
d51c1be HEAD@{3}: rebase finished: returning to refs/heads/MTX-65
d51c1be HEAD@{4}: rebase: Add Notification
c33d31f HEAD@{5}: pull --tags -r origin feature/MTX-65: checkout c33d31f4d0109396dea6d6bb78f47ba56097e4ac
#######
# This is the key commit that got lost
# It's not in `git log` out any more
#######
a6a7a7e HEAD@{6}: commit (merge): Warning message
3c8113c HEAD@{7}: commit (amend): Add Notification
7f551e4 HEAD@{8}: commit: Add Notification
96bcf99 HEAD@{9}: pull --tags -r origin feature/MTX-65: Fast-forward
b79bee0 HEAD@{10}: commit: personal & institution page
3cfb1aa HEAD@{11}: commit: Institution:
7f66c72 (test) HEAD@{12}: checkout: moving from test to MTX-65
7f66c72 (test) HEAD@{13}: merge MTX-65: Fast-forward
0733fd2 HEAD@{14}: checkout: moving from MTX-65 to test
7f66c72 (test) HEAD@{15}: commit (merge): Merge test
ebfaeea HEAD@{16}: checkout: moving from test to MTX-65
0733fd2 HEAD@{17}: pull: Fast-forward
1043c35 HEAD@{18}: checkout: moving from MTX-65 to test
#######
# This is a commit that still exists after the disaster
#######
ebfaeea HEAD@{19}: commit: institution 认证信息
Let's take a look at a6a7a7e HEAD@{6}: commit (merge): Warning message
.
commit (merge)
indicates the merge encounters conflicts. After resolving conflicts, your colleague changes the default commit message to Warning message
. The default message is like Merge made by the 'recursive' strategy
.
Then your colleague runs git pull --tags -r origin feature/MTX-65
. With -r
, git rebase
is used instead of git merge
after the fetch is done.
As the manual says,
By default, a rebase will simply drop merge commits from the todo list, and put the rebased commits into a single, linear branch.
There are many debates about which is better, git merge
or git rebase
. One of the pros for git rebase
is that we can use it to create a linear history in a convenient way. As designed, merge commits are dropped by default, although git rebase
provides -r
and -p
to preserve them in some situations.
During git rebase
, the conflicts are expected to occur again. In theory, the changes can't be lost if your colleague resolves them the same way as he does in the previous git merge
. You can try git log --reflog -S <keywords> -p
to find out in which commit the changes including the keywords get lost.