2009-09-10 6 views
20

que j'ai une branche de fonctionnalité, dans laquelle je fusionne les changements en amont avant de pousser mes modifications dans:git checkout et fusionner sans toucher l'arbre de travail

git branch feature1 
... [edit my code] 
... [commit] 
git fetch origin master 
git merge fetch_head [or rebase] 
... [resolve conflicts] 
... [build and test code] 

À ce stade, je voudrais pousser mes changements. La façon normale de faire ce serait:

git checkout master [changes a bunch of working tree files] 
git merge feature1 [changes the same files right back] 

Cela fonctionne très bien, mais fera la (date de vérification) compilateur pense que tout un tas de fichiers sont sales et a besoin d'une reconstruction, même si le contenu sont les mêmes . Existe-t-il un moyen de checkout-and-merge qui laisse l'arbre de travail inchangé dans ce cas?

Quelque chose comme:

git checkout master --merge-branch feature1 

EDIT:

Je ne parle que de l'avance rapide se confond par définition ne changerait pas l'état des fichiers.

+0

http://stackoverflow.com/questions/1282639/switch-git-branch-without-files-checkout –

+0

double possible de [fusion, mise à jour, et tirer les branches Git sans utiliser checkouts] (http://stackoverflow.com/questions/3216360/merge-update-and-pull-git-branches-without-using-checkouts) –

Répondre

7

[Éditer] Ceci est seulement une solution partielle/solution de contournement. Voir la réponse réelle par @djpohly ci-dessous.

Premièrement, vous pouvez pousser depuis n'importe où. Peu importe ce que vous avez extrait, ou si les commits que vous voulez pousser sont en master.

git push REMOTE_REPO feature1:master 

voir git help push

Conseil: git push remoteRepo localRef:remoteRef

Comme pour amener maître à l'endroit où vous êtes maintenant sans jongler avec votre copie de travail ... Vous pouvez forcer comme ceci:

# (while still on feature1 branch) 
git checkout -B master origin/master 

Mais cela fait une réinitialisation matérielle sur le maître. c'est-à-dire qu'il ne vérifie pas l'avance rapide.

+0

C'est vrai, et corrige la moitié du problème. Même ainsi, je ne peux pas vraiment rester sur la branche de fonctionnalité après qu'elle soit terminée. Comme je voudrais revenir à la maîtrise, j'aurais encore ce problème (plutôt mineur). –

+1

Eh bien, l'autre partie de votre question (à propos de vouloir les temps de modification de vos fichiers en quelque sorte magiquement changé pour la bonne chose) n'est pas vraiment résoluble. Git ne sait pas quels fichiers ont été compilés quand. Donc git met toujours à jour les horodatages quand il change les fichiers. Cela entraîne une recompilation supplémentaire, mais c'est beaucoup mieux que de ne pas recompiler quand cela devrait parfois arriver. – JasonWoof

+2

Peut-être que vous aimeriez avoir un autre clone sur votre ordinateur, de sorte que vous pouvez avoir vérifié les deux à la fois? Si vous vous souciez de l'espace, il est possible que deux clones locaux partagent le stockage des repo. – JasonWoof

3

Il est impossible de fusionner (ou de rebaser) sans toucher au répertoire de travail (et à l'index), car il peut y avoir des conflits de fusion qui doivent être résolus en utilisant le répertoire de travail (et/ou index).

Vous pouvez toujours avoir un autre clone (en utilisant peut-être des alternatives ou un répertoire d'objets symlink pour économiser de l'espace disque) ou un autre répertoire de travail avec contrib/workdir/git-new-workdir. Ou utilisez un outil tel que ccache.

36

Une façon simple et sûre de le faire, sans une poussée ou une mise à jour est-chercher feature1 en maître forcé:

(feature1)$ git fetch . feature1:master 
From . 
    4a6000d..8675309 feature1 -> master 

L'astuce utilise . pour obtenir l'arbitre locale feature1. C'est plus sûr que de mettre à jour de force la branche master, car elle garantit que la mise à jour est un fast-forward. (Voir le paramètre <refspec> dans le git-fetch documentation pour plus de détails.)

Maintenant que feature1 et maître sont les mêmes, la commutation entre eux ne touche pas tous les fichiers:

(feature1)$ git checkout master 
Switched to branch 'master' 
(master)$ 
+0

Merci, cela a fonctionné. Bien que, je ne comprends pas ce que fait la partie 'fetch'. – towi

+1

@towi Vous faites effectivement un 'git pull' de vous-même sans mettre à jour la copie de travail (git pull est essentiellement une combinaison de' git fetch' et 'git merge'). – dlitz

+3

Ceci devrait être la réponse acceptée. Je reviens toujours dans divers scénarios :) –

0

Si vous ne vous préoccupez quelques fichiers et que vous utilisez Unix, vous pouvez modifier manuellement réparer le mtime après le fait en utilisant touch -d <timestamp>. Assurez-vous d'utiliser ls --full-time pour obtenir l'horodatage, car l'affichage par défaut manque de précision. Par exemple, imaginez que vous utilisez Docker pour créer une image pour une application Web basée sur Python. Si le fichier requirements.txt change, la reconstruction prend du temps, car il doit télécharger un tas de bibliothèques tierces et les compiler. réinitialiser tout simplement le mtime de ce fichier après la fusion:

ls -og --full-time src/requirements.txt 
# -rw-r--r-- 1 282 2015-11-04 20:03:28.918979065 +0400 src/requirements.txt 

git checkout master 
git merge --no-ff feature-foo 

touch src/requirements.txt -d "2015-11-04 20:03:28.918979065 +0400" 
Questions connexes