Git-Tipps#

Rebasen auf main#

Dies aktualisiert Ihren Feature-Branch mit Änderungen aus dem Upstream-Repository von SciPy auf GitHub. Wenn Sie dies nicht unbedingt tun müssen, versuchen Sie es zu vermeiden, außer vielleicht, wenn Sie fertig sind. Der erste Schritt besteht darin, das Remote-Repository mit neuen Commits von Upstream zu aktualisieren

git fetch upstream

Als Nächstes müssen Sie den Feature-Branch aktualisieren

# go to the feature branch
git checkout my-new-feature
# make a backup in case you mess up
git branch tmp my-new-feature
# rebase on upstream main branch
git rebase upstream/main

Wenn Sie Änderungen an Dateien vorgenommen haben, die sich auch Upstream geändert haben, kann dies zu Merge-Konflikten führen, die Sie lösen müssen. Hilfe hierzu finden Sie weiter unten.

Entfernen Sie schließlich den Backup-Branch nach einem erfolgreichen Rebase

git branch -D tmp

Hinweis

Rebasen auf main wird dem Mergen von Upstream in Ihren Branch vorgezogen. Die Verwendung von git merge und git pull wird bei der Arbeit an Feature-Branches nicht empfohlen.

Wiederherstellung nach Fehlern#

Manchmal macht man Fehler bei Merges oder Rebases. Glücklicherweise ist es in Git relativ einfach, sich von solchen Fehlern zu erholen.

Wenn Sie sich bei einem Rebase vertan haben

git rebase --abort

Wenn Sie feststellen, dass Sie sich nach dem Rebase vertan haben

# reset branch back to the saved point
git reset --hard tmp

Wenn Sie vergessen haben, einen Backup-Branch zu erstellen

# look at the reflog of the branch
git reflog show my-feature-branch

