Git-Frage zum Checkout



  • Hallo

    ich habe ein DokuWiki auf meinem Server laufen. Bisher hab ich das immer über so ein Plugin upgedatet, das war etwas mühsam, weil ich einige Codeänderungen drin habe, die ich danach alle wieder einpflegen musste.
    Jetzt hab ich entdeckt, dass DokuWiki ja auf github ist, damit kann ich dann ja per git updaten.
    Dennoch möchte ich gerne nicht jedes Mal meine eigenen Änderungen wieder von Hand einpflegen.
    Es sind 7 Dateien bisher, die ich anders habe.
    Ins .gitignore kann ich es ja nicht tun, ich kann es ja nicht committen.
    Ich habe dann eine globale gitignore angelegt:
    ~/.gitignore_global
    wo ich meine Dateien rein habe. Dann mit:
    git config --global core.excludesfile ~/.gitignore_global
    diese bekannt gemacht.
    Aber immer noch werden die Dateien als geändert angezeigt.

    Zudem gibt es bei Updates gelegentlich auch Änderungen in diesen von mir geänderten Dateien, die mit meinen Änderungen nichts zu tun haben und die ich auf jeden Fall einpflegen will (Sicherheitsupdates z.B.).
    Ich müsste also bei einem Update auf jeden Fall wenigtens bei ca. 3 dieser Dateien immer schauen (mit diff) was sich außer meiner Hacks geändert hat, also ob überhaupt.

    Mir fällt eigentlich nur ein Weg ein: das git in ein eigenes git forken und dann jedes Mal bei einem DokuWiki Update vermutlich ebenso mühsam mergen.

    Geht das einfacher?
    Ich will bei einem Update nur die paar Dateien, die ich geändert habe, beibehalten, aber dennoch auf Änderungen prüfen, also per diff, damit ich sehe wenn etwas anderes außer meiner Änderungen neu geändert wurde.

    Danke für Tipp

    franc



  • franc schrieb:

    Ins .gitignore kann ich es ja nicht tun, ich kann es ja nicht committen.

    Commits sind in Git local. Du kannst also durchaus comitten, du kannst es nur nicht nach Github pushen.

    franc schrieb:

    Aber immer noch werden die Dateien als geändert angezeigt.

    Sind das Dateien die bereits im Repo sind? Ich bin mir nicht ganz sicher, aber glaube dann ignoriert Git die nicht.

    franc schrieb:

    Mir fällt eigentlich nur ein Weg ein: das git in ein eigenes git forken und dann jedes Mal bei einem DokuWiki Update vermutlich ebenso mühsam mergen.

    Geht das einfacher?
    Ich will bei einem Update nur die paar Dateien, die ich geändert habe, beibehalten, aber dennoch auf Änderungen prüfen, also per diff, damit ich sehe wenn etwas anderes außer meiner Änderungen neu geändert wurde.

    Dein "Checkout" ist bereits sowas wie ein fork, denn es ist ein komplett separates Repository. Und Git stellt dir die Werkzeuge um Repositores unternander zu synchronisieren.

    Ich würde so vorgehen das ich mir von Github den entsprechenden Branch, den ich als Basis nutzen möchte (z.B. master) hole, und dann davon ausgehend einen eigenen Branch (z.B. dev) erstelle. Mein lokaler master Branch würde keine eigene Änderungen enthalten und kann einfach per pull immer wieder auf den neusten Stand des remote master gebracht werden. Der eigene dev Branch enthält dann die Änderungen und wird bei Bedarf auf den lokalen master rebased. Das Rebase ist genau die Aktion die du durchführen möchtest: Änderungen die auf eine Version gemacht wurden auf eine andere Version erneut anwenden (in Form von Patches). Nach dem Rebase basiert der dev Branch dann wieder auf dem aktuellen master und alles ist gut. Konflikte kann es da natürlich trotzdem geben, aber meiner Erfahrung nach deutlich seltener und es ist deutlich angenehmer zu mergen.



  • Danke!
    Stimmt, rebase scheint genau das zu sein, was ich suche.
    Ich will ja nichts weiter entwickeln, sondern nur meine eigene kleine Suppe köcheln. Die Basis soll immer der master (upstream) sein, die lokale Historie ist uninteressant.
    Die Frage ist noch, ob es nur dann Konflikte gibt, wenn sich eine der Dateien, die ich geändert habe, auch im upstream geändert hat, oder immer, weil sie ja immer vom upstream verschieden sein werden. Ersteres wäre ideal, bei zweiterem wäre ich so schlau wie zuvor.

    EDIT: Ich muss mich korrigieren, ich hatte es noch nicht richtig verstanden:
    Die lokale Historie verschwindet ja nicht.
    rebase speichert alle lokalen Änderungen seit dem Klonen des master als Patch und wendet diese erneut auf den aktuellen master an.



  • Meistens wird git das mergen können, wenn aber in einer Funktion, die du angefasst hast was geändert wird, kann es zum Konflikt kommen.



  • Was mir noch nicht klar ist, wann meldet git nach dem Patchen einen Konflikt und wann nicht? Woher weiß git, dass der Patch nichts kaputt macht?



  • Einen Konflikt gibt es dann, wenn in einer Codezeile sowohl im Repository als auch lokal eine Änderung (Löschen, Editieren, Hinzufügen) erfolgt ist.

    Sofern es nur auf einer Seite eine Änderung gibt, kann einfach gemergt werden.

    Bei Code funktioniert das noch ganz gut mittels "resolve conflicts" - ganz schlimm wird es bei den Projektdateien (*.csproj, *.vcproj etc.), weshalb wir bei uns dann darauf verzichten (und lokal dann die Änderung rückgängig machen und dann neu die Dateien vom Repository ziehen).



  • Hm. Wäre ja zu schön gewesen.
    Ich wollte jetzt genau so vorgehen, also meinen eigenen branch mit meinen Änderungen mit dem aktuellen origin/master per rebase in Einklang bringen, aber da sind so viele Konflikte dass ich wieder abgebrochen habe (mit git rebase --abort).
    Zuerst habe ich noch mit --skip versucht zu überspringen, aber das wird ja immer mehr.
    Sonderbar ist aber, dass nicht meine Änderungen beanstandet werden, sondern irgendwelche Dateien, mit denen ich gar nichts zu tun hatte. Hier die erste Ausgabe (vor dem --skip):

    root@me:/var/www/wiki# git rebase origin/master
    Zunächst wird der Branch zurückgespult, um Ihre Änderungen
    darauf neu anzuwenden...
    Wende an: fixed information leakage in ACL plugin FS#1847
    Verwende Informationen aus der Staging-Area, um einen Basisverzeichnis nachzustellen
    A       lib/plugins/acl/ajax.php
    Falle zurück zum Patchen der Basis und des 3-Wege-Merges...
    KONFLIKT (ändern/löschen): lib/plugins/acl/ajax.php gelöscht in HEAD und geändert in fixed information leakage in ACL plugin FS#1847. Stand fixed information leakage in ACL plugin FS#1847 von lib/plugins/acl/ajax.php wurde im Arbeitsbereich gelassen.
    Merge der Änderungen fehlgeschlagen
    Anwendung des Patches fehlgeschlagen bei 0001 fixed information leakage in ACL plugin FS#1847
    Die Kopie des fehlgeschlagenen Patches befindet sich in:
       /var/www/wiki/.git/rebase-apply/patch
    
    Wenn Sie das Problem aufgelöst haben, führen Sie "git rebase --continue" aus.
    Falls Sie diesen Patch auslassen möchten, führen Sie stattdessen "git rebase --skip" aus.
    Um den ursprünglichen Branch wiederherzustellen und den Rebase abzubrechen,
    führen Sie "git rebase --abort" aus.
    

    Da bin ich wohl doch auf die herkömmliche Weise schneller 😞



  • Es ging jetzt doch mit normalem merge viel einfacher als gedacht:

    cd /pfad/ins/wiki
    git checkout origin/master
    git pull http://github.com/splitbrain/dokuwiki.git
    
    # oder auch:
    # git checkout master
    # git pull
    
    git checkout fcw
    git merge origin/master
    # oder: git merge master
    
    # Konflikte lösen
    git add .
    # oder git add bestimmte/datei.en
    git commit
    

    Ich hatte tatsächlich nur einen Konflikt in einer Datei wo die gleiche Stelle geändert worden war. Das war ein Hack, den ich im Github ins issue geschrieben hatte und der dann genau dort wo ich es selbst hingepfuscht hatte, sauber korrigiert worden war. Da hab ich dann einfach die github Variante übernommen, geht.

    Also prinzipiell mache ich es jetzt so:
    Ich habe einen eigenen Branch erstellt, wo meine Änderungen drin sind.
    Will ich ein Update machen, pull ich den origin/master (von github) aktuell, schalte in mein fcw-branch und mache merge zu origin/master.


Log in to reply