web-dev-qa-db-fra.com

Comment puis-je 'git fetch' et 'git fusion' depuis une branche de suivi à distance (comme 'git pull')

J'ai configuré certaines branches de suivi à distance dans git, mais il semble que je ne sois jamais capable de les fusionner dans la branche locale une fois que je les ai mises à jour avec "git fetch".

Par exemple, supposons que j'ai une branche distante appelée "une autre branche". Je configure cela localement comme une branche de suivi en utilisant

git branch --track an-other-branch Origin/an-other-branch

Jusqu'ici tout va bien. Mais si cette branche est mise à jour (généralement par le déplacement de la machine et la validation de cette machine) et que je souhaite la mettre à jour sur la machine d'origine, des problèmes d'extraction/fusion se présentent:

git fetch Origin an-other-branch
git merge Origin/an-other-branch

Chaque fois que je fais cela, je reçois un message "Déjà mis à jour" et rien ne se fond.

Cependant, un

git pull Origin an-other-branch

met toujours à jour comme vous vous en doutez.

En outre, en cours d'exécution git diff

git diff Origin/an-other-branch

montre qu'il y a des différences, alors je pense que ma syntaxe est fausse.

Qu'est-ce que je fais mal?

EDIT [2010-04-09]: J'ai vérifié plusieurs fois et je ne suis certainement pas sur une autre branche. Mon "git fetch" suivi d'une "fusion de git" (comme indiqué ci-dessus) fait-il exactement la même chose qu'un pull git? Je vais obtenir un flux de travail montrant les résultats d'un statut git, etc.

111
kaybenleroll

Vous ne récupérez pas de branche, vous récupérez une télécommande entière:

git fetch Origin
git merge Origin/an-other-branch
168
Gareth

Sélection d'une seule branche: fetch/merge vs. pull

Les gens vous conseillent souvent de séparer "chercher" de "fusionner". Ils disent à la place de ceci:

    git pull remoteR branchB

faire ceci:

    git fetch remoteR
    git merge remoteR branchB

Ce qu’ils ne mentionnent pas, c’est qu’une telle commande de récupération extraira effectivement toutes les branches du dépôt distant, qui est . ) pas ce que fait la commande pull. Si vous avez des milliers de branches dans le référentiel distant, mais que vous ne voulez pas toutes les voir, vous pouvez exécuter cette commande obscure:

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

Bien sûr, c’est ridiculement difficile à retenir, donc si vous voulez vraiment éviter d’aller chercher toutes les branches, il est préférable de modifier votre .git/config comme décrit dans ProGit.

Hein?

La meilleure explication de tout cela se trouve au chapitre 9-5 de ProGit, Git Internals - The Refspec ( ou via github ). C'est incroyablement difficile à trouver via Google.

Premièrement, nous devons clarifier certains termes. Pour le suivi des branches distantes, il existe généralement 3 branches différentes à connaître:

  1. La branche sur le référentiel distant: refs/heads/branchB à l'intérieur de l'autre dépôt
  2. Votre branche de télé-suivi : refs/remotes/remoteR/branchB dans votre repo
  3. Votre propre branche: refs/heads/branchB à l'intérieur de votre repo

Suivi des branches à distance (dans refs/remotes) sont en lecture seule. Vous ne les modifiez pas directement. Vous modifiez votre propre branche, puis vous appuyez sur la branche correspondante dans le référentiel distant. Le résultat ne se reflète pas dans votre refs/remotes jusqu’à la fin d’une traction ou d’une récupération appropriée. Cette distinction était difficile à comprendre pour moi à partir des pages de manuel de git, principalement parce que la branche locale (refs/heads/branchB) est dit "suivre" la branche de télé-suivi quand .git/config définit branch.branchB.remote = remoteR.

Pensez à 'refs' comme des pointeurs C++. Physiquement, ce sont des fichiers contenant des résumés SHA, mais au fond, ils ne sont que des pointeurs dans l'arbre de validation. git fetch ajoutera de nombreux noeuds à votre arbre de validation, mais la manière dont git décide des pointeurs à déplacer est un peu compliquée.

Comme mentionné dans autre réponse , ni

    git pull remoteR branchB

ni

    git fetch remoteR branchB

se déplacerait refs/remotes/branches/branchB, et ce dernier ne peut certainement pas bouger refs/heads/branchB. Cependant, les deux bougent FETCH_HEAD. (Vous pouvez cat n’importe lequel de ces fichiers dans .git/ pour voir quand ils changent.) Et git merge fera référence à FETCH_HEAD, en mettant MERGE_ORIG, etc.

67
cdunn2001

Êtes-vous sûr que vous êtes sur le an-other-branch Local lorsque vous fusionnez?

git fetch Origin an-other-branch
git checkout an-other-branch
git merge Origin/an-other-branch

Le autre explication :

toutes les modifications de la branche que vous essayez de fusionner ont déjà été fusionnées avec la branche sur laquelle vous vous trouvez.
Plus spécifiquement, cela signifie que la branche que vous essayez de fusionner est un parent de votre branche actuelle.

si vous êtes en avance sur le dépôt distant par un commit, c'est le dépôt distant qui est obsolète, pas vous.

Mais dans votre cas, si git pull Fonctionne, cela signifie simplement que vous n'êtes pas sur la bonne branche.

9
VonC

Git pull est en fait un outil combo: il exécute git fetch (récupère les modifications) et git fusionne (les fusionne avec votre copie actuelle)

Êtes-vous sûr que vous êtes sur la bonne branche?

3
RDL

ce sont les commandes:

git fetch Origin
git merge Origin/somebranch somebranch

si vous faites cela sur la deuxième ligne:

git merge Origin somebranch

il va essayer de fusionner le maître local dans votre branche actuelle.

Si j'ai bien compris, la question était de savoir si vous aviez déjà récupéré localement et que vous souhaitiez maintenant fusionner votre branche avec la dernière de la branche identique.

1
user1524957