Git tip: see all commits introduced by a merge

Git has the useful function git log --first-parent that will show your branch without the commits introduced by merge commits. Sometimes I want the opposite (i.e., understand which commits were added by a merge), and there I find the following command useful: git log ^HEAD^ HEAD. This command will print the commits that are not (an ancestor of) the commit on your branch before the merge commit. Effectively, it will only show the commits brought in by the merge commit.

A more succinct but less readable version is git log ^@^ @ .

Changing default link sharing type for Teams channels in Microsoft 365

When you wish to change the default link sharing type for Teams channels in Office/Microsoft 365, the SharePoint admin interface is lacking the options to configure for this. This is now also mentioned in the SharePoint documentation since this GitHub PR, but the updated SP documentation does not go into detail on the exacts steps to take. To bridge the gap, this post will provide a script that you can use.

The following code will solve this problem by looping through all SharePoint sites and setting the default link sharing option to “people with existing access”, which was my use case. You can tweak the script to your requirements.

$admin_site_url = "https://<YOUR_SITE>.sharepoint.com"
 
Connect-SPOService -Url $admin_site_url
$site_collections = Get-SPOSite -Limit All
  
Foreach ($site in $site_collections)
{
    Write-Host $site.Url
    Set-SPOSite -identity $site.Url -DefaultLinkToExistingAccess $true
}

Workaround for Joplin-server encrypted notes sync error

Joplin-server is a nice solution to sync multiple Joplin instances. In fact, you can even use it to sync only a subset of your notebooks to certain devices by providing different user accounts for those devices and using the notebook-sharing functionality in Joplin-server.

I did find in Joplin-server that syncing shared encrypted notebooks didn’t always succeed in sharing the master keys. One workaround if you own all the accounts, of course is to use a single master key with a very strong password.

To achieve this:

  1. Close your secondary Joplin client with the option Joplin->Settings->Sync (advanced)->’delete local data and re-download from sync target’;
  2. Connect to the postgresql database with the credentials that you used to set it up (e.g. check your .env if you used docker-compose). Go to the table ‘items’;
  3. Inspect the stored master keys, e.g. [...] content LIKE '%activeMasterKeyId%'(should only hit for ‘info.json’);
  4. Copy the value of the content and content_size fields of your primary account to those of your secondary account (you can determine primary and secondary by comparing the keys with those found in Joplin->Settings->Encryption);
  5. On the secondary Joplin system, edit the database in ~/.config/joplin-desktop/database.sqlite and also insert the primary master key data into table ‘settings’ -> field ‘syncInfoCache’;
  6. Restart your secondary Joplin, and it will download your notes and use the right master key. No more yellow warning banners in the apps.

Home assistant temporary scenes based on area_id

When using lights in automations to inform the users (e.g., using light.turn_on with the flash property), you’ll want to reset the lights to their previous state after the automation is completed. In case of Hue lights it doesn’t seem to work to expand() the automatically-added light groups. What I’ve opted for instead, is to retrieve the entity_ids from an area and use this as input for scene.create (which requires, of course, that you assign each of the Hue lights to an area inside Home Assistant, which I find this an acceptable trade-off).

Since I use Node-RED for my automations, I do the following:

  • Template node, containing:
    {% for entity in expand(area_entities('<NAME_OF_YOUR_AREA>')) | selectattr('entity_id', 'match', 'light.*') %}
    {{ entity.entity_id }}{%- if not loop.last %}, {% endif -%}
    {% endfor %}

    (You can let it output to the payload field or another field of your choosing.)
  • Service call node, calling scene.create with data { "scene_id": "before", "snapshot_entities": $.payload }
  • <your light operations, such as hue.hue_activate_scene, flashing lights, etc.>
  • Service call node, calling scene.turn_on with data { "entity_id": "scene.before" }