In my previous blog post I outlined the Split bug which was targeting merge changesets. To fix this issue I re-examined what mergeData contains and was able to come up with a solution. Let me explain why this bug is occurring and how I fixed it:
The Why
There are two types of changesets that are shown by the pushlog, normal changesets and merge changsets. This particular bug applies to merge changesets. When passing merge changeset data from the server side to the client side it is stored in a list, called mergeData. What does this list contain?
1. It contains a another list that contains another list, which contains strings (confusing, isn’t it?)
OR
2. It contains strings
Now, I thought that only the first option was possible and thus I didn’t take the second option into account when writing my code. I still don’t understand how sometimes the list is made up of option 1 while other time, option 2 occurs. Regardless, it does happen and I needed to find a solution
The Fix
Let me show you the code right away. The following is the code that fixes the issue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | //Check whether it is a merge changeset or not if(pushData[i].MergeData != []) { for(var j = 0; j < pushData[i].mergeData.length; j++) { if(pushData[i].mergeData[j] != "") { var mergeStr = pushData[i].mergeData[j]; for(var k = 0; k < pushData[i].mergeData[j].length; k++) { if(pushData[i].mergeData[j] instanceof Array) { var actualMergeStr = mergeStr[k].split('|-|'); var mergeC = actualMergeStr[0]; var mergeUser = actualMergeStr[1]; var mergeDesc = actualMergeStr[2]; } else { var actualMergeStr = mergeStr.split('|-|'); var mergeC = actualMergeStr[0]; var mergeUser = actualMergeStr[1]; var mergeDesc = actualMergeStr[2]; k = pushData[i].mergeData[j].length; } if(mergeDesc != pushData[i].desc) { var trScrollMerge = document.createElement("tr"); trScrollMerge.className = trScroll.className; var tdScroll_MergeUser = document.createElement("td"); tdScroll_MergeUser.width = "184px"; Create changset link var tdScroll_MergeC = document.createElement("td"); tdScroll_MergeC.innerHTML += '<a href="/rev/' + mergeC.substring(0, 12) + '">' + mergeC.substring(0, 12) + '</a>'; //Create bugLink var merge_bugLink = createBuglink(mergeDesc); var tdScroll_MergeAuthorDesc = document.createElement("td"); tdScroll_MergeAuthorDesc.innerHTML += '<strong>' + mergeUser + ' &mdash ' + merge_bugLink + '</strong>'; trScrollMerge.appendChild(tdScroll_MergeUser); trScrollMerge.appendChild(tdScroll_MergeC); trScrollMerge.appendChild(tdScroll_MergeAuthorDesc); document.getElementById("titlePush").appendChild(trScrollMerge); } } } } } |
Basically, line 7 is the key here. The instanceof keyword allows me to find out whether the variable I am examining is a list or not. If it is a list, then mergeData contains option one and I perform the appropriate parsing. However, if it isn’t a list, then option 2 has occurred and I parse the data in a different way.
Adding the above functionality completely solved my problem. No more errors with Split() and all the merge changesets are appearing properly.