Ziel ist es ein Git Repository in ein anderes, leeres Git Repository zu kopieren, inklusiver aller Daten wie z.B. der History. Also das Kopieren / Klonen / Duplizieren eines Repositories inklusive aller Infos. Es reicht also nicht den Ordner nur zu kopieren und in das neue Repository zu pushen, damit hätte dieses Repository nur 1 Commit, nicht aber alle Daten übernommen.

Hier die Abfolge der Schritte:

  1. Das alte Repository „old-repo“ auf der Festplatte auf den aktuellsten Stand bringen; logisch
  2. Einen Ordner für das neue Repository anlegen; der Name des Ordners sollte dem Namen des neuen Repositories entsprechen
  3. Den Inhalt des Ordners „old-repo“ in den Ordner „new-repo“ kopieren
  4. Git Bash in „new-repo“ starten bzw. diesen Ordner in der Bash aufrufen
  5. Git origin neu setzen, Ziel ist das neue Repository:
    git remote set-url origin git@[Server IP/URL]:new-repo
  6. Neuen Master Stand pushen:
    git push origin master

Hier ein Video der Vorgehensweise:

Vor langer Zeit suchte ich eine Möglichkeit coole Locations und besuchenswerte Orte gut sichtbar „anpinnen“ zu können, auf einer großen Karte wie der Google Map. Warum das nicht selber entwickeln? 😉

Mit der „Location Map“ habe ich versucht diesen Gedanken umzusetzen. Auf der Google Map kann man mit Hilfe eines Formulars neue Locations mit einem Icon anpinnen, und noch eine Beschreibung hinzufügen. Die Beschreibung kann bequem mit einem Editor bearbeitet werden. Ebenso lassen sich die Einträge natürlich nachträglich bearbeiten und löschen.
location-map-interaktive-google-maps-webapplication-banner
location-map-interaktive-google-maps-webapplication-tooltip location-map-interaktive-google-maps-webapplication-editform

Der größte Knackpunkt des Projekts bestand darin die in der Datenbank gespeicherten Locations dynamisch auf die Google Map laden zu lassen und jeder Location ein eigenes Icon, ein Klick Event und ein Info Window zu geben. Diesen schweren Part würde ich hier kurz veröffentlichen. Ich gehe davon aus, dass ihr schon mit der Google Map hantiert und sie am besten auch schon lauffähig realisiert habt. Hier geht es jetzt nur noch im die Location Marker mit Icon, Klick Event und Info Box.

Hinweis: Dieser Code und die folgenden Anmerkungen beziehen sich auf eine veraltete Version der Location Map, zeigen aber die Grundfunktionalität der Map mit den Locations. Der Aufbau zeigt also eine Art Minimalgerüst. Für weitere Features bitte den Code aus der Demo Page (siehe unten) benutzen.
Code

map.php:

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas"></div>

In der Webseite wird beim onload die initialize Funktion aufgerufen, in der die Google Map initialisiert und zusammengebastelt wird.

locations-main.js:

/* GMaps v3 !!! */				
function initialize() {
	
	// map initialisieren
	map = new google.maps.Map(document.getElementById("map_canvas"), 
	{
		zoom: 11,
		center: new google.maps.LatLng(52.510788, 13.426666),
		mapTypeId: google.maps.MapTypeId.HYBRID
	}); 
	 
	// marker
	$.ajax({
		type: 'POST',
		url: 'locationmgr.php',
		dataType: 'json',
		data: 'action=get',
		success: function(data) {
			for (loca in data) {
				setMarkers( map, 
					data[loca]['XKoord'], 
					data[loca]['YKoord'],
					data[loca]['Titel'],
					data[loca]['Icon'],
					data[loca]['Inhalt'],
					data[loca]['EventID']
					);
			}
			infowindow = new google.maps.InfoWindow({
				content: "loading...",
				maxWidth: 300
			});
		}
	});
}

