Entwicklungsworkflow #

Sie haben bereits Ihre eigene gegabelte Kopie des Matplotlib- Repositorys, indem Sie den folgenden Schritten folgen: Eigene Kopie (Fork) von Matplotlib erstellen . Sie haben Ihre Gabel eingerichtet . Sie haben Git konfiguriert, indem Sie Configure git befolgt haben . Jetzt sind Sie bereit für echte Arbeit.

Workflow-Zusammenfassung #

Im Folgenden bezeichnen wir den Upstream-Matplotlib main-Zweig als "Stamm".

  • Verwenden Sie Ihren mainZweig für nichts. Überlege es zu löschen.

  • Wenn Sie mit einem neuen Satz von Änderungen beginnen, holen Sie sich alle Änderungen vom Stamm und starten Sie von dort aus einen neuen Feature-Zweig .

  • Erstellen Sie für jeden trennbaren Satz von Änderungen einen neuen Zweig – „eine Aufgabe, ein Zweig“ ( ipython git workflow ).

  • Benennen Sie Ihren Zweig zum Zweck der Änderungen - zB bugfix-for-issue-14oder refactor-database-code.

  • Wenn Sie es vermeiden können, vermeiden Sie es, während der Arbeit trunk oder andere Branches in Ihren Feature-Branch zu mergen.

  • Wenn Sie feststellen, dass Sie vom Stamm zusammenführen, ziehen Sie eine Neubasierung auf den Stamm in Betracht

  • Fragen Sie auf der Matplotlib-Mailingliste, wenn Sie nicht weiterkommen.

  • Fordern Sie Code-Review an!

Diese Arbeitsweise hilft, die Arbeit gut organisiert zu halten, mit lesbarem Verlauf. Dies wiederum macht es für Projektbetreuer (das könnten Sie sein) einfacher zu sehen, was Sie getan haben und warum Sie es getan haben.

Siehe Linux-Git-Workflow und Ipython-Git-Workflow für einige Erklärungen.

Ziehen Sie in Betracht, Ihren Hauptzweig # zu löschen

Es mag seltsam klingen, aber das Löschen Ihres eigenen mainZweigs kann dazu beitragen, die Verwirrung darüber zu verringern, in welchem ​​​​Zweig Sie sich befinden. Siehe Haupt löschen auf GitHub für Details.

Aktualisieren Sie den Spiegel von Trunk #

Stellen Sie zunächst sicher, dass Sie Ihr Repository mit dem Upstream-Repository verknüpft haben .

Von Zeit zu Zeit sollten Sie die Upstream (Trunk)-Änderungen von github abrufen:

git fetch upstream

Dadurch werden alle Commits heruntergezogen, die Sie nicht haben, und die Remote-Zweige so eingestellt, dass sie auf den richtigen Commit zeigen. Zum Beispiel ist „trunk“ der Branch, auf den von (remote/branchname) verwiesen wird upstream/main– und wenn es seit Ihrer letzten Überprüfung Commits gegeben hat, upstream/mainändert sich dies, nachdem Sie den Abruf durchgeführt haben.

Erstellen Sie einen neuen Feature-Branch #

Wenn Sie bereit sind, einige Änderungen am Code vorzunehmen, sollten Sie einen neuen Zweig beginnen. Verzweigungen, die für eine Sammlung verwandter Bearbeitungen vorgesehen sind, werden oft als „Funktionsverzweigungen“ bezeichnet.

Das Erstellen eines neuen Zweigs für jeden Satz verwandter Änderungen erleichtert es jemandem, der Ihren Zweig überprüft, um zu sehen, was Sie tun.

Wählen Sie einen aussagekräftigen Namen für die Branche, um sich selbst und den Rest von uns daran zu erinnern, wofür die Änderungen in der Branche gedacht sind. Zum Beispiel add-ability-to-fly, oder bugfix-for-issue-42.

# Update the mirror of trunk
git fetch upstream
# Make new feature branch starting at current trunk
git branch my-new-feature upstream/main
git checkout my-new-feature

Im Allgemeinen möchten Sie Ihre Feature-Zweige auf Ihrem öffentlichen Github- Fork von Matplotlib behalten . Um dies zu tun, pushen Sie diesen neuen Branch in Ihr Github-Repo. Im Allgemeinen (wenn Sie die Anweisungen auf diesen Seiten befolgt haben, und standardmäßig) hat git einen Link zu Ihrem Github-Repo namens origin. Sie pushen zu Ihrem eigenen Repo auf GitHub mit:

git push origin my-new-feature

In git >= 1.7 können Sie sicherstellen, dass der Link korrekt gesetzt wird, indem Sie die --set-upstreamOption verwenden:

git push --set-upstream origin my-new-feature

