Comment 'git pull' dans une branche qui n'est pas la branche actuelle?

126

Lorsque vous exécutez git pullsur la masterbranche, il tire généralement de origin/master. Je suis dans une branche différente appelée newbranch, mais je dois exécuter une commande qui fait un git pullde origin/masteren mastermais je ne peux pas exécuter git checkoutpour changer la branche sélectionnée tant que l'extraction n'est pas terminée. Y a-t-il un moyen de faire cela?

Pour donner un peu de contexte, le référentiel stocke un site Web. J'ai apporté quelques modifications newbranchet les ai déployées en basculant le site Web vers newbranch. Maintenant que ces changements ont été fusionnés en amont dans la mastersuccursale, j'essaie de ramener le site Web à la mastersuccursale également. À ce stade, newbranchet origin/mastersont identiques, mais masterest à la traîne origin/masteret doit être mis à jour. Le problème est, si je le fais de manière traditionnelle:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Je dois réaliser la même chose que ci-dessus ( git checkout master && git pull), mais sans changer le répertoire de travail vers une révision antérieure au cours du processus.

Malvineous
la source
@phi: Je ne pense pas que ça marcherait, parce que j'y suis newbranchet qu'il n'y a rien à cacher!
Malvineous
Je clonerais dans un nouveau répertoire, fusionnerais newbranch dans master, fusionnerais à nouveau master dans newbranch, puis git pull d'où vous êtes. Master et newbranch seront les mêmes.
aet
@aet Il pourrait simplement le faire maintenant dans son répertoire actuel en faisant git fetch; git merge origin/masterde l'intérieur newbranch. Il n'y a aucun avantage à cloner une deuxième copie entière du référentiel.
meagar
3
étroitement liés: stackoverflow.com/questions/3216360/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
Possibilité de duplication des branches Merge, Update et Pull Git sans utiliser de checkouts
Kyll

Réponses:

5

Vous avez un arbre de travail que vous ne voulez pas toucher, alors utilisez-en un autre. Le clone est bon marché, il est conçu pour cela.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

Le problème avec toutes les autres réponses ici est qu'elles ne tirent pas réellement. Si vous avez besoin de la fusion ou du rebase pour lequel vous avez configuré l'extraction, vous avez besoin d'un autre arbre de travail et de la procédure ci-dessus. Sinon git fetch; git checkout -B master origin/master, ça fera l'affaire.