8630830 my-feature-branch@{0}: commit: BUG: io: close file handles immediately
278dd2a my-feature-branch@{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a my-feature-branch@{2}: commit: BUG: lib: make seek_gzip_factory not leak gzip obj
...

# reset the branch to where it was before the botched rebase
git reset --hard my-feature-branch@{2}

Wenn Sie sich nicht wirklich vertan haben, aber Merge-Konflikte bestehen, müssen Sie diese lösen. Dies kann eine der kniffligeren Aufgaben sein. Eine gute Beschreibung, wie dies geht, finden Sie in diesem Artikel zu Merge-Konflikten.

Umschreiben der Commit-Historie#

Hinweis

Tun Sie dies nur für Ihre eigenen Feature-Branches.

Gibt es einen peinlichen Tippfehler in einem Commit, den Sie gemacht haben? Oder vielleicht gab es mehrere Fehlstarts, die die Nachwelt nicht sehen soll.

Dies kann über *interaktives Rebasen* erfolgen.

Angenommen, die Commit-Historie sieht so aus

git log --oneline
eadc391 Fix some remaining bugs
a815645 Modify it so that it works
2dec1ac Fix a few bugs + disable
13d7934 First implementation
6ad92e5 * masked is now an instance of a new object, MaskedConstant
29001ed Add pre-nep for a copule of structured_array_extensions.
...

und 6ad92e5 ist der letzte Commit im main-Branch. Nehmen wir an, wir möchten folgende Änderungen vornehmen

  • Schreiben Sie die Commit-Nachricht für 13d7934 in etwas Sinnvolleres um.

  • Kombinieren Sie die Commits 2dec1ac, a815645, eadc391 zu einem einzigen.

Wir gehen wie folgt vor

# make a backup of the current state
git branch tmp HEAD
# interactive rebase
git rebase -i 6ad92e5

Dies öffnet einen Editor mit folgendem Text darin

pick 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
pick a815645 Modify it so that it works
pick eadc391 Fix some remaining bugs

# Rebase 6ad92e5..eadc391 onto 6ad92e5
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Um das Gewünschte zu erreichen, nehmen wir folgende Änderungen daran vor

r 13d7934 First implementation
pick 2dec1ac Fix a few bugs + disable
f a815645 Modify it so that it works
f eadc391 Fix some remaining bugs

Das bedeutet, dass (i) wir die Commit-Nachricht für 13d7934 bearbeiten wollen und (ii) die letzten drei Commits zu einem zusammenfassen. Jetzt speichern und beenden wir den Editor.

Git öffnet dann sofort einen Editor, um die Commit-Nachricht zu bearbeiten. Nach der Überarbeitung erhalten wir die Ausgabe

[detached HEAD 721fc64] FOO: First implementation
 2 files changed, 199 insertions(+), 66 deletions(-)
[detached HEAD 0f22701] Fix a few bugs + disable
 1 files changed, 79 insertions(+), 61 deletions(-)
Successfully rebased and updated refs/heads/my-feature-branch.

und die Historie sieht jetzt so aus

0f22701 Fix a few bugs + disable
721fc64 ENH: Sophisticated feature
6ad92e5 * masked is now an instance of a new object, MaskedConstant

Wenn etwas schiefgegangen ist, ist die Wiederherstellung wieder möglich, wie oben erklärt.

Löschen eines Branches auf GitHub#

git checkout main
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on GitHub
git push origin :my-unwanted-branch

(Beachten Sie den Doppelpunkt : vor test-branch. Siehe auch: guides/remove-a-remote-branch

Mehrere Personen teilen sich ein einzelnes Repository#

Wenn Sie mit anderen Leuten an etwas arbeiten möchten, wobei Sie alle in dasselbe Repository oder sogar denselben Branch committen, dann teilen Sie es einfach über GitHub.

Forken Sie zunächst SciPy in Ihr Konto, wie in Eigene Kopie (Fork) von SciPy erstellen beschrieben.

Gehen Sie dann zur GitHub-Seite Ihres geforkten Repositories, z. B. https://github.com/your-user-name/scipy

Klicken Sie auf die Schaltfläche 'Admin' und fügen Sie andere Personen als Mitwirkende zum Repository hinzu

../../_images/pull_button.png

Nun können all diese Personen

git clone git@github.com:your-user-name/scipy.git

Denken Sie daran, dass Links, die mit git@ beginnen, das SSH-Protokoll verwenden und Lese-/Schreibzugriff haben; Links, die mit git:// beginnen, sind schreibgeschützt.

Ihre Mitwirkenden können dann direkt in dieses Repository mit dem üblichen

git commit -am 'ENH - much better code'
git push origin my-feature-branch # pushes directly into your repo

Erkunden Ihres Repositories#

Um eine grafische Darstellung der Repository-Branches und Commits zu sehen

gitk --all

Um eine lineare Liste der Commits für diesen Branch anzuzeigen

git log

Sie können auch den Netzwerkgraphen-Visualisierer für Ihr GitHub-Repository nutzen.

Backporting#

Backporting ist der Prozess des Kopierens neuer Features/Korrekturen, die in scipy/main committet wurden, zurück in stabile Release-Branches. Dazu erstellen Sie einen Branch vom Branch, in den Sie backporten, picken die gewünschten Commits von scipy/main aus und reichen dann eine Pull-Anfrage für den Branch ein, der den Backport enthält.

  1. Zuerst müssen Sie den Branch erstellen, an dem Sie arbeiten werden. Dieser muss auf der älteren Version von SciPy basieren (nicht main)

    # Make a new branch based on scipy/maintenance/1.8.x,
    # backport-3324 is our new name for the branch.
    git checkout -b backport-3324 upstream/maintenance/1.8.x
    
  2. Nun müssen Sie die Änderungen von main auf diesen Branch anwenden, indem Sie git cherry-pick verwenden

    # Update remote
    git fetch upstream
    # Check the commit log for commits to cherry pick
    git log upstream/main
    # This pull request included commits aa7a047 to c098283 (inclusive)
    # so you use the .. syntax (for a range of commits), the ^ makes the
    # range inclusive.
    git cherry-pick aa7a047^..c098283
    ...
    # Fix any conflicts, then if needed:
    git cherry-pick --continue
    
  3. Es kann sein, dass Sie beim Cherry-Picking auf einige Konflikte stoßen. Diese werden auf dieselbe Weise gelöst wie Merge/Rebase-Konflikte. Hier können Sie jedoch git blame verwenden, um den Unterschied zwischen main und dem gebackporteten Branch zu sehen und sicherzustellen, dass nichts schief geht.

  4. Pushen Sie den neuen Branch in Ihr Github-Repository

    git push -u origin backport-3324
    
  5. Erstellen Sie schließlich eine Pull-Anfrage über GitHub. Stellen Sie sicher, dass diese gegen den Wartungsbranch und nicht gegen main gerichtet ist, GitHub wird Ihnen normalerweise vorschlagen, die Pull-Anfrage gegen main zu erstellen.

Pushen von Änderungen in das Haupt-Repository#

Dies ist nur relevant, wenn Sie Commit-Rechte für das Haupt-SciPy-Repository haben.

Wenn Sie eine Reihe von "fertigen" Änderungen in einem Feature-Branch haben, die für die main- oder maintenance-Branches von SciPy bereit sind, können Sie diese wie folgt nach upstream pushen

  1. Führen Sie zuerst einen Merge oder Rebase auf dem Ziel-Branch durch.

    1. Nur wenige, nicht zusammenhängende Commits, dann lieber Rebase

      git fetch upstream
      git rebase upstream/main
      

      Siehe Rebasen auf main.

    2. Wenn alle Commits zusammenhängen, erstellen Sie einen Merge-Commit

      git fetch upstream
      git merge --no-ff upstream/main
      
  2. Überprüfen Sie, ob das, was Sie pushen werden, sinnvoll ist

    git log -p upstream/main..
    git log --oneline --graph
    
  3. Pushen Sie zu Upstream

    git push upstream my-feature-branch:main
    

Hinweis

Es ist normalerweise eine gute Idee, die Option -n für git push zu verwenden, um zuerst zu überprüfen, ob Sie die gewünschten Änderungen an den gewünschten Ort pushen.