You may be able to package up both paths of the content tree and use something like WinMerge or Kdiff to do a item by item comparison, which might be quick and dirty but may be hard to wade thru especially in instances of inherited fields. I usually like to see if I can use Sitecore Powershell Extensions to complete potentially repeatable tasks like this. You may or may not have SPE installed but in the event you might, this may help you:
# Site 1 content path
$site1 = "/sitecore/content/Sites/Site1"
# Site 2 content path
$site2 = "/sitecore/content/Sites/Site2"
# Get site relative paths and IDs
$site1Desc = Get-ChildItem -Path "master:$site1" -Recurse
$site1Lookup = $site1Desc | ForEach-Object { $lookup = @{} } { $lookup[$_.FullPath.Replace($site1, "")] = $_.ID } { $lookup }
$site1LookupRel = $site1Desc | ForEach-Object { $objArr = @() } {
$newObj = (New-Object -TypeName PSObject | Add-Member NoteProperty Name $_.Name -PassThru | Add-Member NoteProperty ID $_.ID -PassThru | Add-Member NoteProperty Path $_.FullPath.Replace($site1, "") -PassThru)
$objArr += $newObj
} { $objArr }
$site2Desc = Get-ChildItem -Path "master:$site2" -Recurse
$site2Lookup = $site2Desc | ForEach-Object { $lookup = @{} } { $lookup[$_.FullPath.Replace($site2, "")] = $_.ID } { $lookup }
$site2LookupRel = $site2Desc | ForEach-Object { $objArr = @() } {
$newObj = (New-Object -TypeName PSObject | Add-Member NoteProperty Name $_.Name -PassThru | Add-Member NoteProperty ID $_.ID -PassThru | Add-Member NoteProperty Path $_.FullPath.Replace($site2, "") -PassThru)
$objArr += $newObj
} { $objArr }
# Compare lists of relative paths/items
$itemComparison = Compare-Object -ReferenceObject $site1LookupRel -DifferenceObject $site2LookupRel -Property Path -IncludeEqual
$matchingItems = $itemComparison | Where-Object { $_.SideIndicator -eq "==" } |Select-Object -Expand Path
$nonMatchingItems = $itemComparison | Where-Object { $_.SideIndicator -ne "==" } |Select-Object -Expand Path
Write-Host " *** Matching Items *** "
foreach($matchingItem in $matchingItems) {
$site1MatchingItem = $null;
$site2MatchingItem = $null;
if($site1Lookup.Contains($matchingItem))
{
$site1MatchingItem = Get-Item -Path "master:" -ID $site1Lookup[$matchingItem]
}
if($site2Lookup.Contains($matchingItem)){
$site2MatchingItem = Get-Item -Path "master:" -ID $site2Lookup[$matchingItem]
}
if($site1MatchingItem -ne $null -AND $site2MatchingItem -ne $null) {
$site1ItemFieldValues = Get-ItemField -Item $site1MatchingItem -ReturnType Field -Name "*" | Where-Object {!$_.ContainsStandardValue} | Select-Object -Property @{Name="SourceID"; Expression={$site1MatchingItem.ID}},Name,Value
$site2ItemFieldValues = Get-ItemField -Item $site2MatchingItem -ReturnType Field -Name "*" | Where-Object {!$_.ContainsStandardValue} | Select-Object -Property @{Name="SourceID"; Expression={$site12MatchingItem.ID}},Name,Value
if($site1ItemFieldValues -ne $null -AND $site2ItemFieldValues -ne $null){
Write-Host "$matchingItem does exist in both sites, comparing now - (" $site1MatchingItem.ContentPath " <=>" $site2MatchingItem.ContentPath ")" -ForegroundColor Green
$comparedItems = Compare-Object -ReferenceObject $site1ItemFieldValues -DifferenceObject $site2ItemFieldValues -Property Name,Value -IncludeEqual -PassThru
$comparedItems | Format-Table -AutoSize
}
else{
Write-Host "$matchingItem does exist in both sites, but there is nothing to compare - (" $site1MatchingItem.ContentPath " <=>" $site2MatchingItem.ContentPath ")" -ForegroundColor Green
}
}
}
Write-Host " *** NonMatching Items *** "
foreach($nonMatchingItem in $nonMatchingItems) {
$site1MatchingItem = $null;
$site2MatchingItem = $null;
if($site1Lookup.Contains($nonMatchingItem))
{
$site1MatchingItem = Get-Item -Path "master:" -ID $site1Lookup[$nonMatchingItem]
}
if($site2Lookup.Contains($nonMatchingItem)){
$site2MatchingItem = Get-Item -Path "master:" -ID $site2Lookup[$nonMatchingItem]
}
if($site1MatchingItem -ne $null -AND $site2MatchingItem -eq $null){
Write-Host "$nonMatchingItem exists in Site1 but not Site2 - (" $site1MatchingItem.ContentPath ")" -ForegroundColor Yellow
}
elseif($site1MatchingItem -eq $null -AND $site2MatchingItem -ne $null){
Write-Host "$nonMatchingItem exists in Site2 but not Site1 - (" $site2MatchingItem.ContentPath ")" -ForegroundColor Yellow
}
}
The above SPE script should grab all content under a Site
path and compare it to the other site by site relative paths (path underneath the site node itself). If an item exists in one site and not the other it will show up in the bottom nonMatchingItems
and show up in yellow in the output. If they do match, it will show up green and will use the Get-ItemField
command to get the fields you specify (in this case *
is used to return all fields, in which we then filter based on ContainsStandardValue
to filter out items that are currently using Standard Value
values) and associated values.
It uses the Powershell Compare-Object
command output to a table to show you how the fields themselves compare. Output should look something like this:
*** Matching Items ***
.....
/_content does exist in both sites, but there is nothing to compare - ( /Site1/_content <=> /Site2/_content )
/_content/Country Landing Intro does exist in both sites, comparing now - ( /Site1/_content/Intro <=> /Site2/_content/Intro )
SourceID Name Value SideIndicator
-------- ----- ----- -------------
{96892835-46BF-437A-8C9E-40B12EC58881} Image Is Map true ==
{96892835-46BF-437A-8C9E-40B12EC58881} Is Header true =>
{98D165DB-25EA-4E80-B9A3-ABCC181A9FAF} Is Header false <=
/Cities does exist in both sites, but there is nothing to compare - ( /Site1/Cities <=> /Site2/Cities )
*** NonMatching Items ***
/Cities/Second-Test exists in Site1 but not Site2 - ( /Site1/Cities/Second-Test )
/Cities/Second-Test/_content exists in Site1 but not Site2 - ( /Site1/Cities/Second-Test/_content )
This should help as a starting point, I could see extending the matched item comparison (the SideIndicator
Value) to go into more detail on the exact field values that differ, but at least identifying which fields differ may help you in the current capacity.
Additional commentary here