Πώς μπορώ να ενημερώσω ένα αποθετήριο με διακλάδωση στο GitHub;

Πρόσφατα διακλάδισα ένα έργο και εφάρμοσα αρκετές διορθώσεις. Στη συνέχεια, δημιούργησα ένα pull request, το οποίο στη συνέχεια έγινε αποδεκτό.

Λίγες μέρες αργότερα έγινε μια άλλη αλλαγή από έναν άλλο συνεργάτη. Έτσι, η διακλάδωση μου δεν περιέχει αυτή την αλλαγή.

Πώς μπορώ να βάλω αυτή την αλλαγή στο fork μου; Πρέπει να διαγράψω και να δημιουργήσω εκ νέου το fork μου όταν έχω περαιτέρω αλλαγές να συνεισφέρω; Ή υπάρχει κάποιο κουμπί ενημέρωσης;

Λύση

Στον τοπικό σας κλώνο του διχαλωμένου αποθετηρίου σας, μπορείτε να προσθέσετε το αρχικό αποθετήριο GitHub ως "απομακρυσμένο" (Τα "απομακρυσμένα" είναι σαν ψευδώνυμα για τις διευθύνσεις URL των αποθετηρίων - το origin είναι ένα, για παράδειγμα.) Στη συνέχεια, μπορείτε να λάβετε όλους τους κλάδους από αυτό το αποθετήριο upstream και να επανατοποθετήσετε την εργασία σας για να συνεχίσετε να εργάζεστε στην έκδοση upstream. Από την άποψη των εντολών αυτό μπορεί να μοιάζει ως εξής:

# Add the remote, call it "upstream":

git remote add upstream https://github.com/whoever/whatever.git

# Fetch all the branches of that remote into remote-tracking branches,
# such as upstream/master:

git fetch upstream

# Make sure that you're on your master branch:

git checkout master

# Rewrite your master branch so that any commits of yours that
# aren't already in upstream/master are replayed on top of that
# other branch:

git rebase upstream/master

Αν δεν θέλετε να ξαναγράψετε το ιστορικό του master branch σας, (για παράδειγμα επειδή άλλοι άνθρωποι μπορεί να το έχουν κλωνοποιήσει) τότε θα πρέπει να αντικαταστήσετε την τελευταία εντολή με git merge upstream/master. Ωστόσο, για να κάνετε περαιτέρω pull requests που να είναι όσο το δυνατόν πιο καθαρά, είναι πιθανώς καλύτερο να κάνετε rebase.


Αν έχετε rebased το branch σας στο upstream/master ίσως χρειαστεί να εξαναγκάσετε το push προκειμένου να το προωθήσετε στο δικό σας forked αποθετήριο στο GitHub. Θα το κάνετε αυτό με: "Η διαδικασία της εκκίνησης του νέου πακέτου είναι η εξής:":

git push -f origin master

Χρειάζεται να χρησιμοποιήσετε το -f μόνο την πρώτη φορά αφού έχετε κάνει rebased.

Σχόλια (28)

Από τον Μάιο του 2014, είναι δυνατή η ενημέρωση ενός fork απευθείας από το GitHub. Αυτό εξακολουθεί να λειτουργεί από τον Σεπτέμβριο του 2017, ΑΛΛΑ θα οδηγήσει σε ένα βρώμικο ιστορικό δεσμεύσεων.

  1. Ανοίξτε το fork σας στο GitHub.
  2. Κάντε κλικ στο Pull Requests.
  3. Κάντε κλικ στο New Pull Request. Από προεπιλογή, το GitHub θα συγκρίνει το πρωτότυπο με το fork σας, και δεν θα πρέπει να υπάρχει τίποτα να συγκριθεί αν δεν κάνατε καμία αλλαγή.
  4. Κάντε κλικ στην επιλογή switching the base αν δείτε αυτόν τον σύνδεσμο. Διαφορετικά, ορίστε χειροκίνητα το base fork drop down στο δικό σας fork και το head fork στο upstream. Τώρα το GitHub θα συγκρίνει το fork σας με το πρωτότυπο και θα πρέπει να δείτε όλες τις τελευταίες αλλαγές. 1
  5. Create pull request και δώστε ένα προβλέψιμο όνομα στο pull request σας (π.χ. Update from original).
  6. Μετακινηθείτε προς τα κάτω στο Merge pull request, αλλά μην κάνετε κλικ σε τίποτα ακόμα.

