web-dev-qa-db-fra.com

Comment mettre à jour un référentiel GitHub forké?

J'ai récemment créé un projet et appliqué plusieurs correctifs. J'ai ensuite créé une demande d'extraction qui a ensuite été acceptée.

Quelques jours plus tard, un autre contributeur a apporté une autre modification. Donc, ma fourchette ne contient pas ce changement.

Comment puis-je obtenir ce changement dans ma fourchette? Dois-je supprimer et recréer mon fork lorsque j'ai d'autres modifications à apporter? Ou y a-t-il un bouton de mise à jour?

3275
Lea Hayes

Dans votre clone local de votre référentiel forké, vous pouvez ajouter le référentiel GitHub d'origine en tant que "distant". ("Remotes" sont comme des surnoms pour les URL des référentiels - Origin en est un, par exemple.) Vous pouvez ensuite extraire toutes les branches de ce référentiel en amont et redéfinir votre travail pour continuer à travailler sur la version en amont. En termes de commandes qui pourraient ressembler à:

# 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

Si vous ne souhaitez pas réécrire l'historique de votre branche principale (par exemple, parce que d'autres personnes l'ont peut-être cloné), vous devez remplacer la dernière commande par git merge upstream/master. Cependant, pour faire des demandes d'extraction aussi propres que possible, il est probablement préférable de rebaser.


Si vous avez redéfini votre branche sur upstream/master, vous devrez peut-être forcer le Push pour pouvoir le pousser dans votre propre référentiel forké sur GitHub. Vous feriez ça avec:

git Push -f Origin master

Il vous suffit d'utiliser le -f la première fois après le changement de base.

3583
Mark Longair

À partir de mai 2014, il est possible de mettre à jour un fork directement à partir de GitHub. Cela fonctionne toujours à partir de septembre 2017, MAIS cela conduira à un historique de commit sale.

  1. Ouvrez votre fourche sur GitHub.
  2. Cliquer sur Pull Requests.
  3. Cliquer sur New Pull Request. Par défaut, GitHub comparera l'original à votre fork, et il ne devrait rien y avoir à comparer si vous n'avez apporté aucune modification.
  4. Cliquez sur switching the base si vous voyez ce lien. Sinon, définissez manuellement le base fork descendez à votre fourche, et le head fork à l'amont. Maintenant, GitHub comparera votre fork avec l'original, et vous devriez voir toutes les dernières modifications. enter image description here
  5. Create pull request et attribuez un nom prévisible à votre demande d'extraction (par exemple, Update from original).
  6. Faites défiler jusqu'à Merge pull request, mais ne cliquez pas encore sur quelque chose.

Vous avez maintenant trois options, mais chacune d’elles conduira à un historique de validation moins que pur.

  1. La valeur par défaut créera une validation de fusion laide.
  2. Si vous cliquez sur le menu déroulant et choisissez "Réduire et fusionner", tous les commits intervenant seront regroupés en un seul. C'est le plus souvent quelque chose que vous ne voulez pas.
  3. Si vous cliquez Rebase and merge, tous les commits seront effectués "avec" vous, les PRs originaux seront liés à votre PR, et GitHub affichera This branch is X commits ahead, Y commits behind <original fork>.

Alors oui, vous pouvez garder votre rapport mis à jour avec son amont en utilisant l'interface utilisateur Web de GitHub, mais cela détruira votre historique de validation. Tenez-vous en à la ligne de commande à la place - c'est facile.

696
lobzik

Voici le document officiel de GitHub sur Synchroniser un fork :

Synchroniser une fourchette

La mise en place

Avant de pouvoir synchroniser, vous devez ajouter une télécommande qui pointe vers le référentiel en amont. Vous avez peut-être fait cela lorsque vous avez créé un fork.

Conseil: La synchronisation de votre fork permet uniquement de mettre à jour votre copie locale du référentiel; il ne met pas à jour votre référentiel sur 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)

Synchronisation

Il existe deux étapes pour synchroniser votre référentiel avec l'amont: vous devez d'abord aller chercher à partir de la télécommande, puis fusionner la branche souhaitée dans votre branche locale.

Aller chercher

La récupération depuis le référentiel distant apportera ses branches et leurs commits respectifs. Ceux-ci sont stockés dans votre référentiel local sous des branches spéciales.