Von nun an weiß Git, dass my-new-featurees sich um einen my-new-featureZweig im Github-Repo handelt.

Der Bearbeitungsablauf #

Übersicht #

# hack hack
git add my_new_file
git commit -am 'NF - some message'
git push

Ausführlicher #

  1. Nehmen Sie einige Änderungen vor

  2. Sehen Sie, welche Dateien sich mit geändert haben (siehe git status ). Sie sehen eine Auflistung wie diese:git status

    # On branch ny-new-feature
    # Changed but not updated:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #  modified:   README
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #  INSTALL
    no changes added to commit (use "git add" and/or "git commit -a")
    
  3. Überprüfen Sie mit ( git diff ), was die tatsächlichen Änderungen sind .git diff

  4. Fügen Sie alle neuen Dateien zur Versionskontrolle hinzu (siehe git add ).git add new_file_name

  5. Um alle geänderten Dateien in die lokale Kopie Ihres Repos zu übertragen, tun Sie . Beachten Sie die Optionen bis . Das Flag signalisiert nur, dass Sie eine Nachricht in die Befehlszeile eingeben werden. Die Flagge – Sie können einfach glauben – oder sehen Sie, warum die -a-Flagge? — und die hilfreiche Use-Case-Beschreibung im wirren Arbeitskopie-Problem . Die Handbuchseite zum Git-Commit könnte ebenfalls nützlich sein.git commit -am 'A commit message'-amcommitma

  6. Um die Änderungen in Ihr Fork-Repo auf Github hochzuschieben, führen Sie eine (siehe git push ) durch.git push

Bitten Sie darum, dass Ihre Änderungen überprüft oder zusammengeführt werden #

Wenn Sie bereit sind, jemanden zu bitten, Ihren Code zu überprüfen und eine Zusammenführung in Betracht zu ziehen:

  1. Gehen Sie zur URL Ihres gegabelten Repos, sagen wir https://github.com/your-user-name/matplotlib.

  2. Verwenden Sie das Dropdown-Menü „Zweige wechseln“ oben links auf der Seite, um den Zweig mit Ihren Änderungen auszuwählen:

    ../../_images/branch_dropdown.png
  3. Klicken Sie auf die Schaltfläche „Pull-Request“:

    ../../_images/pull_button.png

    Geben Sie einen Titel für die Änderungen ein und erklären Sie, was Sie getan haben. Sagen Sie, ob es etwas gibt, für das Sie besondere Aufmerksamkeit wünschen – wie eine komplizierte Änderung oder einen Code, mit dem Sie nicht zufrieden sind.

    Wenn Sie der Meinung sind, dass Ihre Anfrage nicht zum Zusammenführen bereit ist, teilen Sie dies einfach in Ihrer Pull-Request-Nachricht mit. Dies ist immer noch eine gute Möglichkeit, eine vorläufige Überprüfung des Codes zu erhalten.

Einige andere Dinge, die Sie vielleicht tun möchten #

Einen Branch auf Github löschen #

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 :davor my-unwanted-branch. Siehe auch: https://help.github.com/articles/pushing-to-a-remote/#deleting-a-remote-branch-or-tag

Mehrere Personen teilen sich ein einzelnes Repository #

Wenn Sie mit anderen Leuten an einigen Dingen arbeiten möchten, bei denen Sie alle in dasselbe Repository oder sogar denselben Branch einsteigen, dann teilen Sie es einfach über GitHub.

Verzweigen Sie zuerst Matplotlib in Ihr Konto, wie unter Making your own copy (fork) of Matplotlib .

Gehen Sie dann zu Ihrer gegabelten Repository-Github-Seite, sagen wir https://github.com/your-user-name/matplotlib

Klicken Sie auf die Schaltfläche „Admin“ und fügen Sie eine andere Person als Mitarbeiter zum Repo hinzu:

../../_images/pull_button.png

Jetzt können all diese Leute Folgendes tun:

git clone https://github.com/your-user-name/matplotlib.git

Denken Sie daran, dass Links, die mit httpsoder beginnen git@, schreibgeschützt sind und git@das ssh-Protokoll verwenden.

Ihre Mitarbeiter können sich dann wie gewohnt direkt in dieses Repo einschreiben:

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

Erkunden Sie Ihr Repository #

So sehen Sie eine grafische Darstellung der Repository-Zweige und Commits:

gitk --all

So sehen Sie eine lineare Liste von Commits für diesen Zweig:

git log

Sie können sich auch den Netzwerkdiagramm-Visualizer für Ihr Github-Repo ansehen.

Schließlich gibt Ihnen der Ausgabealias Fancy log lg ein vernünftiges textbasiertes Diagramm des Repositorys.

Rebasing auf Amtsleitung #

