Comment extraire une branche distante du référentiel de quelqu'un d'autre

266

J'ai un projet hébergé sur GitHub que quelqu'un a bifurqué. Sur leur fork, ils ont créé une nouvelle branche "foo" et ont fait quelques changements. Comment puis-je tirer leur "foo" dans une nouvelle branche également appelée "foo" dans mon repo?

Je comprends qu'ils pourraient me soumettre une demande de retrait, mais j'aimerais lancer ce processus moi-même.

Supposons ce qui suit:

  1. Parce qu'ils ont bifurqué mon projet, nos deux repos partagent la même 'histoire'
  2. Bien que GitHub montre que leur projet est issu du mien, mon référentiel local n'a aucune référence au projet de cette personne. Dois-je ajouter le leur en tant que télécommande?
  3. Je n'ai pas encore de branche appelée "foo" - je ne sais pas si je dois d'abord la créer manuellement.
  4. Je veux vraiment que cela soit tiré dans une branche distincte et non mon maître.
Colin O'Dell
la source

Réponses:

349
git remote add coworker git://path/to/coworkers/repo.git
git fetch coworker
git checkout --track coworker/foo

Cela va configurer une branche locale foo, suivre la branche distante coworker/foo. Ainsi, lorsque votre collègue a apporté des modifications, vous pouvez facilement les retirer:

git checkout foo
git pull

Réponse aux commentaires:

Cool :) Et si je souhaite apporter mes propres modifications à cette branche, dois-je créer une deuxième "barre" de branche locale à partir de "foo" et y travailler au lieu de directement sur mon "foo"?

Vous n'avez pas besoin de créer une nouvelle branche, même si je le recommande. Vous pourriez tout aussi bien vous engager directement fooet demander à votre collègue de retirer votre branche. Mais cette branche existe déjà et votre branchefoo doit être configurée en tant que branche amont:

git branch --set-upstream foo colin/foo

en supposant que colinvotre référentiel (distant de votre référentiel de collègues) est défini de la même manière:

git remote add colin git://path/to/colins/repo.git
ralphtheninja
la source
3
C'était très rapide :) Vous voudrez peut-être ajouter qu'il devrait utiliser l' git://URL de la page du référentiel GitHub de l'autre personne à la place de //path/to/coworkers/repo.git. (Décrivant ce qui a rendu ma réponse trop lente;))
Mark Longair
Cool :) Et si je souhaite apporter mes propres modifications à cette branche, dois-je créer une deuxième branche locale "bar" à partir de "foo" et y travailler au lieu de directement sur mon "foo"?
Colin O'Dell
Ou est-il sûr de travailler directement dans mon "foo" et de tirer / fusionner ses modifications plus tard? Quelle est la meilleure pratique ici?
Colin O'Dell
1
Parfait, c'est exactement ce que je cherchais :) Merci pour votre aide !!
Colin O'Dell
1
Belle réponse en 3 minutes!
Tieme
103

Non, vous n'avez pas besoin de les ajouter en tant que télécommande. Ce serait lourd et pénible à faire à chaque fois.

Saisir leurs engagements:

git fetch git@github.com:theirusername/reponame.git theirbranch:ournameforbranch

Cela crée une branche locale nommée ournameforbranchqui est exactement la même que celle qui theirbranchétait pour eux. Pour l'exemple de question, le dernier argument seraitfoo:foo .

Notez :ournameforbranchqu'une partie peut être laissée de côté si trouver un nom qui n'entre pas en conflit avec l'une de vos propres branches est gênant. Dans ce cas, une référence appelée FETCH_HEADest disponible. Vous pouvez git log FETCH_HEADvoir leurs commits puis faire des choses comme cherry-pickedchoisir leurs commits.

Le repousser à eux:

Souvent, vous voulez réparer quelque chose à eux et le repousser immédiatement. C'est possible aussi:

git fetch [email protected]:theirusername/reponame.git theirbranch
git checkout FETCH_HEAD