$ git fetch upstream
# Grab the upstream remote's branches
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

Nous avons maintenant la branche principale en amont stockée dans une branche locale, en amont/maître

$ 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

Fusionner

Maintenant que nous avons récupéré le référentiel en amont, nous souhaitons fusionner ses modifications dans notre branche locale. Cela synchronisera cette branche avec l'amont, sans perdre nos modifications locales.

$ 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

Si votre branche locale n'a pas de commits uniques, git effectuera une "avance rapide":

$ git merge upstream/master
Updating 34e91da..16c56ad
Fast-forward
 README.md                 |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Astuce: Si vous souhaitez mettre à jour votre référentiel sur GitHub, suivez les instructions ici

421
jumpnett

Beaucoup de réponses finissent par déplacer votre fork d'un commit du référentiel parent. Cette réponse résume les étapes trouvées ici qui va déplacer votre fork sur le même commit que le parent .

  1. Changer de répertoire dans votre référentiel local.

    • Passez à la branche principale si vous n'êtes pas git checkout master
  2. Ajoutez le parent en tant que référentiel distant, git remote add upstream <repo-location>

  3. Numéro git fetch upstream
  4. Numéro git rebase upstream/master

    • A ce stade, vous vérifiez que les modifications seront fusionnées en tapant git status
  5. Numéro git Push Origin master

Pour plus d'informations sur ces commandes, reportez-vous à la section étape .

91
Sahar Rabinoviz

Depuis novembre 2013, une demande de fonctionnalité non officielle a été ouverte avec GitHub pour leur demander d'ajouter une méthode très simple et intuitive pour garder un fork local synchronisé avec le flux amont:

https://github.com/isaacs/github/issues/121

Remarque: la demande de fonctionnalité n'étant pas officielle, il est également conseillé de contacter [email protected] pour ajouter votre soutien à la mise en œuvre d'une fonctionnalité de ce type. La demande de fonctionnalité non officielle ci-dessus pourrait servir de preuve de l’intérêt manifesté pour cette mise en œuvre.

44
isedwards

Avant-propos: Votre fork est "l'origine" et le référentiel à partir duquel vous avez créé un "amont".

Supposons que vous ayez déjà cloné votre fork sur votre ordinateur avec une commande comme celle-ci:

git clone [email protected]:your_name/project_name.git
cd project_name

Si cela est indiqué, vous devez continuer dans cet ordre:

  1. Ajoutez le "amont" à votre référentiel cloné ("Origin"):

    git remote add upstream [email protected]:original_author/project_name.git
    
  2. Récupérez les commits (et les branches) de "l'amont":

    git fetch upstream
    
  3. Passez à la branche "master" de votre fork ("Origin"):

    git checkout master
    
  4. Rangez les modifications de votre branche "maître":

    git stash
    
  5. Fusionnez les modifications de la branche "maître" de "l'amont" dans votre branche "maître" de votre "origine":

    git merge upstream/master
    
  6. Résoudre les conflits de fusion, le cas échéant, et valider votre fusion

    git commit -am "Merged from upstream"
    
  7. Poussez les modifications sur votre fourche

    git Push
    
  8. Récupère vos modifications cachées (le cas échéant)

    git stash pop
    
  9. Vous avez terminé! Toutes nos félicitations!

GitHub fournit également des instructions pour ce sujet: Synchroniser un fork

42
Benny Neugebauer

Si, comme moi, vous ne jamais rien faire directement dans master, ce que vous devriez vraiment, vous pouvez faire ce qui suit.

À partir du clone local de votre fork, créez votre télécommande en amont. Il suffit de le faire une fois:

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

Ensuite, chaque fois que vous souhaitez rattraper la branche principale du référentiel en amont, vous devez:

git checkout master
git pull upstream master

En supposant que vous n’ayez jamais rien commis sur maître, vous devriez déjà le faire. Vous pouvez maintenant pousser votre maître local sur votre fourche d'origine GitHub distante. Vous pouvez également redéfinir votre branche de développement sur votre maître local, désormais à jour.

Après la configuration initiale en amont et la vérification du maître, il vous suffit d’exécuter la commande suivante pour synchroniser votre maître en amont: git pull upstream master.

39
Slion