Angenommen, Sie haben an eine Arbeit gedacht, die Sie gerne erledigen würden. Sie aktualisieren den Spiegel des Trunks und erstellen einen neuen Feature-Zweig mit dem Namen cool-feature. In diesem Stadium befindet sich Trunk an einem Commit, nennen wir es E. Jetzt nehmen Sie einige neue Commits auf Ihrem cool-featureZweig vor, nennen wir sie A, B, C. Vielleicht dauern Ihre Änderungen eine Weile, oder Sie kommen nach einer Weile darauf zurück. In der Zwischenzeit ist trunk von Commit E zu Commit (sagen wir) G übergegangen:

      A---B---C cool-feature
     /
D---E---F---G trunk

In diesem Stadium erwägen Sie, trunk in Ihren Feature-Zweig zu mischen, und Sie erinnern sich, dass diese Seite Ihnen streng davon abrät, dies zu tun, da die Historie unordentlich wird. Meistens können Sie einfach um eine Bewertung bitten und sich keine Sorgen machen, dass Trunk ein wenig voraus ist. Aber manchmal können sich die Änderungen im Stamm auf Ihre Änderungen auswirken, und Sie müssen sie harmonisieren. In dieser Situation ziehen Sie es vielleicht vor, eine Rebase durchzuführen.

rebase übernimmt Ihre Änderungen (A, B, C) und spielt sie so ab, als ob sie am aktuellen Stand von vorgenommen worden wären trunk. Mit anderen Worten, in diesem Fall nimmt es die durch A, B, C repräsentierten Änderungen und spielt sie auf G ab. Nach dem Rebase sieht Ihr Verlauf so aus:

              A'--B'--C' cool-feature
             /
D---E---F---G trunk

Siehe Rebase ohne Tränen für weitere Details.

So führen Sie eine Rebase auf Trunk durch:

# Update the mirror of trunk
git fetch upstream
# go to the feature branch
git checkout cool-feature
# make a backup in case you mess up
git branch tmp cool-feature
# rebase cool-feature onto trunk
git rebase --onto upstream/main upstream/main cool-feature

In dieser Situation, in der Sie sich bereits auf branch befinden cool-feature, kann der letzte Befehl prägnanter geschrieben werden als:

git rebase upstream/main

Wenn alles gut aussieht, können Sie Ihren Backup-Zweig löschen:

git branch -D tmp

Wenn es nicht gut aussieht, müssen Sie sich möglicherweise Wiederherstellung nach Fehlern ansehen .

Wenn Sie Änderungen an Dateien vorgenommen haben, die sich auch im Trunk geändert haben, kann dies zu Merge-Konflikten führen, die Sie lösen müssen – siehe die git rebase- Manpage für einige Anweisungen am Ende des Abschnitts „Beschreibung“. Es gibt einige verwandte Hilfestellungen zum Zusammenführen im Git-Benutzerhandbuch - siehe Auflösung einer Zusammenführung .

Sich von Misserfolgen erholen #

Manchmal vermasseln Sie Merges oder Rebases. Glücklicherweise ist es in Git relativ einfach, sich von solchen Fehlern zu erholen.

Wenn Sie während einer Rebase Fehler machen:

git rebase --abort

Wenn Sie bemerken, dass Sie nach dem Rebase Mist gebaut 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 cool-feature

8630830 [email protected]{0}: commit: BUG: io: close file handles immediately
278dd2a [email protected]{1}: rebase finished: refs/heads/my-feature-branch onto 11ee694744f2552d
26aa21a [email protected]{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 [email protected]{2}

Commit-Verlauf umschreiben #

Notiz

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

Es gibt einen peinlichen Tippfehler in einem Commit, das du gemacht hast? Oder vielleicht haben Sie mehrere Fehlstarts gemacht, von denen Sie möchten, dass die Nachwelt es nicht sieht.

Dies kann über interaktives Rebasing erfolgen .

Angenommen, der Commit-Verlauf sieht folgendermaßen 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 6ad92e5ist das letzte Commit in der cool-featureVerzweigung. Angenommen, wir möchten die folgenden Änderungen vornehmen:

  • Schreiben Sie die Commit-Nachricht für 13d7934etwas Sinnvolleres um.

  • Kombinieren Sie die Commits 2dec1ac, a815645, eadc391zu 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 dem folgenden 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 zu erreichen, was wir wollen, werden wir die folgenden Änderungen daran vornehmen:

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 wir (i) die Commit-Nachricht für bearbeiten 13d7934und (ii) die letzten drei Commits zu einem zusammenfassen wollen. Jetzt speichern und beenden wir den Editor.

Git ruft dann sofort einen Editor zum Bearbeiten der Commit-Nachricht auf. 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 es schief gelaufen ist, ist eine Wiederherstellung wie oben beschrieben wieder möglich .