jthill
la source
2
Lorsque vous exécutez, git checkout mastervous récupérez l'ancienne masterbranche car vous n'avez pas fait de git pulldans le maindossier pour le synchroniser avec origin / master. C'est ce que j'essaye d'éviter.
Malvineous
L'extraction effectuée par le clone est de l'ancien maître, mais cette extraction est dans un répertoire que le serveur Web ne regarde pas. L'extraction principale à la fin est celle du maître entièrement fusionné qui a été repoussé de l'effacement.
jthill
À la ligne 6, vous repoussez la fusion (mise à jour) mastervers origin, mais je ne pense pas que votre paiement final soit de cette mise à jour master. Il n'y a pas git pullde mise à jour de la masterbranche dans le mainrépertoire, donc à moins que je ne manque quelque chose, vos commandes ne sont pas différentes de simplement fonctionner git checkout masterseules et d'obtenir l'ancien masterarbre. Si vous regardez de près, vous n'exécutez aucune commande dans le mainrépertoire qui communique en amont (à l'exception de la ligne 1, qui est exécutée avant que vous
n'apportiez
eh bien, vous pouvez l'essayer sur un dépôt de test ou consulter les documents push.
jthill
1
@jwg par rapport à quoi, s'il vous plaît? Assurez-vous de répondre à tous les besoins déclarés de l'OP.
jthill
163

Simple: mise à jour d'une branche distante vers un maître de branche actuellement non extrait :

git fetch origin master:master

origin est votre télécommande et vous êtes actuellement extrait dans une branche, par exemple dev .

Si vous souhaitez mettre à jour votre branche actuelle en plus de la branche spécifiée en une seule fois:

git pull origin master:master
Martin Peter
la source
4
Hm, il semble que cela ne fonctionne pas toujours, cependant; Je viens d'être invité à fusionner avec ma branche WIP.
underscore_d
@underscore_d pareil pour moi.
Greg
1
Cela a fonctionné pour moi ... si cela invite à fusionner, j'imagine qu'il y a des changements dans votre branche que vous mettez à jour et qui ne sont pas validés par rapport à l'origine
skim
2
Comment cela fonctionne-t-il? Cela ne fonctionne pas pour moi, il essaie simplement de fusionner l'origine / le maître dans ma branche actuellement extraite.
mhogerheijde
3
Cela entraîne le maître dans la branche actuelle. Ce n'est certainement PAS ce qui est demandé. Si vous changez pull pour récupérer, alors ce serait exactement ce qui est demandé.
Jeff Wolski
90

Ceci est répondu ici: Fusionner, mettre à jour et extraire des branches Git sans utiliser d'extraction

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo
Thomas
la source
2
C'est le meilleur, car il fonctionne avec des modifications locales non validées.
Tomasz Gandor
2
Si vous voulez juste rattraper les derniers changements que vous feriez git fetch origin master:master. git fetchen soi supposerait que vous vouliez mettre à jour la branche actuelle et non une autre branche.
John Leidegren
2
C'est la réponse la plus simple et la plus directe. Cela devrait être la réponse acceptée de l'OMI.
Keego
@JohnLeidegren - sauf que cela ne fonctionne pas toujours comme prévu. Voir les commentaires sur stackoverflow.com/a/42902058/274579 réponse.
ysap
22

En fait, la réponse est d'une simplicité trompeuse:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Cela vous permet de mettre à jour la masterbranche sans passer à jusqu'à après qu'il a été mis à jour.

Malvineous
la source
11
Cela ne fait pas ce que vous avez demandé comment faire.
jthill
Comme le dit le commentaire ci-dessus, la question que vous avez fini par poser n'est pas vraiment la question à laquelle vous avez fini par répondre. Vous devriez mettre à jour votre question afin qu'il s'agisse moins spécifiquement de fusionner dans une branche sans la vérifier, et plus de passer directement à la dernière version d'une branche disponible sur une télécommande sans avoir d'abord vérifié l'ancienne version.
meagar
1
C'est absolument la réponse que je suis venu chercher ici :)
Sophistifunk
1
Pas ce que OP voulait, mais m'a aidé, pour être honnête.
Marcel Bro
1
@anoniim, pas ce que le PO voulait? Vous voulez dire le PO qui vient de répondre à cette question?
smac89
12

Vous vous inquiétez de quelque chose qui ne peut pas être corrigé, car les opérations Git ne sont pas atomiques. Vous aurez toujours un trou où votre répertoire de travail est à mi-chemin entre les branches, même si vous mettez à jour le maître sans y avoir d'abord basculé. C'est pourquoi Git n'est pas un outil de déploiement .

Puisque vous ne validez pas réellement de code dans votre environnement de production (j'espère), vous n'avez pas vraiment besoin de faire extraire une branche. Vous pouvez simplement faire a git fetchpour mettre à jour vos références distantes, puis git checkout origin/masterpour déplacer le répertoire de travail directement vers le commit actuellement pointé par origin/master. Cela vous mettra dans un état principal détaché, mais encore une fois, comme vous ne validez pas de code, cela n'a pas d'importance.

C'est le plus petit trou que vous allez avoir, mais comme je l'ai dit, un trou existe toujours; checkoutn'est pas atomique.

meagar
la source
Je comprends les limites de l'utilisation de git pour le déploiement, le problème est que le trou dans ce cas va durer quelques minutes au lieu de moins d'une seconde. Bonne idée de vérifier origin/mastercependant, cela pourrait bien faire l'affaire.
Malvineous
Qu'est-ce qui fait que le trou dure "minutes"? Extraire des données sur le réseau? git fetchFaites juste un avant de faire quoi que ce soit d'autre et éliminez le transfert réel des données.
meagar
Cela dure quelques minutes car un fichier (maintenant) non suivi serait écrasé par une validation antérieure. Je dois donc copier le fichier, faire le truc git, puis le remettre. Les «minutes» proviennent de ma vitesse de frappe. (Oui, je pouvais le scénariser, mais c'était juste pour faire valoir que le fait d'avoir git tout faire lui-même est plus rapide.)
Malvineous
3

Vous pouvez utiliser update-ref pour cela:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Notez que cela rejetterait tous les commits locaux dans la branche master. Dans votre cas, il n'y en aura pas, donc ça va. Pour d'autres personnes qui essaient de faire cela là où il y a des commits locaux, je ne pense pas que ce soit possible, car la fusion ne peut être exécutée que sur la branche actuelle.

Philip Beber
la source
Serait-ce équivalent à git branch --force master origin/master? Cela oblige le chef local masterà pointer vers le chef de originsmaster
Keego
2

La solution de Malvineous fonctionne pour moi

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Juste pour donner l'erreur


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Alors je cours avec l'option -D

Merci

Sébastien Oscar Lopez
la source
0

git fetch origin master:master

  • "Pulls" (en fait récupère) master.
  • Si vous avez des modifications sur votre masterqui ne sont pas encore transmises, elles origin/mastersont fusionnées dans votre maître.
  • S'il y a des conflits de fusion, vous devrez d'abord les résoudre.
Luzian
la source