À la date de cette réponse, GitHub n'a pas ( ou devrais-je dire plus? ) cette fonctionnalité dans l'interface Web. Vous pouvez cependant demander à [email protected] d'ajouter votre vote pour cela.

Entre temps, l'utilisateur de GitHub bardiharborow a créé un outil permettant de faire ceci: https://upriver.github.io/ =

La source est ici: https://github.com/upriver/upriver.github.io

22
Lucero

Si vous utilisez GitHub pour Windows, ils disposent désormais d'une fonctionnalité permettant de mettre à jour les forks en un clic:

  1. Sélectionnez le référentiel dans l'interface utilisateur.
  2. Cliquez sur le bouton "Mettre à jour depuis un utilisateur/une branche" en haut.
15
Shital Shah

En fait, il est possible de créer une branche dans votre fork à partir de n’importe quel commit en amont dans le navigateur:

  • Ouvrez https://github.com/<repo>/commits/<hash>, où repo est votre fourchette et dièse est un hash complet de commit que vous pouvez trouver dans l’interface Web en amont. Par exemple, je peux ouvrir https://github.com/max630/linux/commits/0aa0313f9d576affd7747cc3f179feb097d2899 , qui pointe sur linuxmaster au moment de l'écriture.
  • Cliquez sur le bouton "Arbre: ....".
  • Tapez le nom de la nouvelle branche et appuyez sur Enter

Enter image description here

Vous pouvez ensuite récupérer cette branche sur votre clone local, sans avoir à renvoyer toutes ces données à GitHub lorsque vous apportez des modifications au-dessus de ce commit. Ou utilisez l'interface Web pour modifier quelque chose dans cette branche.

Comment ça marche (c'est une supposition, je ne sais pas comment GitHub le fait exactement): les fourchettes partagent le stockage des objets et utilisent espaces de noms pour séparer les références des utilisateurs. Ainsi, vous pouvez accéder à tous les commits via votre fork, même s’ils n’existaient pas au moment de la conversion.

9
max630

Suivez les étapes ci-dessous. Je les ai essayés et ça m'a aidé.

Paiement à votre agence

Syntaxe: git branch yourDevelopmentBranch
Exemple: git checkout master

Extrait la branche du référentiel source pour obtenir le dernier code

Syntaxe: git pull https://github.com/tastejs/awesome-app-ideas maître
Exemple: git pull https://github.com/ORIGINAL_OWNER/ORIGINAL_REPO.git BRANCH_NAME

8
Venkat.R

En complément de cette réponse, je cherchais un moyen de mettre à jour toutes les branches distantes de mon référentiel cloné ( Origin ) à partir de en amont des branches en une fois. Voici comment je l'ai fait.

Cela suppose que vous avez déjà configuré un pointage distant en amont vers le référentiel source (où Origine a été dérivé de) et l'a synchronisé avec git fetch upstream.

Puis lancez:

for branch in $(git ls-remote --heads upstream|sed 's#^.*refs/heads/##'); do git Push Origin refs/remotes/upstream/$branch:refs/heads/$branch; done

La première partie de cette commande répertorie toutes les têtes du référentiel distant en amont et supprime le SHA-1 suivi du préfixe refs/heads/ du nom de la branche.

Ensuite, pour chacune de ces branches, il envoie directement la copie locale de la branche de suivi distante en amont (refs/remotes/upstream/<branch> du côté local) branche sur Origine (refs/heads/<branch> du côté distant).

Chacune de ces commandes de synchronisation de branche peut échouer pour deux raisons: la branche en amont a été réécrite ou vous avez envoyé des validations sur cette branche à votre fourchette. Dans le premier cas où vous n'avez rien engagé dans la branche de votre branche, il est prudent de pousser avec force (ajoutez le commutateur - f; c'est-à-dire git Push -f dans la commande ci-dessus). Dans l’autre cas, cela est normal car votre branche fork a divergé et vous ne pouvez pas vous attendre à ce que la commande sync fonctionne tant que vos validations n’ont pas été fusionnées dans en amont .

6

Je mets à jour mes dépôts avec cette seule ligne:

git pull https://github.com/forkuser/forkedrepo.git branch

Utilisez cette option si vous ne souhaitez pas ajouter un autre point de terminaison distant à votre projet, comme les autres solutions publiées ici.

