Andreas Korthaus: Versionskontrolle bei Webprojekten

Hallo!

Mich würde mal interessieren wie Ihr Eure Webprojekte mit einem Versionskontrollsystem verwaltet. Nachdem ich Dank lighttpd auf trac gestoßen bin, habe ich mir das direkt mal installiert. Trac ist ein sehr simples System, es beinhaltet Webzugriff auf das subversion repository (alles IMHO sehr schön gelöst, auch mit diffs (Bsp.)), und ein recht einfaches Ticket/Bugtracking System (z.B.: neues Ticket, Übersicht, Ticket) und ein wiki. Aber das nur am Rande ;-)

Ich habe subversion auf einem Server eingerichtet. Entwickelt wird auf diesem und auf einem anderen Server (jeweils Testumgebungen). Naja, eigentlich wird lokal entwickelt (Windows XP), und auf einem Server (Gentoo Linux) getestet, PHP eben ;-)
Aber das "testen" ist eben mein Problem. Ich kann nicht lokal testen, weil die  Software eben lokal nicht so einfach ans Laufen zu bekommen ist. Ich will aber lokal entwickeln, weil ich nur hier eine ordentliche Entwicklungsumgebung habe (IDE...). Ich habe jetzt also nicht nur eine Working-Copy, sondern eigentlich zwei. Lokal schreibe ich Code, lade den auf einen Server um den zu testen, und wenn das läuft "committe" ich das ganze.

Im Moment habe ich nur eine Working-Copy auf dem Test-Server, lokal lade ich mir ggfs. Dateien runter. Das ist aber alles andere als das gelbe vom Ei ;-)

Vor allem wenn man auf verschiedenen Rechnern arbeitet ist das sehr lästig und auch fehleranfällig. Ich hatte auch dran gedachte den Umweg von einer lokalen Working-Copy über svnserve zu gehen, und auf dem Server immer HEAD in das  Testverzeichnis auf dem Server entweder zu aktualisieren (svn update, hierbei muss das Testverzeichnis eine Workingcopy sein), oder vielleicht besser zu exportieren (per svn --force export..., dann wäre ich auch die .svn Verzeichnisse in der Webumgebung los da das Testverzeichnis keine Workingcopy mehr sein muss), nur ist das IMHO sehr umständlich. Aber vielleicht könnte man den letzten Schritt per post-commit Hook automatisieren? Dann würde man gar nichts mehr per SCP/SFTP hochladen, sondern nur noch per svn+ssh:// Änderungen übertragen, die dann sofort in der Testserver-Umgebung sichtbar werden. Allerdings ist dann für jede noch so kleine Änderung ein commit inklusive Kommentar fällig - was auch irgendwie nervig ist, denn es kommt bei größeren Änderungen oft vor dass ich eine Datei mehrmals hochladen muss, bis alle Flüchtigkeitsfehler draußen sind, und am liebsten würde ich die Datei eben erst am Ende "committen".

Daher meine Frage an Euch - wie löst Ihr sowas? Wie macht Ihr das bei Euren Webprojekten?

Naja, dann müsste ich mir auch abgewöhnen zwischendurch kleine Änderungen mit nano/vi direkt vorzunehmen, oder ich brauche online einfach noch eine zusätzliche Working-Copy.

Noch eine andere Frage - wie kann ich bei subversion bestimmte Dateien ignorieren? Ich habe zwar so Sachen wie svn:ignore gefunden, aber das ist AFAIK nicht das was ich will. Ich habe z.B. eine Konfigurationsdatei, die spezielle Angaben wie Pfade, DB-Zugangsdaten... enthält. Die Datei muss auch im Versions-Kontrollsystem sein, da sich diese auch ändern kann. Allerdings hier in einer "anonymisierten" Form. Nur würde Subversion jetzt bei einem svn --force export eine lokale Konfigurationsdatei überschreiben. Wie kann ich das verhindern?

Viele Grüße
Andreas