function setMarkers(map, XKoord, YKoord, Titel, Icon, Inhalt, ID) {
	var marker = new google.maps.Marker({
		position: new google.maps.LatLng(XKoord, YKoord),
		map: map,
		title: Titel,
		html: generateInfoWindowHtml(Titel, Icon, Inhalt, ID),
		icon: new google.maps.MarkerImage("img/"+ Icon +".png")
	});

	google.maps.event.addListener(marker, "click", function () {
		infowindow.setContent(this.html);
		infowindow.open(map, this);
		$('div.infowindow').css({
			'height':'+=3px'
		});
	});
}

function generateInfoWindowHtml(Titel, Icon, Inhalt, ID) {
	var html = "\
	<div class='infowindow'>\
		<img class='infowindowmoodicon' src='img/"+Icon+".png' alt='"+Icon+"' />\
		<h5>"+Titel+"</h5>\
		<div class='fulltext'>"+decodeHtml(Inhalt)+"</div>\
		<span class='edit' onclick='javascript:editLocation("+ID+");'>(edit)</span>\
	</div>";
	return html;
}

function decodeHtml(encodedHtml) {
  return encodedHtml
      .replace(/&amp;/g, '&')
      .replace(/&lt;/g, '<')
      .replace(/&gt;/g, '>')
      .replace(/&quot;/g, '"')
      .replace(/&#039;/g, "'");
}

Anmerkungen:
Wie in Zeile 1 schon gesehen, ist der Code nach dem aktuelleren Google Maps API v3 Standard programmiert. Irgendwann während meiner Entwicklung stellte Google von v2 auf v3 um und ich programmierte ebenso mein halbes Projekt um, man möchte ja mit dem Fortschritt mithalten.
In den Zeilen 4-10 wird die Google Map im div initialisiert, das Zentrum auf den Berlin Alexanderplatz gesetzt, Zoom und MapType gesetzt.
Nun werden in 12-19 die Locations mit der locationmgr.php aus der Datenbank geladen und für Javascript aufbereitet. Die Daten werden entgegengenommen und eine Schleife durchläuft nun in Zeile 19 jeden Locationdatensatz. setMarkers wird aufgerufen und erzeugt in den Zeilen 38-44 ein Marker Objekt. Dieses wird mit map: map direkt auf die Google Map gepinnt.
Hier erfolgt noch der Aufruf der generateInfoWindowHtml. Diese bastelt ein optisch etwas angepasstes InfoWindow mit der Beschreibung und gibt das komplette HTML Paket zurück an das Marker Objekt, welches daraus das Info Window baut.
In den Zeilen 46-52 wird ein Listener auf das soeben erstellte Marker Objekt gelegt.
Diese 3 Schritte – Marker erstellen, InfoWindow generieren, Listener zuweisen – werden für jede Location ausgeführt und in die Map integriert.


Demo

http://public.hannes-schurig.de/LocationMapDemo/map.php
Demo Version: 0.16


Changelog

Code anzeigenDen Code könnt ihr bequem mit den Links/Rechts Pfeiltasten horizontal bewegen.

Changelog (08.04.2013)

  • v0.1: Event Map zeigt Events an, Events können erstellt und gelöscht werden, 2 Icons stehen zur Verfügung
  • v0.2: Events lassen sich anklicken, ein kleines Popup mit Zusatzinformationen erscheint, Eingabe der Zusatzinformationen bei neuen Events möglich
  • v0.3: Statt getrennter X und Y Koordinaten kann jetzt ein Koordinatenstring, der sich aus Google Maps extrahieren lässt, eingeben
  • v0.4: Statische Icons in eine Datenbank übertragen, die möglichen Icons werden jetzt direkt beim Erstellen neuer Events angezeigt und können somit ausgewählt werden
  • v0.5: Infofenster für das Koordinatentextfeld, komplette Umbenennung in Location Map inklusive aller Codeverweise
  • v0.6: Locations löschen jetzt via selektieren, mit Suchfunktion
  • v0.7: etliche Designverbesserungen und Fixes
  • v0.8: komplette Umprogrammierung: Umstieg von Maps API v2 auf Maps API v3
  • v0.9: komplette Umprogrammierung: Umstieg von HTML Forms auf AJAX
  • v0.10: kleine Informationsfenster als Feedback für den User am unteren Bildschirmrand
  • v0.11: 2 Events mit gleichem Namen verboten, doppelte Überprüfung
  • v0.12: Edititeren von bestehenden Locations
  • v0.12.1: Löschen aus dem Update Dialog
  • v0.12.2: Umstrukturierung des HTML Codes, neuer Formularaufbau
  • v0.13: Dialog Manager kürzt den Code um ca 20%
  • v0.14: verbesserte Unterstützung von Auflösungen kleiner als 1280px
  • v0.14.1: Fehler im Dialog Manager, wenn der zu öffnende Dialog schon geöffnet ist, behoben
  • v0.15: für die Veröffentlichung vorbereitet: Read-Only-Modus, Read-Only-Designset
  • v0.15.1: neuer HTML Head, Meta Tags, see/ref ergänzt, CSSDOC DocBlock erweitert
  • v0.16: Maus-Features: Linksklick auf die Map -> fügt automatisch die Koordinaten des Klicks in das „Neue Location“ Koordinatenfeld ein, Rechtsklick auf die Map -> Management Menü (noch ungenutzt)

To-Do:
Rechte- & Usermanagement
Zuklappen der rechten Seite zulassen
Größen der Map und Formulare dynamisch ändern
Mehr Icons
fehlerhaften Login optisch hervorheben
Unterstützung für mobile Geräte und kleinere Auflösungen einbauen/verbessern


Download

Ich habe schon ein Paket fertig geschnürt, dass die komplette Entwicklung in wenigen Minuten auf dem eigenen Server einrichten lässt, werde das aber erstmal nur auf Anfrage herausgeben. Die Entwicklung hat noch einige Macken und vermisst noch viele Features. Vorerst werde ich selber an dem Projekt weiterarbeiten und es dann in einem reiferen Zustand veröffentlichen.

Ich erinnere mich noch an das vor langer Zeit präsentierte 26 Gigapixel Halbpanorama von Paris. Das war schon gigantisch, wie weit man zoomen konnte und trotzdem noch ein scharfes Bild vor sich hatte. Tja, fuck that.
320 Gigapixel! Das ist neue Fototechnik! Ein London Panorama mit insgesamt 320 Gigapixel. Das heißt ich kann den Text lesen, den eine Frau dutzende Kilometer entfernt, in ihr Handy tippt… zumindest fast 😀
330-gigapixel-london-panorama

Das ist schon sexy moderne Fototechnik. Auch nett ist das skyhigh Panorama von der Spitze des Burj Khalifa über Dubai. Der Zoom rockt hier nicht so aber die Aussicht ist schon gewaltig.
330-gigapixel-london-panorama-dubai

via, via

Wenn ein frisch installiertes Betriebssystem erstmal fertig eingerichtet ist und perfekt läuft sollte man diesen Zustand im Notfall wiederherstellen können. Das Sichern von funktionierenden Treibern ist einer der Schritte, die man dafür regelmäßig durchführen sollte.

Double Driver ist klein, portable, kostenlos, einfach zu bedienen und besonders schnell!

Die Oberfläche ist besonders einfach und die Bedienung ist selbsterklärend:

Die Treiber des eigenen Systems sind in weniger als 1 Sekunde komplett geladen (zumindest bei mir). Irgendwie soll man auch andere Systeme scannen können; wie das geht habe ich aber noch nicht getestet.

Wie bei den meisten Treiber Backup Tools werden alle Systemtreiber gelistet aber nur die non-Microsoft Treiber ausgewählt. Diese Selektion ist schon am sinnvollsten, lässt sich bei Bedarf aber verändern. „All“, „None“, „Invert“ beschleunigen die Anpassung.

Die Treiber lassen sich als Ordner, als gezippte Ordnerstruktur oder als selbstentpackendes Archiv sichern. Treiber größerer Systeme können schon mal 100-200MB groß sein, die 2 ZIP Auswahlmöglichkeiten würde ich also empfehlen. Damit kann die Größte auf 40-80MB verringert werden. Das Wiederherstellen der Treiber ist ebenso simpel. Die Sicherung wird ausgewählt und alle gesicherten Treiber werden aufgelistet. Hier kann man dann entweder alle Treiber wiederherstellen oder einzelne Einträge deselektieren.

Das Tool ist dazu portable, muss also nicht installiert werden und funktioniert sofort auf jedem System, gerne auch vom USB Stick aus.

Super Freeware, Hut ab.
Das Sichern der Treiber funktioniert auch bei Windows 8. Ich gehe davon aus, dass auch die Wiederherstellung funktioniert. Probieren geht über studieren.

Bis vor Kurzem habe ich noch FastStone Capture als mein Windows Screenshot Utility genutzt. Die Software wurde irgendwann kostenpflichtig und ich blieb dann auf der letzten kostenlosen Version des Programms sitzen.
Letztens las ich auf lifehacker von einer angeblich guten Screenshot Freeware: PicPick!

Ich habe die Software mittlerweile auf all meinen Computern installiert und bin wirklich überzeugt; die Software kann alles, was man von einem Screenshot Utility erwartet!

Übersichtliche Oberfäche in modernem Design:

Oberfläche, Nutzung und Dialoge an das bekannte Office Ribbon angelehnt:

Komplexer Bildeditor mit vielen Funktionen, Formen, Effekten, guter Handhabung, einfach top:

Vielen Einstellungsmöglichkeiten, u.A. automatischer FTP Server Upload und wichtige Shotcuts:

Wer also eine solche Freeware sucht, mit seiner aktuellen Software nicht so zufrieden ist oder einfach den King der Screenshots testen möchte: PicPick ist euer Kandidat!

Ich habe bereits vor einigen Monaten mal über die Erkennung von laufenden Prozessen via Batch geschrieben. Damals habe ich diese Erkennung in einfachen oder komplexeren If Else Blöcken verschachtelt. Ich habe nun gemerkt, dass dies zu Problemen und falschen Erkennungen führen kann!

Daher hier das Update: If Else Verschachtelungen können zwar ein paar Zeilen sparen aber verfälschen Errorlevel Rückgaben! In If Else Blöcken würde ich keine Programmbefehle schreiben, die mit dem Errorlevel arbeiten sollen. Lieber mit einigen gotos arbeiten.

Hier ein Beispiel:

REM Statt:
if /i %action%==start-server (
 tasklist |find /i "IQB_Server.exe"
 if not %errorlevel%==0 start IQB_Server.exe
 goto end
)

REM folgenden Code verwenden:
if /i %action%==start-server goto start-server
:start-server
 tasklist |find /i "IQB_Server.exe"
 if not %errorlevel%==0 start IQB_Server.exe
 goto end

REM Errorlevel in IF ELSE Blöcken können falsch sein!

Nochmal zum Erkennen von Prozessen via Batch: hier sind 3 verschiedene funktionierende Methoden:

REM %errorlevel% ist immer 0 wenn der Prozess existiert
REM 1 wenn nicht gefunden
REM am besten mit 'if not "%errorlevel%"=="0"' überprüfen

REM Variante 1:
tasklist | find /i "dropbox.exe"

REM Variante 2:
tasklist /FI "IMAGENAME eq dropbox.exe" 2>NUL | find /I /N "dropbox.exe">NUL
REM beide NUL Umleitungen optional

REM Variante 3:
tasklist /nh /fi "imagename eq dropbox.exe" | find /i "dropbox.exe" >NUL
REM letzte NUL Umleitung optional

English Version

A few months ago I already wrote a post about the detection of running processes with batch. In this post I used this detection code inside simple or more complex if-else block statements. I recently noticed possible false positives if doing so. Using %errorlevel% return codes inside if-else statements can lead to wrong return codes.

So, here’s the update: if else structures can save a few code lines but can also falsify errorlevel return codes! And since the detection of running processes rely on errorlevel returns you should use gotos instead of if else.

Here’s a code example:

REM instead of:
if /i %action%==start-server (
 tasklist |find /i "IQB_Server.exe"
 if not %errorlevel%==0 start IQB_Server.exe
 goto end
)

REM use this code:
if /i %action%==start-server goto start-server
:start-server
 tasklist |find /i "IQB_Server.exe"
 if not %errorlevel%==0 start IQB_Server.exe
 goto end

REM errorlevel return codes in if-else blocks may be wrong!

Here are 3 different working code examples for process detection:

REM %errorlevel% is always 0 if the process is running
REM and 1 if it is not running
REM best way is to check with 'if not "%errorlevel%"=="0"'

REM code 1:
tasklist | find /i "dropbox.exe"

REM code 2:
tasklist /FI "IMAGENAME eq dropbox.exe" 2>NUL | find /I /N "dropbox.exe">NUL
REM both NUL redirections are optional

REM code 3:
tasklist /nh /fi "imagename eq dropbox.exe" | find /i "dropbox.exe" >NUL
REM last NUL redirection is optional

via, via

Das Ziel sind Screenshots von Webseiten, mit einem Batch Script automatisiert und kontrolliert. Keep it simple & stupid.

Die Wichtigste ist natürlich das Anfertigen der Screenshots. Das ließe sich vermutlich auch mit pure Batch erledigen, ich fand allerdings folgende Utilities besonders einfach und optimal für diesen Zweck: CutyCapt und IECapt. Beide Tools bestehen nur aus einer kleinen .exe Datei und sind kommandozeilenbasiert, optimal für eine Batch Benutzung.
CutyCapt fertigt Website Screenshots mit der WebKit Engine (Chrome und Opera nutzen diese Engine) an, IECapt nutzt die Engine des Internet Explorers.

Die Anwendung ist relativ einfach, über die CMD. Ein Beispiel:

CutyCapt.exe --url=http://www.spiegel.de/ --out=spiegel.png --min-width=1100 --min-height=800 --delay=1000

Wenn die Webseite besonders lang ist so wird sie komplett aufgenommen. Die Parameter steuern das Verhalten der Engine, beim IE gibt es nicht ganz so viele Möglichkeiten.

Das kann man jetzt in einem netten Script verpacken und schon lassen sich beliebige Webseiten mit einem Doppelklick fotografieren. Versehen mit Logging, Mailer und ein paar Kleinigkeiten, fertig.

Hier mein Script, welches 2 Screenshots der Fritz Box aufnimmt, in einem Unterordner speichert, eine Mail schickt und alles loggt, so als Muster:

Code anzeigenDen Code könnt ihr bequem mit den Links/Rechts Pfeiltasten horizontal bewegen.

@echo off
setlocal
Color 9f

REM ### INFORMATIONS ############################################

REM ****************************************************
REM  Title:   	Website Screenshot Daemon (WSD)
REM  Author:  	Hannes Schurig
REM  Created: 	22.02.2013
REM  Changed: 	25.02.2013
REM  Version: 	0.3.5
REM  Changelog: 0.1: complete mailer function with flexible callback
REM				0.1.1: complete new mailer with call, parameters and no local variables, 50% less code
REM				0.2: CutyCapt configured to take 2 screenshots, formatted datetime filename
REM				0.2.1: collect errorlevels and added to mail text
REM				0.2.2: save screenshots in subfolder, check if exist, create if needed
REM				0.3: use working directory and absolute paths for sheduling compatibility
REM				0.3.1: script renamed, detect working directory and filename
REM				0.3.2: removed usesubdir variable, remove 40-45 and edit 51 & 53 for no subdir
REM				0.3.3: fixed bug - spaces in working path lead to script malfunction
REM				0.3.4: CutyCapt parameters as variable - they do not change
REM				0.3.5: added 20 seconds max-wait parameter
REM  Credits: CutyCapt website screenshot utility: http://cutycapt.sourceforge.net/ - awesome!
REM ****************************************************

REM ### VARIABLES ############################################

for %%a in (%0) do set filename=%%~nxa
for %%a in (%0) do set wd=%%~dpa
REM remove last "\" or "/" from working directory (wd) path
if "%wd:~-1%"=="\" set wd=%wd:~0,-1%
if "%wd:~-1%"=="/" set wd=%wd:~0,-1%
set subdir=%wd%\screenshots
set mailer=1
set adminmail=hannes.schurig@online.de
set log="%wd%\logfile.txt"
set cutycapt="%wd%\CutyCapt.exe"
set datetime=0
set scerrorlevel=0

REM same parameters for every screenshot? It's shorter with:
set cutycaptparameters=--min-width=1100 --min-height=800 --delay=1000 --max-wait=20000

REM ### PROGRAM START ############################################

echo %date% - %time:~0,5% (i) WSD starting... >> %log%

REM check and create subdir if wanted and needed
if not "%subdir%"=="" (
	if not exist "%subdir%" (
		md "%subdir%"
	)
)

REM prepare short datetime with . instead :
set datetime=%date%-%time:~0,5%
set datetime=%datetime::=.%

%cutycapt% --url=http://fritz.box/ --out="%subdir%/%datetime%-dashboard.png" %cutycaptparameters%
set scerrorlevel=%errorlevel%
%cutycapt% --url=http://fritz.box/system/syslog.lua --out="%subdir%/%datetime%-events.png" %cutycaptparameters%
set scerrorlevel=%scerrorlevel%%errorlevel%

echo %date% - %time:~0,5% (i) Screenshot taken with errorlevel %scerrorlevel% >> %log%

echo %date% - %time:~0,5% (i) Sending admin mail... >> %log%
if %mailer%==1 call :mailer "WSD" "Status" "noreply@WSD.com" "Script finished with errorlevel %scerrorlevel%"

:shutdown
echo %date% - %time:~0,5% (i) WSD shutting down... >> %log%
goto end


REM ### MAILER FUNCTION ############################################

:mailer
start iexplore "http://php.webmailer.de/webmail.php&mailto=%adminmail%&contactname=%~1&subject=%~2&email=%~3&message=%~4"
REM wait and close
ping 127.0.0.1 -n 5 > nul
taskkill /im "iexplore.exe" /f
ping 127.0.0.1 -n 3 > nul

REM ### PROGRAM EXIT ############################################

:end
endlocal

Anmerkungen dazu:
Keine Unterordner? Löscht Zeile 49-54 und passt den „–out“ Parameter in Zeile 60 und 62 an. Wenn doch, passt Zeile 28 an.
IECapt statt CutyCapt? In Zeile 38 den Dateinamen anpassen.
Der Mailer muss natürlich angepasst werden. Habt ihr einen PHP Webmailer? Dann passt die Zeilen 36, 68 und 78 an. Wenn ihr keinen Mailer habt reicht es die Zeile 35 auf 0 zu setzen.
Ansonsten müsste das funktionieren.

Alternativ zu diesem Script gibt es auch Browser Plugins mit denen Website Screenshots erstellt werden können. Awesome Screenshot wäre ein Google Chrome Plugin für diesen Zweck. Die Extension fotografiert einen ausgewählten Bereich, den sichtbaren Bereich oder die komplette Seite. Das Bild lässt sich bearbeiten, speichern, teilen und mehr.
Über die Automatisierung dieser Geschichte muss man sich dann aber noch Gedanken machen, das ist vermutlich etwas schwieriger.

Bugs, Anmerkungen sowie Verbesserungsvorschläge nehme ich natürlich gerne entgegen.