Resolving conflicts via UI in a MR results in corruption of the fork
- Version: GitLab 9.0.4-ee
- Ticket: https://gitlab.zendesk.com/agent/tickets/72476
Steps to reproduce
- Have an upstream project and a fork.
- Create a Merge Request from the fork to the upstream project.
- Make a change in the upstream project (example CHANGELOG file)/create a merge conflict
- The MR page will go into "conflict", proceed to “Resolve conflicts” from the UI, uses ‘edit inline’ to merge changes in the CHANGELOG file, then commits changes from the UI.
Expected result
MR is merged and we can now “Accept Merge Request”
Actual result
The MR page is in a weird state where only “Merge locally” is available. The fork becomes corrupted at the filesystem level due to missing blob and is unusable: it cannot be cloned anymore. Running ‘git fsck’ in the server filesystem for the fork results in:
# git fsck
Checking object directories: 100% (256/256), done.
Checking objects: 100% (4094/4094), done.
broken link from tree 171a0ad1ca598d84ea2d578a4efb4b0dcc9e1bc0
to blob b518cd8edc2a4dcc98f5675272450448eb4c8a2c
dangling blob aa4517474ae8a77a16af15079d5c537f8a60eed8
missing blob b518cd8edc2a4dcc98f5675272450448eb4c8a2c
dangling blob 042549e605c5d2ac216f2f62b75b99991e054808
Notes:
This happens consistently for that particular Merge Request (if I restore the fork’s initial state and do the same operations again, they always result in corruption; the same happens after copying the not-yet-corrupted fork and upstream projects to a different GitLab server and redoing the same steps). Other Merge Requests are in general not affected, but this is the second time we run into this corruption issue when rebasing from the UI, with two different and unrelated projects.
The first time we had corruption after a user rebased from the UI, we thought was just bad luck, but this has happened again on a completely different repository and we are worried of future corruption affecting other repositories.
There are NO error or anything suspicious in the logs apart from downstream errors that result from the missing blob (e.g. UpdateMergeRequestsWorker fails). I strongly suspect the corruption happens silently in Rugged inside Projects::MergeRequestsController#resolve_conflicts, which pushes an incomplete commit to the fork. The usual chain of PostReceive/ProcessCommitWorker/UpdateMergeRequestsWorker then takes place and faces a corrupted repository.
For instance Sidekiq log shows this error:
2017-04-07_15:39:44.89408 2017-04-07T15:39:44.893Z 264 TID-ot0d7w21c UpdateMergeRequestsWorker JID-582c701a0c87391b12a4998e INFO: fail: 0.819 sec
2017-04-07_15:39:44.89422 2017-04-07T15:39:44.894Z 264 TID-ot0d7w21c WARN: {"context":"Job raised exception","job":{"class":"UpdateMergeRequestsWorker","args":[3059,96,"36d2c5058d6b4f60bf8a8422419f25c8cb7e2db5","4b7700b6e0d0cf5f3f4df71055675728aec6b17f","refs/heads/master-innerpix"],"retry":3,"queue":"update_merge_requests","jid":"582c701a0c87391b12a4998e","created_at":1491579584.0499632,"enqueued_at":1491579584.0535,"error_message":"Object not found - no match for id (171a0ad1ca598d84ea2d578a4efb4b0dcc9e1bc0)","error_class":"Rugged::OdbError","failed_at":1491579584.892977,"retry_count":0},"jobstr":"{\"class\":\"UpdateMergeRequestsWorker\",\"args\":[3059,96,\"36d2c5058d6b4f60bf8a8422419f25c8cb7e2db5\",\"4b7700b6e0d0cf5f3f4df71055675728aec6b17f\",\"refs/heads/master-innerpix\"],\"retry\":3,\"queue\":\"update_merge_requests\",\"jid\":\"582c701a0c87391b12a4998e\",\"created_at\":1491579584.0499632,\"enqueued_at\":1491579584.0535}"}
2017-04-07_15:39:44.89423 2017-04-07T15:39:44.894Z 264 TID-ot0d7w21c WARN: Rugged::OdbError: Object not found - no match for id (171a0ad1ca598d84ea2d578a4efb4b0dcc9e1bc0)
2017-04-07_15:39:44.89428 2017-04-07T15:39:44.894Z 264 TID-ot0d7w21c WARN: /opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/rugged-0.24.0/lib/rugged/tree.rb:9:in `diff'
2017-04-07_15:39:44.89428 /opt/gitlab/embedded/lib/ruby/gems/2.3.0/gems/rugged-0.24.0/lib/rugged/tree.rb:9:in `diff'