Verständnisfrage zu git



  • Wenn du aus irgendeinem Grund gerade nicht committen möchtest, kannst du deine Änderungen auch kurz mit "git stash" weglegen und dann mit "git stash pop" wieder herstellen. Wobei ich das nur für Kleinmist benutze, alles andere wird committet; notfalls kann man Commits ja immer noch aufräumen, bevor man sie pusht.



  • Ach ja, die GitHub-Leute verlinken das eh auch, aber eine tolle Ressource zu Git ist das hier:
    http://progit.org/book/



  • Was abseits der einzelnen Kommandos aus meiner Sicht für das Verständnis von git & Co. gut verständlich geschrieben ist: http://www.ericsink.com/vcbe/



  • franc schrieb:

    Oh, tut mir leid!

    Ach, muss Dir nicht leid tun. Hauptsache, Du bist weitergekommen!



  • Jetzt habe ich doch noch eine Frage:

    Ich habe ein bestehendes GitHub Projekt geforkt (gegabelt) und daran herumgebastelt.
    Mit:

    git remote add upstream git://github.com/originalrep.git
    

    habe ich die Originalquelle zu meinem lokalen Repository hinzugefügt, wie man unter:

    http://help.github.com/fork-a-repo/

    nachlesen kann.
    Ich kann nun mit:

    git fetch upstream
    

    das Originalrepository holen:

    c:\apache\Apache2\htdocs\kimai-git>git fetch upstream
    remote: Counting objects: 271, done.
    remote: Compressing objects: 100% (64/64), done.
    remote: Total 222 (delta 168), reused 210 (delta 156)
    Receiving objects: 100% (222/222), 218.02 KiB | 239 KiB/s, done.
    Resolving deltas: 100% (168/168), completed with 31 local objects.
    From git://github.com/kimai/kimai
     * [new branch]      master     -> upstream/master
    

    Aber wie schalte ich die zwei Repositorys (mein geforktest und das Upstream-Original) nun um?

    Das eigene geforkte Repository ist nämlich nach wie vor aktiv.
    Es ist mir noch recht unklar das gitten.

    Ich habe dann auch noch:

    >git checkout -b upstream
    Switched to a new branch 'upstream'
    

    ausgeführt, aber ich befinde mich noch in meinem eigenen git, also mit dessen Änderungen am (upstream)Original. Meine Änderungen am Original sind immer noch zu sehen.

    Ein git commit -a ergibt:

    c:\apache\Apache2\htdocs\kimai-git>git commit -a
    # On branch upstream
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       core/extensions/ki_adminpanel/compile/wrt4B2.tmp
    #       core/extensions/ki_invoice/templates/00_Rechnung.odt
    #       core/kimai-mobile/
    #       core/skins/standard/grfx/lupe.jpg
    #       core/skins/standard/grfx/lupe.psd
    #       core/temporary/logfile.txt
    #       docu/Programmieranleitungen.txt
    #       update.bat
    nothing added to commit but untracked files present (use "git add" to track)
    

    Was mach ich falsch?



  • was genau willst du denn machen? du kannst die änderungen aus dem original repository mittels pull holen. als nach git remote add upstream ... machst du git fetch upstream und dann git pull upstream. die änderungen an deinem code kannst du aber nur pushen, wenn du auch berechtigungen dazu hast. da du ja auf einem fork arbeitest, hast du ja offenbar keine rechte für das original repository. du kannst also nur in deinen fork pushen. über die github oberfläche könntest du dann an die leute des original repositories einen pull request schicken, um sie aufzufordern, die änderungen aus deinem fork in das original repository zu übernehmen.



  • Ich will bequem umschalten zwischen dem Original Repository, woran ich gar nichts ändern will und meinem Repository, wohin ich auch Änderungen einpflege.

    c:\apache\Apache2\htdocs\kimai-git>git pull upstream
    You asked to pull from the remote 'upstream', but did not specify
    a branch. Because this is not the default configured remote
    for your current branch, you must specify a branch on the command line.
    

    Welchen "branch" nehme ich denn da nun?

    EDIT:

    c:\apache\Apache2\htdocs\kimai-git>git branch --set-upstream origin origin/master
    Branch origin set up to track remote branch master from origin.
    

    und dann:

    c:\apache\Apache2\htdocs\kimai-git>git pull upstream
    You asked to pull from the remote 'upstream', but did not specify
    a branch. Because this is not the default configured remote
    for your current branch, you must specify a branch on the command line.
    

    bingt immer noch nichts.
    Geht das prinzipiell vielleicht gar nicht, so einfach zwischen dem Original und meinem Fork umzuschalten?



  • franc schrieb:

    Ich will bequem umschalten zwischen dem Original Repository, woran ich gar nichts ändern will und meinem Repository, wohin ich auch Änderungen einpflege.

    Mach mal git branch -a, um zu sehen welche branches du überhaupt hast. Dein Branch "upstream" hat nichts mit dem Remote-Repository zu tun, so wie du ihn angelegt hast. Den würde ich daher erstmal löschen (git branch -d upstream).

    Du könntest dann entweder den branch "master/upstream" direkt auschecken mit "git checkout master/upstream", oder einen tracking branch dafür machen mit "git branch upstream master/upstream". Wichtig ist hier das "master/upstream" am Ende des Aufrufs.

    Hin und herschalten geht in jedem Fall mit git checkout <branch>. Im ersten Fall ist <branch> dann master/upstream, im zweiten einfach nur upstream.

    Wenn du direkt master/upstream auscheckst, landest du aber im "detached HEAD state", was erstmal nur bedeutet, dass du in diesen Branch nicht committen kannst. Einen separaten Branch "upstream" anlegen hat den Nachteil, dass du manuell git pull aufrufen musst, um ihn zu aktualisieren.

    Aber eigentlich sollte das nicht nötig sein. Die Anleitung, die du verlinkt hast, erklärt auch, wie man upstream-Änderungen in den eigenen master-Branch merged:
    $ git fetch upstream
    $ git merge upstream/master

    So würde ich das einfach machen, da musst du den upstream/master-Branch gar nicht erst manuell auschecken.



  • franc schrieb:

    c:\apache\Apache2\htdocs\kimai-git>git branch --set-upstream origin origin/master
    Branch origin set up to track remote branch master from origin.
    

    Ich würde eventuell noch mal ein frisches git clone machen. Diese Zeile mit --set-upstream (und ich weiß ja nicht, was du noch alles gemacht hast), kann ziemlich viel kaputt machen. Natürlich kann man das alles schnell reparieren, wenn man weiß wie, aber ein git clone dürfte viel einfacher sein.

    Mit --set-upstream musst du normalerweise nie arbeiten, "git branch <branch> <start-point>" macht das automatisch.



  • Christoph schrieb:

    Mach mal git branch -a, um zu sehen welche branches du überhaupt hast. ...

    c:\apache\Apache2\htdocs\kimai-git>git branch -a
      fcw
      master
      origin
    * upstream
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
      remotes/upstream/master
    

    Mir scheint das ist schon völlig verkorkt 😞



  • So also den branch upstream, der ja nur für Verwirrung sorgt, habe ich wieder gelöscht, so schaut das jetzt aus:

    c:\apache\Apache2\htdocs\kimai-git>git checkout fcw
    Switched to branch 'fcw'
    
    c:\apache\Apache2\htdocs\kimai-git>git branch -d upstream
    Deleted branch upstream (was 119cc7f).
    
    c:\apache\Apache2\htdocs\kimai-git>git checkout master
    Switched to branch 'master'
    Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
    
    c:\apache\Apache2\htdocs\kimai-git>git checkout origin/master
    Note: checking out 'origin/master'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by performing another checkout.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -b with the checkout command again. Example:
    
      git checkout -b new_branch_name
    
    HEAD is now at d53d059... Ignore some new files
    
    c:\apache\Apache2\htdocs\kimai-git>git branch -a
    * (no branch)
      fcw
      master
      origin
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
      remotes/upstream/master
    

    So langsam funktioniert das auch mit dem git checkout ... 🙂

    Ich bin mir nicht sicher, ob ich meine Änderungen in meinen Fork korrekt auf github gepusht habe, sonst würde ich nämlich jetzt wirklich alles nochmal löschen und neu pullen.
    Warum steht bei mir denn da untereinander master UND origin? Ist das nicht das gleiche und beides lokal?



  • franc schrieb:

    Christoph schrieb:

    Mach mal git branch -a, um zu sehen welche branches du überhaupt hast. ...

    c:\apache\Apache2\htdocs\kimai-git>git branch -a
      fcw
      master
      origin
    * upstream
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
      remotes/upstream/master
    

    Mir scheint das ist schon völlig verkorkt 😞

    Ja, deswegen mein Tipp ein neues git clone zu machen von deinem (deinem persönlichen) github-Repository (nicht das Original-Repository).

    Wenn du das nicht möchtest, würde ich erstmal master auschecken und dann die beiden Branches "origin" und "upstream" löschen mit git branch -d. Dann master mit --set-upstream wieder reparieren, sodass er origin/master trackt. Dann das machen, was ich in meinem ersten Posting hier beschrieben habe.

    Aber nochmal, was spricht gegen die Anleitung von github?
    $ git fetch upstream
    $ git merge upstream/master

    Dann musst du den Original-Branch gar nicht auschecken, sondern bekommst die Änderungen in deinen Branch gemerged. Du siehst dann auch exakt die Änderungen, die du gemacht hast gegenüber den Änderungen, die upstream passiert sind. Diese Änderungen sind ja normalerweise das interessante, nicht der tatsächliche Zustand des upstream-Repositories. Man möchte ja nicht tausende Zeilen manuell vergleichen, da ist es gut, wenn git einem ein diff automatisch erstellt und man nicht manuell zwischen Original-Branch und eigenem Branch hin- und herwechseln muss, um zu vergleichen.



  • franc schrieb:

    Ich bin mir nicht sicher, ob ich meine Änderungen in meinen Fork korrekt auf github gepusht habe, sonst würde ich nämlich jetzt wirklich alles nochmal löschen und neu pullen.
    Warum steht bei mir denn da untereinander master UND origin? Ist das nicht das gleiche und beides lokal?

    Du hast scheinbar manuell einen Branch namens "origin" angelegt.

    Die Namen "master", "origin", und so weiter haben für git keinerlei besondere Bedeutung. Das sind keine keywords und die werden von git auch nicht speziell behandelt. Das sind einfach nur willkürliche Namen für einen Branch oder ein remote repository. Du kannst also ein remote repository "origin" nennen, du kannst aber genausogut einen Branch "origin" nennen. Das eine hat mit dem anderen nichts zu tun.



  • Ah, danke, langsam wird es sehr viel klarer.
    Ich glaube ich habe aber auch im GitHub Mist gebaut, dort habe ich zwei Mal gepusht, einmal in HEAD, einmal in master, das sieht jetzt so aus:

    http://img1.uploadscreenshot.com/images/orig/3/9008122558-orig.jpg

    und:

    http://img1.uploadscreenshot.com/images/orig/3/9008193320-orig.jpg

    Habe ich jetzt im GitHub zwei branches, einen HEAD einen master?
    Beide Namen auch wieder willkürlich und ohne Sonderbedeutung?

    Die Lösung mit dem

    $ git fetch upstream
    $ git merge upstream/master
    

    werde ich wählen, aber ich muss erst mal einen sauberen Zustand im GitHub erhalten, bevor mich die Verwirrung völlig vernebelt.

    EDIT: ich muss dazusagen, dass ich beim pushen zu GitHub TortoiseGit verwendet hatte und nicht genau wusste was ich tat.
    Kann es sein, dass ich dabei einen branch "HEAD" angelegt habe, also dass dieses "HEAD" gar keine Sonderbedeutung hat (s.o.)?



  • franc schrieb:

    http://img1.uploadscreenshot.com/images/orig/3/9008122558-orig.jpg

    und:

    http://img1.uploadscreenshot.com/images/orig/3/9008193320-orig.jpg

    Nimm doch bitte png für Screenshots, dann wird die Datei kleiner und das Bild nicht so unscharf. 🙂

    franc schrieb:

    Kann es sein, dass ich dabei einen branch "HEAD" angelegt habe, also dass dieses "HEAD" gar keine Sonderbedeutung hat (s.o.)?

    Ja, genau danach sieht es aus. Wenn du sicher bist, dass dieser Branch gelöscht werden kann, kannst du ihn von github löschen mit
    $ git push dein_github_repo :HEAD

    Der Doppelpunkt vor HEAD ist wichtig.

    HEAD hat zwar in git eine Sonderbedeutung, denn es zeigt auf den aktuell ausgecheckten commit. Allerdings hält git den Nutzer nicht davon ab, einen Branch namens "HEAD" anzulegen.



  • Christoph schrieb:

    ...Nimm doch bitte png für Screenshots, dann wird die Datei kleiner und das Bild nicht so unscharf. :)...

    Da habe ich gar keinen Einfluss darauf, das ist dieser Dienst uploadscreenshot.com, der erstellt das aus der Zwischenablage selbst.

    Christoph schrieb:

    ...HEAD hat zwar in git eine Sonderbedeutung, denn es zeigt auf den aktuell ausgecheckten commit. Allerdings hält git den Nutzer nicht davon ab, einen Branch namens "HEAD" anzulegen.

    Ja, das hat geklappt!
    Anscheinend habe ich mit TortoiseGit einen branch namens HEAD erstellt, den ich jetzt erfolgreich gelöscht habe.
    Langsam lichtet sich der Nebel, die Sonne geht auf 🙂

    Ich habe gemacht:

    git push origin :HEAD
    

    Jetzt lösche ich lokal alles und mach einen neuen pull.



  • franc schrieb:

    Christoph schrieb:

    ...Nimm doch bitte png für Screenshots, dann wird die Datei kleiner und das Bild nicht so unscharf. :)...

    Da habe ich gar keinen Einfluss darauf, das ist dieser Dienst uploadscreenshot.com, der erstellt das aus der Zwischenablage selbst.

    Dann würde ich einen Dienst nehmen, jpeg für Screenshot ist wirklich nicht nett gegenüber dem, der es anschauen soll.

    franc schrieb:

    Christoph schrieb:

    ...HEAD hat zwar in git eine Sonderbedeutung, denn es zeigt auf den aktuell ausgecheckten commit. Allerdings hält git den Nutzer nicht davon ab, einen Branch namens "HEAD" anzulegen.

    Ja, das hat geklappt!
    Anscheinend habe ich mit TortoiseGit einen branch namens HEAD erstellt, den ich jetzt erfolgreich gelöscht habe.
    Langsam lichtet sich der Nebel, die Sonne geht auf 🙂

    Sehr schön. Es ist bei git zum Glück ziemlich schwer, wirklich Daten zu verlieren, solange sie irgendwann mal committet wurden.



  • Christoph schrieb:

    ...jpeg für Screenshot ist wirklich nicht nett gegenüber dem, der es anschauen soll...

    Ich kann da gar keine Unschärfe erkennen, die Bilder sind doch einwandfrei scharf!?

    Christoph schrieb:

    ...Sehr schön. Es ist bei git zum Glück ziemlich schwer, wirklich Daten zu verlieren, solange sie irgendwann mal committet wurden.

    Das beruhigt mich 🙂
    Natürlich habe ich aber dennoch vor dem Löschen des lokalen Repositorys gesichert 😉
    Jetzt habe ich auch, deinem Rad folgend, mit dem remote Original gemerged mit:

    git merge upstream/master
    

    Da musste ich ein paar Dateien händisch korrigieren, aber dann ging es und ich habe jetzt in meinem lokalen und remote Repository einen Zustand mit meinen Änderungen und denen vom Original.
    Das war ein wichtiger Tipp, glaube ich.
    Das hätte ich nämlich nicht gemacht und mich immer weiter vom Original entfernt, bis es kaum mehr zu mergen gewesen wäre, fürchte ich.
    Je nach dem natürlich nur, wie eifrig die Original-Entwickler überhaupt ändern 😉

    Es ist für mich noch leicht verwirrend, dass es mehrere Zustände gibt, lokal, remote, remote upstream usw.

    Ich habe auch gesehen, was ich bei TortoiseGit falsch gemacht habe:

    http://www.abload.de/img/head80ko8.png

    Ich hatte hier HEAD ausgewählt und damit wohl einen neuen branch erstellt.
    Komisch dass das so geht.



  • franc schrieb:

    Ich hatte hier HEAD ausgewählt und damit wohl einen neuen branch erstellt.
    Komisch dass das so geht.

    Das funktioniert, weil ein Branch lokal und remote nicht denselben Namen haben muss. Du kannst zum Beispiel
    $ git push origin master:foo
    ausführen. Dann wird der Branch "master" im lokalen Repository auf den Branch "foo" gepusht im Repository namens "origin". Wenn der Branch "foo" im Repository "origin" nicht existiert, wird er angelegt.

    Was tortoisegit gemacht hat, war also vermutlich
    $ git push origin master:HEAD


Anmelden zum Antworten