5
R.Bravo

Android Studio a maintenant appris à travailler avec les référentiels fork de GitHub (vous n'avez même pas besoin d'ajouter un référentiel distant "en amont" à l'aide d'une commande de console).

Ouvrir le menu VCS Git

Et faites attention aux deux derniers éléments du menu contextuel:

  • Rebase mon fork de GitHub

  • Créer une demande d'extraction

Essayez les. J'utilise le premier pour synchroniser mon référentiel local. Quoi qu'il en soit, les branches du référentiel distant parent ("en amont") seront accessibles dans Android Studio après avoir cliqué sur "Rebaser mon fork GitHub", et vous pourrez facilement les utiliser.

(J'utilise Android Studio 3.0 avec les plug-ins "intégration Git" et "GitHub".)

Enter image description here

3
alexshr

Lorsque vous avez cloné votre référentiel forké, accédez au chemin du répertoire dans lequel réside votre clone et aux quelques lignes de votre terminal Git Bash.

$ cd project-name

$ git remote add upstream https://github.com/user-name/project-name.git
 # Adding the upstream -> the main repo with which you wanna sync

$ git remote -v # you will see the upstream here 

$ git checkout master # see if you are already on master branch

$ git fetch upstream

Et vous voilà prêt à partir. Toutes les modifications mises à jour dans le référentiel principal seront placées dans votre référentiel fork.

La commande "fetch" est indispensable pour rester à jour dans un projet: c'est uniquement lorsque vous effectuez un "git fetch" que vous êtes informé des modifications que vos collègues ont appliquées au serveur distant.

Vous pouvez toujours visiter ici pour d'autres requêtes

3
Prateek Chanda

Cela dépend de la taille de votre référentiel et de la façon dont vous l'avez créé.

Si le référentiel est assez volumineux, vous avez peut-être voulu le gérer de manière spéciale (par exemple, l'historique des dépôts). Fondamentalement, vous pouvez obtenir des différences entre les versions actuelle et amont, les valider, puis les rediriger vers maître.

Essayez de lire celui-ci . Il décrit comment gérer les grands référentiels Git et comment les remonter avec les dernières modifications.

1
s0nicYouth

Si vous définissez votre amont. Vérifiez avec git remote -v, alors cela suffira.

git fetch upstream
git checkout master
git merge --no-edit upstream/master
git Push
1
prosti

Il y a deux choses principales pour garder un référentiel forké toujours mettre à jour pour de bon.

1. Créez les branches à partir du fichier fork et effectuez les modifications à cet emplacement .

Ainsi, lorsque votre requête d'extraction est acceptée, vous pouvez supprimer la branche en toute sécurité, car le code que vous apportez sera alors stocké dans votre maître de votre référentiel forké lorsque vous le mettrez à jour en amont. De ce fait, votre maître sera toujours en état de créer une nouvelle branche pour effectuer un autre changement.

2. Créez un travail planifié pour le maître des fourches à mettre à jour automatiquement .

Cela peut être fait avec cron. Voici un exemple de code si vous le faites sous Linux.

$ crontab -e

mettez ce code sur le crontab file pour exécuter le travail toutes les heures.

0 * * * * sh ~/cron.sh

créez ensuite le fichier de script cron.sh et un interaction git avec ssh-agent = et/ou attend comme ci-dessous

#!/bin/sh
WORKDIR=/path/to/your/dir   
REPOSITORY=<name of your repo>
MASTER="[email protected]:<username>/$REPOSITORY.git"   
[email protected]:<upstream>/<name of the repo>.git  

cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent` && expect ~/.ssh/agent && ssh-add -l
git clone $MASTER && cd $REPOSITORY && git checkout master
git remote add upstream $UPSTREAM && git fetch --Prune upstream
if [ `git rev-list HEAD...upstream/master --count` -eq 0 ]
then
    echo "all the same, do nothing"
else
    echo "update exist, do rebase!"
    git reset --hard upstream/master
    git Push Origin master --force
fi
cd $WORKDIR && rm -rf $REPOSITORY
eval `ssh-agent -k`

Vérifiez votre référentiel forké. De temps en temps, cette notification sera toujours affichée:

Cette branche est même avec <upstream>: master .

enter image description here

0
Chetabahana