while working on our code we encountered a problem inside our git repository:
On august 15th, the method "CheckforLogout" inside the class "UserHelper" was still present (Commit: 08cc360 or green commit in the picture). After the 26th of august, this method was completly gone.
I checked wether there was a commit where the method was deleted, but there was none.
After reading a similar thread i started bisecting the commits with the result, that the commit 9013cf5 (Yellow commit in the picture) was the "bad one".
The probable cause for this behaviour is, that my boss made changes and comitted them to the repository without pulling first. As his respository was rather out of date, a merge was then in order. As a result of this merge, my method was removed.
Therefore the "bad commit" was out of date and did not have my method.
The important questions for me:
We are currently using GitLab 12.6.4-ee for our git server.
Thank you for your consideration!
The picture you've shown probably doesn't give enough context to clarify exactly what's happening; but we can start with this: The yellow commit (marked "bisect bad") is on a different branch[1] from the "green" commit and everything after it, and its parent is not shown in the picture (it's off the bottom of the screen). So combining that with what you've explained, we can make some educated guesses:
Most likely we're looking at something like
... O -- x -- G -- x -- P1 -- M -- ... <--(HEAD)
\ /
Y -- x -- x -- x -- P2
Now presumably when you bisected, you marked G
as "known good" and HEAD
as "known bad". Every ancestor of G
would be excluded from the search, so Y
would get singled out as the oldest commit not meeting your criteria. (It's not an ancestor of G
, but it doesn't contain your code.) To clarify that point - your code also isn't in O
, but you wouldn't expect it to be - it hasn't been added yet - and so bisect isn't paying attention to O
(because it's an ancestor of G
which is known to be good).
But really Y
is fine; the issue is most likely at M
. During a normal merge, git would look at all changes from O
to P1
-- including the addition of your code at G
-- and also all changes from O
to P2
. It would attempt to apply all of those changes on top of O
to produce the merge result.
Most likely some change from O
to P2
conflicted with the addition of your code, requiring manual intervention. You can confirm that by performing the same merge operation again.
git checkout P1
git merge P2
(This oeration would take place in "detached HEAD" state and would be a throw-away merge, just to recreate what happened. Afterward you would probably want to abort the merge and check back out to your working branch.)
If there was indeed a conflict affecting your function, then the most likely explanation is that it was resolved incorrectly. If so, this is not a problem git can solve - the point of manual conflict resolution is that the tool can't automatically decide what the right thing is. Sometimes you can't make the tool protect you from a person making a mistake.
(Resolving merge conflicts is a skill. Often it's not too hard to see what you shoudl do, but for example if the other branch was in fact deleting code from that same area of the code, then the conflict markers could've looked like your code was just part of the block being deleted.)
Note that whatever change conflicted with yours wouldn't necessarily be in G
; it would just be somehwere between O
and P2
.
If, when you redo the merge, there is no conflict, then the next thing is to see whether your version of the merge still contains your code; if there was no conflict, then it should. If not, then more info would be needed to figure out what's going on - and unfortunately I wouldn't know what to ask at that point, short of actually examining the repo (which I'm sure is a bit too proprietary for that).
If the redo merge does contain your code, then for some reason the orignial merge was done differently, and then it's something that only the person who performed the merge can explain.
[1] In this case I've used "different branch" in the sense of commit topology. It could be that everyone was working on master
and thinks of themselves as "on the same branch", but if you pushed while the other person was working, then they pulled to update from the remote, this would be like the code from the remote (origin/master
) being on a separate branch from the local code (just master
).