Größe der Packdateien unter Git beschränken

Im Versionsverwaltungssystem Git existieren im Repository sogenannte Packfiles. Diese werden genutzt um mehrere Objekte, wie z.B. Commits, Trees, Blobs oder Tags, als einzelne Dateien abzulegen. Damit fasst Git viele Objekte zu einer einzelnen komprimierten Datei zusammen. Ergänzt wird das ganze durch einen Index, um einen schnellen Zugriff zu ermöglichen. Dabei nutzt Git Delta-Kompression, indem es ähnliche Objekte, z. B. verschiedene Versionen derselben Datei, nicht vollständig speichert, sondern nur die Unterschiede.

Eine Git-Pack-Datei im Schema

Dies reduziert die Repository-Größe erheblich, kann aber bei ungünstigen Repositorys mit vielen Binärdaten zu Repositorys führen, welche mehrere dutzend Gigabyte große Pack-Dateien besitzen. Eine Steuerung ist über den Konfigurationsparameter pack.packsizelimit möglich:

git config pack.packsizelimit 5g

Damit würde diese Einstellung für das aktuelle Repository gesetzt werden. Wer das Ganze global benötigt, kann dies ebenfalls einstellen:

git config --global pack.packsizelimit 5g

Allerdings gilt diese Einstellung nicht sofort, stattdessen muss für ein Repack gesorgt werden:

git repack -Ad --max-pack-size=5g

Anschließend kann die Größe der Packs kontrolliert werden:

ls -lh .git/objects/pack

Allerdings sollte beachtet werden, das die Option grundsätzlich nur in Ausnahmefällen sinnvoll ist:

Note that this option is rarely useful, and may result in a larger total on-disk size (because Git will not store deltas between packs) and worse runtime performance (object lookup within multiple packs is slower than a single pack, and optimizations like reachability bitmaps cannot cope with multiple packs).

Probleme mit dem Git-Index beheben

Wer beim Arbeiten mit Git, z.B. beim Versuch einen Commit zu erstellen, folgende Meldung erhält:

fatal: unknown index entry format 0xb4d90000

ist damit konfrontiert das der Index des Git-Repositories Inkonsistenzen aufweist. In diesem Fall hilft es den Index zu löschen:

rm -f .git/index
git reset

Danach können wieder Dateien zum Index hinzugefügt werden und anschließend darauf aufbauende Operationen, wie Commits und ähnliches vorgenommen werden.

Redirect 301 vs. 302

Wenn von einer Webseite auf eine andere Webseite umgeleitet wird, so wird hierfür meist der HTTP-Statuscode 301 oder 302 genutzt. Der Statuscode 301 leitet eine Anfrage permanent zur angegebenen URL um, während der Statuscode 302 früher für die temporäre Umleitung gedacht war. Unter Nginx könnte eine solche Umleitung wie folgt aussehen:

server {
  listen   443 ssl;
  listen [::]:443 ssl;

  server_name .example.com;

  return 301 https://example.org;
}

In diesem Fall würde alle Anfragen von example.com auf die URL https://example.org umgeleitet. Der Statuscode 301 zeigt dem Client hierbei an, dass die Umleitung permanent ist. Dies ist z.B. wichtig bei Suchmaschinen; sie würden der neuen URL mehr Beachtung schenken und die alte URL unter Umständen schneller aus dem Index entfernen. Der Statuscode 302 ist mittlerweile nicht mehr als Moved Temporarily, sondern als Found definiert.

Neben diesen Statuscodes, existieren eine Reihe weitere Statuscodes wie 303 (See Other), 307 (Temporary Redirect) und 308 (Permanent Redirect). Im Gegensatz zu den Statuscodes 301, 302 und 303 wird bei den neueren Statuscodes 307 und 308, das angefragte HTTP-Verb beibehalten. Fragt der Clients in einem solchen Fall mit dem HTTP-Verb POST an, so bleibt dieses bei der Weiterleitung bestehen.

Chronologische Abfrage unter Elasticsearch

Elasticsearch ist eine quelloffene Suchmaschine. Über eine Query kann eine Suche spezifiziert werden, welche für die entsprechenden Ergebnisse sorgt. Manchmal soll allerdings die Ausgabe der Daten eines Index von Elasticsearch chronologisch erfolgen. Dies ist z.B. sinnvoll, wenn Logdaten oder ähnliches in diesem gespeichert werden. In einem solchen Fall sollen sie unter Umständen chronologisch ähnlich dem Aufruf tail -f angezeigt werden. Dazu dient folgender Request:

GET https://elastic.example.org:9200/index/_search

Zusätzlich muss die eigentliche Query im Body der Anfrage, als JSON hinterlegt werden:

{
  "query": {
    "match_all": {}
  },
  "size": 10,
  "sort": [
    {
      "timestamp": {
        "order": "desc"
      }
    }
  ]
}

Das hier für die Sortierung genutzte Feld timestamp muss in den Daten enthalten sein, sonst funktioniert die Sortierung nicht. Nach dem Absetzen der Query, erhält der Nutzer zehn Einträge, beginnend mit den neusten Einträgen.

Waipoua-Theme für den Podlove Publisher anpassen

Seit meinem letzten Wechsel des Designs auf seeseekey.net nutze ich eine stark modifizierte Version des Elmastudio-Themes Waipoua. Neben Anpassungen am Design wurden unter anderem die externen Einbindungen der Google Fonts deaktiviert. In den aktuellen Themes von Elmastudio werden diese leider immer noch extern eingebunden; was wohl auch auf absehbare Zeit so bleibt.

Leider hat das Waipoua-Theme einige Probleme mit dem Plugin Podlove Publisher. Der Podlove Publisher ist ein Plugin, welches einen Workflow für Podcasts, vom Anbieten bis zum Abonnieren bereitstellt.

Podlove Podcast Publisher
Preis: Kostenlos

Das erste Problem mit dem Podlove Publisher im Zusammenhang mit dem Waipoua-Theme ist die Anzeige der von Beiträgen mit dem Post Type podcast auf der Startseite. In den Experteneinstellungen des Podlove Publishers ist dies die Einstellung Blog und Podcast kombinieren. Damit dies mit dem Waipoua-Theme funktioniert muss die Datei index.php des Themes angepasst werden. Dort findet sich folgende Quelltextblock:

<?php /* Start the Loop */ ?>
<?php global $query_string;
query_posts( $query_string . '&ignore_sticky_posts=1' ); ?>

  <?php while ( have_posts() ) : the_post(); ?>

    <?php get_template_part( 'content', get_post_format() ); ?>

  <?php endwhile; // end of the loop. ?>

<?php wp_reset_query(); // reset the query ?>

An dieser Stelle werden sämtliche Manipulationen der Abfrage entfernt. Anschließend sollte der Code so aussehen:

<?php /* Start the Loop */ ?>

  <?php while ( have_posts() ) : the_post(); ?>

    <?php get_template_part( 'content', get_post_format() ); ?>

  <?php endwhile; // end of the loop. ?>

Nach dieser Modifikation tauchen die Beiträge mit dem Post Type podcast in der Beitragsliste im Startmenü auf. Das nächste Problem betrifft die Darstellung der Beiträge mit dem Post Type podcast, sobald diese einzeln angezeigt werden. Hierbei wird das Design zerschossen, da der Beitrag in voller Breite angezeigt wird. Eine Sidebar würde in diesem Szenario nach unten rutschen.

Nach dem Fix funktionieren die Einzelseiten mit dem Post Type podcast

Um dies zu verhindern muss die Datei header.php angepasst werden. Dort findet sich nach dem schließenden head-Tag die Zeile:

<body <?php body_class(); ?>>

Diese Zeile wird entfernt und stattdessen durch folgenden Quellcode ersetzt:

// Fix problem with single posts (post type: podcast)
$body_class = get_body_class();

// single-podcast exists in body class, replace
if (in_array("single-podcast", $body_class)) {

  echo "<body class=\"";

  foreach($body_class as $body_class_value) {
    if ($body_class_value == "single-podcast") {
      $body_class_value = "single-post";
    }

    echo $body_class_value . " ";
  }
  
  echo "\" >";
}
else {
?>
  <body <?php body_class(); ?>>
<?php
}
?>

Der Quellcode sorgt dafür das die Klasse single-podcast in single-post umbenannt wird. Damit greift das CSS für gewöhnliche Beiträge und die Darstellung der Podcast-Seiten funktioniert ohne Probleme. Als letzten Schritt habe ich die archive.php angepasst. In der Datei wurde der komplette header-Block entfernt. Diese Anpassung ist im Gegensatz zu den anderen Anpassungen Geschmackssache. Sie sorgt dafür das keinerlei Archivtexte mehr auftauchen.