Τώρα έχετε τρεις επιλογές, αλλά η καθεμία θα οδηγήσει σε ένα λιγότερο καθαρό ιστορικό δεσμεύσεων.

  1. Η προεπιλογή θα δημιουργήσει μια άσχημη δέσμευση συγχώνευσης.
  2. Αν κάνετε κλικ στο αναπτυσσόμενο μενού και επιλέξετε "Squash and merge", όλες οι ενδιάμεσες δεσμεύσεις θα συμπιεστούν σε μία. Αυτό είναι τις περισσότερες φορές κάτι που δεν θέλετε.
  3. Αν κάνετε κλικ στο Rebase and merge, όλες οι commits θα γίνουν "μαζί"με" εσάς, τα αρχικά PRs θα συνδεθούν με το PR σας και το GitHub θα εμφανίσει This branch is X commits ahead, Y commits behind.

Έτσι, ναι, μπορείτε να κρατάτε το repo σας ενημερωμένο με το upstream του χρησιμοποιώντας το web UI του GitHub, αλλά με αυτόν τον τρόπο θα αμαυρώσετε το ιστορικό των commit σας. Χρησιμοποιήστε τη γραμμή εντολών - είναι εύκολο.

Σχόλια (15)

Εδώ είναι το επίσημο έγγραφο του GitHub για τον Συγχρονισμό μιας διακλάδωσης:

Συγχρονισμός μιας διακλάδωσης

Η εγκατάσταση

Προτού μπορέσετε να συγχρονίσετε, πρέπει να προσθέσετε ένα απομακρυσμένο που να δείχνει στο αποθετήριο upstream. Μπορεί να το έχετε κάνει αυτό όταν αρχικά είχατε κάνει fork.

  • Συμβουλή: Ο συγχρονισμός της διακλάδωσης ενημερώνει μόνο το τοπικό σας αντίγραφο του αποθετηρίου- δεν ενημερώνει το αποθετήριο στο GitHub.*

$ git remote -v

List the current remotes

origin  https://github.com/user/repo.git (fetch)
origin  https://github.com/user/repo.git (push)

$ git remote add upstream https://github.com/otheruser/repo.git

Set a new remote

$ git remote -v

Verify new remote

origin    https://github.com/user/repo.git (fetch)
origin    https://github.com/user/repo.git (push)
upstream  https://github.com/otheruser/repo.git (fetch)
upstream  https://github.com/otheruser/repo.git (push)

Συγχρονισμός

Υπάρχουν δύο βήματα που απαιτούνται για να συγχρονίσετε το αποθετήριό σας με το upstream: πρώτα πρέπει να φέρνετε από το απομακρυσμένο, στη συνέχεια πρέπει να συγχωνεύσετε τον επιθυμητό κλάδο στον τοπικό σας κλάδο.

Παραλαβή

Η άντληση από το απομακρυσμένο αποθετήριο θα φέρει τους κλάδους του και τις αντίστοιχες δεσμεύσεις τους. Αυτά αποθηκεύονται στο τοπικό σας αποθετήριο κάτω από ειδικούς κλάδους.

$ git fetch upstream

Πιάσε τους κλάδους του απομακρυσμένου αποθετηρίου upstream's

remote: Counting objects: 75, done.
remote: Compressing objects: 100% (53/53), done.
remote: Total 62 (delta 27), reused 44 (delta 9)
Unpacking objects: 100% (62/62), done.
From https://github.com/otheruser/repo
 * [new branch]      master     -> upstream/master

Τώρα έχουμε τον κύριο κλάδο του upstream's αποθηκευμένο σε έναν τοπικό κλάδο, upstream/master

$ git branch -va

List all local and remote-tracking branches

* master                  a422352 My local commit
  remotes/origin/HEAD     -> origin/master
  remotes/origin/master   a422352 My local commit
  remotes/upstream/master 5fdff0f Some upstream commit

Συνένωση

Τώρα που έχουμε ανακτήσει το upstream αποθετήριο, θέλουμε να συγχωνεύσουμε τις αλλαγές του στον τοπικό μας κλάδο. Αυτό θα φέρει αυτόν τον κλάδο σε συγχρονισμό με το upstream, χωρίς να χάσουμε τις τοπικές μας αλλαγές.

$ git checkout master

Check out our local master branch

Switched to branch 'master'

$ git merge upstream/master

Merge upstream's master into our own

Updating a422352..5fdff0f
Fast-forward
 README                    |    9 -------
 README.md                 |    7 ++++++
 2 files changed, 7 insertions(+), 9 deletions(-)
 delete mode 100644 README
 create mode 100644 README.md

Αν ο τοπικός σας κλάδος δεν είχε μοναδικές δεσμεύσεις, το git θα εκτελέσει αντί αυτού μια "fast-forward":

$ git merge upstream/master Ενημέρωση 34e91da..16c56ad Γρήγορη προώθηση README.md | 5 +++-- 1 αρχείο άλλαξε, 3 εισαγωγές(+), 2 διαγραφές(-)

  • Συμβουλή: Αν θέλετε να ενημερώσετε το αποθετήριό σας στο GitHub, ακολουθήστε τις οδηγίες εδώ*.
Σχόλια (5)