automatiquement cachette enregistrer/pop changements sur git rebase?
mon workflow git utilise rebase beaucoup. J'ai toujours chercher changements en amont (le principal repo j'ai forké) et puis les fusionner pour mes branches, et puis rebase pour supprimer inutile (pour moi :D) fusion s'engage et les divisions des arbres.
une chose sur ce flux de travail qui m'agace est:
$ git rebase upstream/master
Cannot rebase: You have unstaged changes.
Please commit or stash them.
$ git stash
Saved working directory and index state WIP on cc: abc1234 Merge remote-tracking branch 'upstream/master' into local_branch
HEAD is now at abc1234 Merge remote-tracking branch 'upstream/master' into local_branch
$ git rebase upstream/master
First, rewinding head to replay your work on top of it...
Applying: awesome code change
$ git stash pop
nous avons donc ici 4 commandes, 1=échec rebase, 2=stash, 3=rebase, 4=stash pop. quelque chose, mais la 3 est juste stupide de travail.
Donc, la question est: Quel est le plus recommandé de l'automatiser? un alias pour exécuter git stash/rebase/pop à chaque fois? certains git config que les forces de rebase pour ranger ou de le traiter comme un autre de s'engager à réappliquer après? quelque chose d'autre?
- Pourquoi voulez-vous fusionner ensuite rebase au lieu de simplement la relocalisation de l'obtenir-aller ?
- je l'ai mentionné sur le flux de travail tout simplement parce que la plupart du temps de fusion sera "rebase" depuis que j'ai la force ff-seulement... je peux probablement retirer que c'est sans importance. sur l'exemple, je l'ai laissée.
- Dans le cas où je écho Torek de réponse. S'engager ensuite rebase et le nettoyage après le fait en tant que de besoin.
- une question très semblable stackoverflow.com/questions/30208928/...
Vous devez vous connecter pour publier un commentaire.
Edit: Comme de Git version 1.8.4, mais avec un côté important correction d'un bug dans la version Git 2.0.1,
git rebase
a maintenant--autostash
. Vous pouvez configurergit rebase
à utiliser--autostash
par défaut ainsi, avecgit config --global rebase.autoStash true
. Veuillez noter que la phrase suivante à partir de la documentation:(Je préfère encore faire juste s'engage.)
TL;DR réponse: il suffit de faire un commit (puis défaire par la suite)
Il peut vous aider à réaliser ce
git stash
est vraiment justegit commit
(dans une forme plus compliquée, qui s'engage d'abord l'index, puis le travail-arbre—lorsque vous appliquez une cachette, vous pouvez maintenir la séparation de l'index et du travail de l'arbre, ou de les combiner en un arbre de changement).Ce qui rend une cachette spéciale est qui le commet fait—le deux ou, avec
-u
ou-a
, voire trois s'engage—sont réalisés dans une forme inhabituelle (comme une fusion de commettre ce n'est pas vraiment une fusion) et pas placé sur n'importe quelle branche (au lieu de cela, le spécialrefs/stash
de référence est utilisé pour conserver et de les trouver).Car ils ne sont pas sur une branche,
rebase
ne touche pas, et dans votre flux de travail, c'est lagit stash pop
qu'apporte le travail de l'arbre-changements dans votre nouveau travail-arbre. Cependant, si vous faites votre propre (normal) s'engagent, sur une branche, et rebase et comprennent que la commettre, en ce que c'est normal de commettre sera relocalisée, avec tous les autres. Nous allons arriver à un dernier problème en un instant; pour l'instant, mettons cela en place, comme une série de commits qui font (ou ne font pas) obtenir relocalisée:À ce point, voici ce que vous devez:
Ici,
A
,B
, etC
sont vos commits (je vais supposer que vous avez fait 3), tous sur la branchemaster
. Lei-w
accroché à commettreC
est votre cachette, ce qui n'est pas sur la branche, mais il est toujours un des deux commettre "git stash sac" et est réellement attaché à votre dernier commit (C
). Le@
s'engage (il pourrait être juste un) sont les nouvelles en amont s'engage.(Si vous l'avez pas s'engage, votre cachette-sac accroche à commettre
*
, et de votre branche points de commettre*
, de sorte quegit rebase
a pas de travail à faire d'autres que de déplacer votre branche courante du pointeur de l'avant. Tout fonctionne de la même manière, dans ce cas, mais je vais supposer il y a quelques révisions.)Maintenant vous exécutez
git rebase upstream/master
. Cette copie votre s'engage à nouveau s'engage, avec de nouveaux codes et de nouvelles parent Id, de sorte qu'ils se trouvent au sommet de la dernière@
. La cachette-sac ne bouge pas, de sorte que le résultat ressemble à ceci:Vous utilisez maintenant
git stash pop
, qui restaure le i/w trucs comme du travail-modifications apportées à l'arbre, l'effacement de lastash
étiquette (plus précisément, à éclater en sorte questash@{1}
, si elle existe, est maintenantstash
, et ainsi de suite). Qui libère les dernières références à l'originalA - B - C
de la chaîne, et signifie que nous n'avons pas besoin de lai-w
bits, ce qui nous permet de redessiner ce que le beaucoup plus simple:Maintenant, nous allons dessiner ce qui se passe si, au lieu de
git stash save
, vous venez de faire ungit commit -a
(ougit add
etgit commit
sans -a) afin de créer une réelle commettreD
. Vous commencez avec:Maintenant, vous
git rebase upstream/master
, dont des copiesA
parD
de les placer à la fin de la dernière@
, et vous avez ceci:Le seul problème, c'est que vous avez celui-ci indésirables supplémentaires commettre
D
(bien,D'
maintenant), au lieu de travail non validé-modifications apportées à l'arbre. Mais c'est carrément l'annuler avecgit reset
pour reculer d'un commit. On peut utiliser un--mixed
de réinitialisation: la valeur par défaut—pour obtenir l'index (zone de transit) re-trop, afin de "nations unies-ajouter" tous les fichiers, ou si vous souhaitez rester àgit add
-ed, un--soft
de réinitialisation. (Ne nuit ni à l'résultant commettre graphique, seul l'indice de l'état est différent.)Voici à quoi ça ressemble:
Vous pourriez penser que c'est inefficace, mais lorsque vous utilisez
git stash
vous êtes en train de faire au moins deux s'engage, qui vous puis de l'abandonner plus tard, quand vousgit stash pop
eux. La vraie différence c'est qu'en faisant temporaire, non-pour-la publication s'engage, vous obtenez ces automatiquement indexé.N'ayez pas peur de temporaire s'engage
Il y a une règle générale avec git: faire beaucoup de temporaire s'engage, pour enregistrer votre travail au fur et à mesure. Vous pouvez toujours rebase loin plus tard. C'est, au lieu de cela:
où
A
,B
, etC
sont parfaites et le final s'engage au sommet de commettre*
(de quelqu'un d'autre ou une version antérieure publiée trucs), faire ceci:où
a1
est un premier coup de couteau àA
,a2
correction d'un bogue dansa1
,b1
est une première tentative pour faireb
travail,a3
est de réaliser queb1
nécessiteA
être différent après tout,b2
correction d'un bogue dansb1
,a4
correction d'un bogue dansa3
's changement dea2
, etb3
est ce queb1
devrait avoir fait; puisc1
est une première tentative deC
,b4
est un correctif àb1
,c2
est un raffinement, et ainsi de suite.Disons qu'après
c3
vous pense que c'est surtout prêt. Maintenant vous exécutezgit rebase -i origin/master
ou que ce soit, mélangez lespick
lignes pour obtenira1
para4
dans l'ordre,b1
parb4
dans l'ordre, etc1
parc3
dans l'ordre, et de laisser le rebase exécuter. Alors vous résoudre tous les conflits et de s'assurer que ça en est encore à droite, puis vous exécutez une autregit rebase -i
à l'effondrement de toutes les quatrea
versions enA
, et ainsi de suite.Lorsque vous avez terminé, il semble comme vous avez créé un parfait
A
la première fois (ou peut-être aveca4
ou un autre en fonction de ce qui vous engage à garder et ceux que vous déposez et si vous re-régler toute heure dans les choses). D'autres personnes peuvent ne pas vouloir ou avoir besoin de voir votre travail intermédiaire—si vous pouvez le conserver, pas combinant s'engage, si c'est utile. Pendant ce temps vous n'avez jamais besoin d'avoir non validées de choses que vous devez rebase, parce que vous avez juste s'engage partielle des choses.Il aide à donner à ces commet noms, dans la ligne de commettre texte, qui servira de guide pour votre plus tard rebase travail:
et ainsi de suite.
git push
l'un d'entre eux et de laisser le reste. Est-ce possible?git cherry-pick
). En supposant que vous avez tout ce temp-commis,git checkout -b pushme upstream/master
pour créer une branche nomméepushme
, puisgit cherry-pick <commit-identifier>
à copier, puisgit push upstream pushme:master
pour pousser la un commit de la branche localepushme
en amontmaster
, par exemple. Une fois le push est terminée, vous pouvez rebase votre temp chaîne sur la nouvelle mise à jourupstream/master
(et omettre celle que vous avez copié, bien que cela le fera automatiquement si elle le peut).svn
pour votre commentaire! c'est un très bon flux de travail que j'ai toujours rejeté une trop compliqué, mais vous avez raison, c'est pratique.Une Réponse Simple:
git rebase -i --autosquash --autostash <tree-ish>
-i = interactively rebase
https://devdocs.io/git/git-rebase
Ce sera...
<tree-ish>
tree-ish
peut être un commettre hachage ou un nom de la branche ou un tag ou tout identifiant.Vous pouvez utiliser un des outils externes appelé git-up, qui fait exactement ce que vous dites pour toutes les branches. Ce sera également vous aider à garder propre histoire graphique.
J'ai utilisé pendant quelques années et il fonctionne très bien, surtout si vous n'êtes pas un git expert. Si vous ajoutez de l'auto-rebasage fonctionnalité, vous devez savoir comment bien récupérer l'échec de rebase (continuer, abandon, ...)
Installer
Ouvrir un shell et de l'exécution:
Configuration
Ouvrez votre fichier de configuration (
~/.gitconfig
), et ajoutez les éléments suivants:Voir le la documentation officielle pour plus d'options.
Invocation
Si tout est bien configuré, il suffit d'exécuter:
C'est (à peu près) l'équivalent de l'exécution des commandes suivantes:
git-up
seulement dans une séquence de "coffre-fort" porcellain commandes. Si quelque chose de "mauvais" vous arrive de finir dans un rebase conflit de fusion scénario: un simplegit rebase --abort
tout résoudre. Comme vous acquérir de la confiance et de la maîtrise de git, vous peu à peu le script inutile si.Le flux de travail entière dans une seule commande, y compris la récupération de:
Réponse de tjsingleton blogg
faire un alias de commandes de :
mise à jour
Si vous utilisez idée, en poussant avec un sale travail dir, il vous invite à une boîte de dialogue, choisissez rebase /fusion, il ne se planque, rebase /fusion et de la pop automatiquement.