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?
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.
À 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.
Update from original
).Vous avez maintenant trois options, mais chacune d’elles conduira à un historique de validation moins que pur.
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.
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
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 .
Changer de répertoire dans votre référentiel local.
git checkout master
Ajoutez le parent en tant que référentiel distant, git remote add upstream <repo-location>
git fetch upstream
Numéro git rebase upstream/master
git status
Numéro git Push Origin master
Pour plus d'informations sur ces commandes, reportez-vous à la section étape .
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.
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:
Ajoutez le "amont" à votre référentiel cloné ("Origin"):
git remote add upstream [email protected]:original_author/project_name.git
Récupérez les commits (et les branches) de "l'amont":
git fetch upstream
Passez à la branche "master" de votre fork ("Origin"):
git checkout master
Rangez les modifications de votre branche "maître":
git stash
Fusionnez les modifications de la branche "maître" de "l'amont" dans votre branche "maître" de votre "origine":
git merge upstream/master
Résoudre les conflits de fusion, le cas échéant, et valider votre fusion
git commit -am "Merged from upstream"
Poussez les modifications sur votre fourche
git Push
Récupère vos modifications cachées (le cas échéant)
git stash pop
Vous avez terminé! Toutes nos félicitations!
GitHub fournit également des instructions pour ce sujet: Synchroniser un fork
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.
À 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
Si vous utilisez GitHub pour Windows, ils disposent désormais d'une fonctionnalité permettant de mettre à jour les forks en un clic:
En fait, il est possible de créer une branche dans votre fork à partir de n’importe quel commit en amont dans le navigateur:
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 linux
master
au moment de l'écriture.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.
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
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 .
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.
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".)
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
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.
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
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 .