# fix fix fix

git push [email protected]:theirusername/reponame.git HEAD:theirbranch

Si travailler dans un état détaché vous inquiète, créez certainement une branche en utilisant :ournameforbranchet remplacez FETCH_HEADet HEADau - dessus par ournameforbranch.

antak
la source
2
Merci pour cela, l'autre réponse ne fonctionne pas si vous et l'autre personne avez des branches nommées de manière identique (comme la masterbranche par défaut )
Job
2
Il convient de mentionner que cette méthode ne fonctionnera pas si vous n'avez pas de trucs comme la clé SSH associée à votre compte github, voir stackoverflow.com/questions/12940626
Przemek D
n'avez-vous pas besoin d'être ajouté en tant que collaborateur pour pouvoir pousser à leur repo?
Honey
@Honey Certainement! Pousser suppose que vous disposez des autorisations nécessaires sur l'extrémité distante pour pousser. La récupération suppose également que le chemin est accessible.
antak
Si vous exécutez git branch -m newbranchdans cet état détaché, git perdra la raison et commencera à dire que votre dépôt n'est plus valide. git initsemble le réparer et vous remettre plus ou moins dans l'état où vous étiez avant, avec la branche nommée "newbranch".
Ian Hickson
14

Si la réponse d'Antak:

git fetch [email protected]:<THEIR USERNAME>/<REPO>.git <THEIR BRANCH>:<OUR NAME FOR BRANCH> 

vous donne:

Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Ensuite (suivant les conseils de Przemek D), utilisez

git fetch https://github.com/<THEIR USERNAME>/<REPO>.git <THEIR BRANCH>:<OUR NAME FOR BRANCH>
Peter
la source
6

Ce qui suit est une bonne solution pratique qui fonctionne avec GitHub pour extraire la branche PR à partir d'un fork d'un autre utilisateur. Vous devez connaître l'ID de demande d'extraction (que GitHub affiche avec le titre PR).

Exemple:

Corriger votre code non sécurisé # 8
Alice veut fusionner 1 commit dans your_repo:masterfromher_repo:branch

git checkout -b <branch>
git pull origin pull/8/head

Remplacez votre télécommande si différente de origin.
Remplacez 8par l'ID de demande d'extraction correct.

Subfuzion
la source
2
Cela nécessite plus de votes positifs. fonctionne parfaitement et a évité l'erreur «fatal: impossible de trouver la référence à distance» que j'obtenais avec la réponse la plus votée. Merci!
Michael Romrell
2 lignes de code facile. Merci d'avoir partagé ça! La seule chose plus douce que cela est de fusionner les mises à jour dans leur demande de tirage de manière simple.
klewis
4

GitHub a une nouvelle option par rapport aux réponses précédentes, il suffit de copier / coller les lignes de commande du PR:

  1. Faites défiler vers le bas du PR pour voir le MergeouSquash and merge bouton
  2. Cliquez sur le lien à droite: view command line instructions
  3. Appuyez sur l'icône Copier à droite de l'étape 1
  4. Collez les commandes dans votre terminal
Robert Monfera
la source
2

Si le dépôt fourchu est protégé de sorte que vous ne pouvez pas y pousser directement, et que votre objectif est d'apporter des modifications à leur foo, alors vous devez placer leur branche foo dans votre référentiel comme ceci:

git remote add protected_repo https://github.com/theirusername/their_repo.git
git fetch protected_repo 
git checkout --no-track protected_repo/foo

Vous avez maintenant une copie locale de foo sans amont associé. Vous pouvez y apporter des modifications (ou non), puis pousser votre foo vers votre propre référentiel distant.

git push --set-upstream origin foo

Maintenant, foo est dans votre référentiel sur GitHub et votre foo local le suit. S'ils continuent d'apporter des modifications à foo, vous pouvez les récupérer et les fusionner dans votre foo.

git checkout foo 
git fetch protected_repo
git merge protected_repo/foo
J Smith
la source