--
SELFHTML Feature Artikel: http://aktuell.de.selfhtml.org/artikel/
  1. Meine Entwicklungsumgebung sieht so aus:

    Ein CVS-Repository befindet sich irgendwo im Internet.
    Auf einem lokaler Linux-Server läuft der Apache mit PHP. Das document root ist mit Samba freigegeben.
    Mittels WinCvs hole ich mir die Dateien in diese Freigabe und bearbeite sie auch dort (mit PhpEdit).
    Das Testen geht ganz normal mit dem Browser.
    Auch das Debuggen mit DBG funktioniert in dieser Konstellation.

    1. Hallo dedlfix!

      Ein CVS-Repository befindet sich irgendwo im Internet.
      Auf einem lokaler Linux-Server läuft der Apache mit PHP. Das document root ist mit Samba freigegeben.
      Mittels WinCvs hole ich mir die Dateien in diese Freigabe und bearbeite sie auch dort (mit PhpEdit).
      Das Testen geht ganz normal mit dem Browser.
      Auch das Debuggen mit DBG funktioniert in dieser Konstellation.

      Ja, das wäre auch eine Variante. Allerdings habe ich keinen lokalen Server, sondern nur einen öffentlichen zum Testen (ich weiß, ist auch nicht die beste Variante...), jedenfalls kann ich entsprechend nur SSH/SFTP/SCP für den Zugriff verwenden um auf den Server zuzugreifen. Hm. Ich könnte SMB (oder FTP oder WebDAV) durch SSH tunneln, naja... hm. Dummerweise müsste ich dafür jeweils einen neuen Dienst installieren und betreiben. Und offline arbeiten ginge auch nicht mehr. Aber auf jeden Fall eine bedenkenswerte Alternative - vielen Dank!

      Viele Grüße
      Andreas

      --
      SELFHTML Feature Artikel: http://aktuell.de.selfhtml.org/artikel/
      1. Moin!

        Ja, das wäre auch eine Variante. Allerdings habe ich keinen lokalen Server, sondern nur einen öffentlichen zum Testen

        Was hindert dich, einen WAMP einzurichten auf deiner Maschine? Das ist meine Variante (die ansonsten CVS statt SVN benutzt): Lokal greift der Server direkt in dem ausgecheckten Repository auf ein Verzeichnis als DOCUMENT_ROOT zu, und schon kann ich ohne lästige Commits lokal testen.

        Die Commits werden direkt danach automatisch auf einen öffentlichen Testserver aktualisiert - dann kann der Kunde ggf. auch angucken, wie der Stand ist. Und Releases installiere ich ebenfalls direkt per CVS-Zugriff auf dem Live-Server.

        • Sven Rautenberg
        1. Hallo Sven!

          Ja, das wäre auch eine Variante. Allerdings habe ich keinen lokalen Server, sondern nur einen öffentlichen zum Testen

          Was hindert dich, einen WAMP einzurichten auf deiner Maschine?

          Naja, das geht wohl, ist aber recht aufwändig. Z.B. nutze ich online nicht MySQL, sondern PostgreSQL oder auch DB2. Gut, ich verwende MDB2 zur Datenbankabstraktion, wäre also eine gute Gelegenheit zu überprüfen ob das auch alles so funktioniert. Bei der Umstellung von MySQL auf PostgreSQL gab es damals schon einige Dinge die ich im Code ändern musste (aber das war meine eigene Schuld, ich dachte jede DB kennt "LIMIT" ;-)). Allerdings ist es mir am liebsten in einer wirklichen 1:1 Kopie der Live-Umgebung zu testen. Ich verwende z.B. auch nicht Apache 2, demnächst werde ich wohl auch hier auf lighttpd umsteigen. Nächster Punkt sind spezielle Perl-Module die ich benötige... Ja, natürlich lässt sich das lokal alles hinbekommen, allerdings arbeite ich nicht immer an einem Rechner, alles in allem arbeite ich regelmäßig auf 4 verschiedenen Rechnern (natürlich alle nicht in einem LAN). Entsprechend müsste ich die Umgebung auf all diesen Rechnern installieren, dazu kommt dass Aktuelisierungen außerhalb der Versionskontrolle (Datenstruktur, neue Tabellen) manuell pflegen müsste. Oder könnte man die Datenstruktur ebenfalls irgendwie elegant unter Versionskontrolle stellen? Man könnte vielleicht eine SQL-Datei mit den Tabellendefinitionen ins repository aufnehmen, aber auch dann muss das noch irgendwie in die lokale DB eingelesen werden. Außerdem ist das blöd mit den Daten, bisher habe ich immer die komplette Test-DB als dump gespeichert, so dass ich dann auch direkt Testdaten habe.

          Das ist meine Variante (die ansonsten CVS statt SVN benutzt): Lokal greift der Server direkt in dem ausgecheckten Repository auf ein Verzeichnis als DOCUMENT_ROOT zu, und schon kann ich ohne lästige Commits lokal testen.

          Ja, das wäre halt der Vorteil. Im Moment mache ich das ja ähnlich, bis auf die "Kleinigkeit" dass ich die Änderungen erst per SCP von der lokalen Arbeitsumgebung in den DOCUMENT_ROOT übertragen muss, und meine "Arbeitsversion" nicht unter Versionskontrolle steht - was natürlich großer Mist ist ;-)

          Die Commits werden direkt danach automatisch auf einen öffentlichen Testserver aktualisiert - dann kann der Kunde ggf. auch angucken, wie der Stand ist.

          Machst Du das per "post-commit hook"?

          Und Releases installiere ich ebenfalls direkt per CVS-Zugriff auf dem Live-Server.

          Das machst Du dann per "export"?

          Viele Grüße
          Andreas

          --
          SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/
          1. Moin!

            Was hindert dich, einen WAMP einzurichten auf deiner Maschine?
            Naja, das geht wohl, ist aber recht aufwändig.

            Die Alternative mit Samba ist leider bei mir nicht so richtig machbar. TortoiseCVS arbeitet dann nicht richtig - irgendein Problem mit den Datumsangaben in den Dateien, weil Windows die Zeitzonen nicht richtig unterstützt. Ich müßte also auf dem Server mit der Kommandozeile agieren - das ist mir für Spezialdinge dann doch zu blöde. :)

            dazu kommt dass Aktuelisierungen außerhalb der Versionskontrolle (Datenstruktur, neue Tabellen) manuell pflegen müsste. Oder könnte man die Datenstruktur ebenfalls irgendwie elegant unter Versionskontrolle stellen?

            Elegant? Nein, davon habe ich noch nichts gehört. Ich bastel SQL-Dumps ins Repository, wenn es notwendig ist.

            Man könnte vielleicht eine SQL-Datei mit den Tabellendefinitionen ins repository aufnehmen, aber auch dann muss das noch irgendwie in die lokale DB eingelesen werden.

            Das wäre vielleicht ja sogar automatisierbar, aber der Client ist da wahrscheinlich die falsche Adresse - und da wäre es nötig.

            Die Commits werden direkt danach automatisch auf einen öffentlichen Testserver aktualisiert - dann kann der Kunde ggf. auch angucken, wie der Stand ist.
            Machst Du das per "post-commit hook"?

            In meiner Datei loginfo (aus CVSROOT) steht die Zeile
            ^modulname      (date; cat; (sleep 2; cd /var/www/vhosts; cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1

            Die hab ich mir irgendwann mal irgendwo abgeschrieben, und gut.

            Man muß also den Testserver einmalig manuell auschecken (bzw. kann Branches zwischendurch ebenfalls aktualisieren), und künftig wird das immer automatisch auf dem neuesten Stand gehalten (in diesem Branch).

            Und Releases installiere ich ebenfalls direkt per CVS-Zugriff auf dem Live-Server.
            Das machst Du dann per "export"?

            Manuell remote auf der Shell. :)

            • Sven Rautenberg
            1. Die Alternative mit Samba ist leider bei mir nicht so richtig machbar. TortoiseCVS arbeitet dann nicht richtig - irgendein Problem mit den Datumsangaben in den Dateien, weil Windows die Zeitzonen nicht richtig unterstützt.

              Ich denke

              dos filetime resolution = yes

              sollte dein Problem lösen, auch wenn du was von Zeitzonen schriebst.

              DOS und FAT [1] runden auf 2 Sekunden ab, Unix aber nicht. Damit erkennen Programme, die einen Zeitstempelvergleich machen einen Unterschied.

              [1] steht in der man page zur smb.conf. Das tritt aber auch unter XP auf, obwohl der Explorer sagt, dass das Dateisystem des Netzlaufwerks NTFS sei.

              1. Moin!

                Ich denke

                dos filetime resolution = yes

                sollte dein Problem lösen, auch wenn du was von Zeitzonen schriebst.

                DOS und FAT [1] runden auf 2 Sekunden ab, Unix aber nicht. Damit erkennen Programme, die einen Zeitstempelvergleich machen einen Unterschied.

                Das würde ja bedeutet, dass durchschnittlich die Hälfte der Dateien als "verändert" betrachtet würden. Das ist aber nicht der Fall, es werde ALLE Dateien als verändert betrachtet.

                Es ist wirklich ein Zeitzonenproblem, insbesondere mit der Sommerzeit. Windows speichert als Dateidatum die lokale Zeit. Unix speichert immer Greenwich-Zeit und errechnet mit der derzeit angegebenen Zeitzone dann die lokale Zeitangabe.

                TortoiseCVS enthält Code, um Bugs in der Windows-Zeitbibliothek zu kompensieren, aber das schlägt offensichtlich fehl, sobald man Unix-Sambalaufwerke einbindet. Abgesehen davon ist es auch nicht empfohlen, seine lokale CVS-Kopie auf Netzlaufwerken zu platzieren und muß extra freigeschaltet werden.

                • Sven Rautenberg
                1. Es ist wirklich ein Zeitzonenproblem, insbesondere mit der Sommerzeit. ...
                  TortoiseCVS enthält Code, um Bugs in der Windows-Zeitbibliothek zu kompensieren, aber das schlägt offensichtlich fehl, sobald man Unix-Sambalaufwerke einbindet.

                  Hmmm... dann weiß ich nicht, was du da verkehrt machst.
                  Zugegebenermaßen arbeite ich mit WinCVS das aber ohne Probleme. Server ist ein Gentoo-Linux, CLOCK="UTC", /etc/localtime zeigt auf .../Europe/Berlin.
                  Die auf die schnelle installierte Schildkröte ergab auch keine Beanstandungen.

                  Abgesehen davon ist es auch nicht empfohlen, seine lokale CVS-Kopie auf Netzlaufwerken zu platzieren und muß extra freigeschaltet werden.

                  Das liegt soweit ich die FAQ von TortoiseCVS (Can I share my sandbox with Linux... und folgende) richtig interpretiere nur am Zeilenende-Problem. Das umgehe ich bewusst indem ich auch unter Windows mit UNIX-Endungen arbeite (entsprechende Ein-/Auscheck-Optionen sind gesetzt.)

            2. Hi Sven!

              Die Commits werden direkt danach automatisch auf einen öffentlichen Testserver aktualisiert - dann kann der Kunde ggf. auch angucken, wie der Stand ist.
              Machst Du das per "post-commit hook"?

              In meiner Datei loginfo (aus CVSROOT) steht die Zeile
              ^modulname      (date; cat; (sleep 2; cd /var/www/vhosts; cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1

              Das heißt aber, dass Deine öffentliche Testumgebung auch eine CVS Arbeitskopie ist, ja? Ich überlege ja, ob ich das so auch für meine eigene Testumgebung machen soll. Das dumme wenn ich immer den Weg über SVN gehe, das heißt für jeden kleinen Typo, dann sinkt I;HO auch die Qualität des Archivs, denn wenn ich eine größere Änderung mache, eine ausführliche Message dazu schreibe - und dann funktioniert es gar nicht so wie ich gehofft hatte, sondern erst 12 "triviale" commits später, dann ist das hinterher ziemlich blöd wenn man da was nachvollziehen will, oder eine Änderung rückgängig machen will. Da wo die Message der Änderung im Log steht, funktioniert das was geändert wurde dann möglicherweise noch gar nicht, eben erst die 12 Revisionen später. Nein, so kann ich das nicht machen, das ist Mist.

              Alternativen hierzu wären also:

              1. Zugriff auf die Dateien auf dem Testserver über SMB/FTP
              2. Verwendung einer lokalen Testumgebung

              Vorteil der beiden Varianten ist dass man lokal wie auf dem Testserver mit denselben Dateien arbeitet. Hm. Aber für Variante 1 habe ich lokal keine Dateien und bei 2. muss ich diese test-Umgebung auf jedem Rechner einrichten, auf dem entwickelt wird. Hm.

              Man muß also den Testserver einmalig manuell auschecken (bzw. kann Branches zwischendurch ebenfalls aktualisieren), und künftig wird das immer automatisch auf dem neuesten Stand gehalten (in diesem Branch).

              Mit "Testserver" meinst Du jetzt nicht den Server mit dem Du lokal testest, sondern die öffentliche Variante für den Kunden, ja?

              Ich überlege gerade, ob ich vielleicht sowohl auf dem Testserver (der Server auf den ich [und *nur* ich] Scripte vom lokalen Rechner hochlade) als auch auf dem lokalen Entwicklungs-PC eine Arbeitskopie auschecken und pflegen soll. Das heißt, wenn ich anfange zu arbeiten mache ich sowohl lokal als auch remote ein svn update, arbeite dann lokal an einem Script, lade das manuell per SCP auf den Testserver, teste es im Browser, mache evtl. noch ein paar kleiner Korrekturen und wenn alles so läuft wie ich es möchte committe ich das. Die Frage ist nur - von wo aus? Ist es besser lokal, oder remote eine 100%ige Konsistenz zu haben? Ich denke eher lokal, denn da muss ich so oder so updaten wenn ich auf einem anderen Rechner arbeite. Allerdings kann es bei einem Fehler passieren (z.B. eine Datei nicht hochgeladen), dass es so aussieht als würde die Änderung funktionieren, in der nicht hochgeladenen Datei aber ein Fehler schlummert. Aber auch anders herum, wenn ich remote committe habe ich das Problem, dass vielleicht irgendwelche lokalen Änderungen nicht ins System wandern.

              Gut, im Normalfall sollte sowas nicht passieren, aber verlassen kann man sich darauf eben nicht - im Gegensatz zu den von Euch verwendeten Methoden.

              Gut, dann wird es wohl darauf hinauslaufen, dass ich nach einem (lokalen) commit nochmal remote einen export mit --force Switch durchführe, um alles zu überschreiben, und das dann alles nochmal teste. Das kann ja auch automatisiert passieren. Oh Gott - wirklich "schön" ist diese Vorgehensweise wohl nicht... ;-)

              Und Releases installiere ich ebenfalls direkt per CVS-Zugriff auf dem Live-Server.
              Das machst Du dann per "export"?

              Manuell remote auf der Shell. :)

              Ja, meine ich ja, bei SVN wäre das svn export....

              Weißt Du wie man bei SVN oder CVS eine Datei von commits ausnimmt? Z.B. eine angepasste Konfigurationsdatei (die im Repository mit default-Werten existiert)...

              Grüße
              Andreas

              --
              SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/
  2. Hallo!

    Noch eine Frage zum Thema svnserve:

    Sowohl das SVN-Buch als auch das subversion-ebuild sagt mir, dass ich bei svn+ssh:// einen Wrapper für svnserver verwenden soll, der eine entsprechende umask setzt, z.B.:

    #!/bin/bash
    umask 002
    exec /usr/bin/svnserve "$@"

    Aber ich habe echt keien Idee wie ich das im System "installieren" sollen, nach Möglichkeit so dass das Wrapper-Script nach einem emerge -u subversion noch genau so funktioniert vorher.

    das ebuild installiert svnserver in /usr/bin. Jetzt sagt das Gentoo-Ebuild:

    "create an svnserve wrapper in /usr/local/bin"

    Gut, aber was habe ich davon? In PATH steht /usr/bin vor /usr/local/bin - also würde das Script doch nie ausgeführt. Aber PATH ändern wegen sowas?

    Wie könnte man das geschickt machen?

    Grüße
    Andreas

  3. Hallo!

    Um eine produktive Umgebung zu aktualisieren gibt es ja 2 Möglichkeiten. Entweder man verwendet hier auch Arbeits-Kopien die man dann mit svn update auf einen neuen Release-Stand aktualisieren kann, oder man verwendet svn export --force, wodurch alle Dateien überschrieben werden. Ersteres hat den Vorteil, dass bei Updates nur geänderte Dateien aktualisiert werden müssen, letztes hat den Vorteil dass man eben keine Arbeitskopie mit den .svn Verzeichnissen hat. Wie macht Ihr das, was würdet Ihr empfehlen? Oder vielleicht ohne svn über ein patch?

    Viele Grüße
    Andreas