Comment écraser l'intégralité de votre référentiel jusqu'au premier commit?
Je peux rebaser au premier commit, mais cela me laisserait avec 2 commits. Existe-t-il un moyen de référencer le commit avant le premier?
git
rebase
git-rebase
squash
git-rewrite-history
Verhogen
la source
la source
--root
n'est-ce pas la meilleure solution pour écraser toutes les validations s'il y en a beaucoup à écraser): combiner les deux premières validations d'un référentiel Git? .Réponses:
Le moyen le plus simple est peut-être de créer simplement un nouveau référentiel avec l'état actuel de la copie de travail. Si vous souhaitez conserver tous les messages de validation, vous pouvez d'abord le faire
git log > original.log
, puis le modifier pour votre message de validation initial dans le nouveau référentiel:ou
la source
git rebase -i --root
. Voir: stackoverflow.com/a/9254257/109618Depuis git 1.6.2 , vous pouvez utiliser
git rebase --root -i
.Pour chaque commit sauf le premier, passez
pick
àsquash
.la source
squash
pour toutes les validations . Le tout premier doit êtrepick
.Mise à jour
J'ai fait un alias
git squash-all
.Exemple d' utilisation :
git squash-all "a brand new start"
.Attention : n'oubliez pas de fournir un commentaire, sinon le message de validation par défaut "Un nouveau départ" serait utilisé.
Ou vous pouvez créer l'alias avec la commande suivante:
Bon mot
Remarque : ici "
A new start
" n'est qu'un exemple, n'hésitez pas à utiliser votre propre langue.TL; DR
Pas besoin de squash, utilisez
git commit-tree
pour créer un commit orphelin et allez-y.Explique
créer un seul commit via
git commit-tree
Qu'est
git commit-tree HEAD^{tree} -m "A new start"
- ce que c'est:L'expression
HEAD^{tree}
signifie l'objet arbre correspondant àHEAD
, à savoir la pointe de votre branche actuelle. voir Tree-Objects et Commit-Objects .réinitialiser la branche actuelle au nouveau commit
Ensuite,
git reset
réinitialisez simplement la branche actuelle sur l'objet de validation nouvellement créé.De cette façon, rien dans l'espace de travail n'est touché, ni besoin de rebase / squash, ce qui le rend vraiment rapide. Et le temps nécessaire n'est pas pertinent pour la taille du référentiel ou la profondeur de l'historique.
Variation: nouveau référentiel à partir d'un modèle de projet
Cela est utile pour créer le "commit initial" dans un nouveau projet en utilisant un autre référentiel comme modèle / archétype / graine / squelette. Par exemple:
Cela évite d'ajouter le référentiel de modèles en tant que distant (
origin
ou autre) et réduit l'historique du référentiel de modèles dans votre validation initiale.la source
git push -f
pour la propagation.git clone
. Si vous ajoutez--hard
àgit reset
et basculezHEAD
avecFETCH_HEAD
dans le,git commit-tree
vous pouvez créer un commit initial après avoir récupéré le référentiel de modèle. J'ai édité la réponse avec une section à la fin démontrant cela.${1?Please enter a message}
Si tout ce que vous voulez faire, c'est écraser toutes vos validations vers la racine, alors tout
peut fonctionner, il n'est pas pratique pour un grand nombre de validations (par exemple, des centaines de validations), car l'opération de rebase s'exécutera probablement très lentement pour générer la liste de validation de l'éditeur de rebase interactif, ainsi que pour exécuter la rebase elle-même.
Voici deux solutions plus rapides et plus efficaces lorsque vous écrasez un grand nombre de commits:
Solution alternative n ° 1: les branches orphelines
Vous pouvez simplement créer une nouvelle branche orpheline à la pointe (c'est-à-dire la validation la plus récente) de votre branche actuelle. Cette branche orpheline forme la validation racine initiale d'une arborescence d'historique de validation entièrement nouvelle et distincte, ce qui équivaut à écraser toutes vos validations:
Documentation:
Solution alternative # 2: réinitialisation logicielle
Une autre solution efficace consiste à simplement utiliser une réinitialisation mixte ou logicielle du commit racine
<root>
:Documentation:
la source
git push origin master --force
.git push --force
Cela va créer un commit orphelin avec l'arborescence de HEAD, et afficher son nom (SHA-1) sur stdout. Ensuite, réinitialisez simplement votre succursale.
la source
git reset $(git commit-tree HEAD^{tree} -m "commit message")
le rendrait plus facile.echo "message" | git commit-tree "HEAD^{tree}"
Voici comment j'ai fini par le faire, juste au cas où cela fonctionnerait pour quelqu'un d'autre:
N'oubliez pas qu'il y a toujours un risque à faire des choses comme ça, et ce n'est jamais une mauvaise idée de créer une branche de sauvegarde avant de commencer.
Commencez par vous connecter
Faites défiler jusqu'au premier commit, copiez SHA
Remplacer
<#sha#>
avec le SHA copié à partir du journalAssurez-vous que tout est vert, sinon exécutez
git add -A
Modifier toutes les modifications actuelles au premier commit actuel
Maintenant, forcez à pousser cette branche et elle écrasera ce qui s'y trouve.
la source
J'ai lu quelque chose sur l'utilisation des greffes, mais je n'ai jamais beaucoup étudié la question.
Quoi qu'il en soit, vous pouvez écraser manuellement les 2 derniers commits avec quelque chose comme ceci:
la source
La façon la plus simple est d'utiliser la commande 'plomberie'
update-ref
pour supprimer la branche actuelle.Vous ne pouvez pas utiliser
git branch -D
car il a une soupape de sécurité pour vous empêcher de supprimer la branche actuelle.Cela vous remet dans l'état «commit initial» où vous pouvez commencer avec un nouveau commit initial.
la source
Tout d'abord, écrasez toutes vos validations en une seule validation en utilisant
git rebase --interactive
. Il vous reste maintenant deux commits de squash. Pour ce faire, lisezla source
En une ligne de 6 mots
la source
git help checkout
sujet--orphan
git help checkout --orphan
créer une sauvegarde
réinitialiser au commit spécifié
puis ajoutez tous les fichiers à la mise en scène
valider sans mettre à jour le message
pousser une nouvelle branche avec des engagements écrasés pour repo
la source
<root>
commit # 1 sera le commit sur lequel vous avez réinitialisé.git commit --amend --no-edit
va valider toutes les modifications apportées à la validation actuelle,<root>
sans avoir à modifier le message de validation.Pour écraser à l'aide de greffes
Ajouter un fichier
.git/info/grafts
, mettez là le hash de commit que vous voulez devenir votre rootgit log
va maintenant commencer à partir de ce commitPour en faire une course «réelle»
git filter-branch
la source
Cette réponse améliore un couple ci-dessus (veuillez les voter), en supposant qu'en plus de créer le seul commit (pas de parents, pas d'historique), vous souhaitez également conserver toutes les données de commit de ce commit:
Bien sûr, le commit-SHA du nouveau / single commit changera, car il représente un nouvel (non) historique, devenant un parentless / root-commit.
Cela peut être fait en lisant
git log
et en définissant certaines variables pourgit commit-tree
. En supposant que vous souhaitez créer un seul commit à partirmaster
d'une nouvelle brancheone-commit
, en conservant les données de commit ci-dessus:la source
Pour ce faire, vous pouvez réinitialiser votre référentiel git local au premier hashtag de validation, de sorte que toutes vos modifications après cette validation ne seront pas mises en scène, puis vous pourrez valider avec l'option --amend.
Modifiez ensuite le premier nom de validation si nécessaire et enregistrez le fichier.
la source
Pour moi, cela a fonctionné comme ceci: j'ai eu 4 commits au total et j'ai utilisé un rebase interactif:
Le tout premier commit reste et j'ai pris 3 derniers commits.
Dans le cas où vous êtes coincé dans l'éditeur qui apparaît ensuite, vous voyez smth comme:
Vous devez d'abord valider et écraser les autres dessus. Ce que vous devriez avoir, c'est:
Pour cela, utilisez la touche INSERT pour changer le mode 'insert' et 'edit'.
Pour enregistrer et quitter l'éditeur, utilisez
:wq
. Si votre curseur se trouve entre ces lignes de validation ou ailleurs, appuyez sur ÉCHAP et réessayez.En conséquence, j'ai eu deux commits: le tout premier qui est resté et le second avec le message "Ceci est une combinaison de 3 commits.".
Vérifiez les détails ici: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit
la source
Je le fais habituellement comme ceci:
Assurez-vous que tout est validé et notez le dernier ID de validation en cas de problème, ou créez une branche distincte comme sauvegarde
Exécutez
git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`
pour réinitialiser votre tête au premier commit, mais laissez votre index inchangé. Toutes les modifications depuis le premier commit apparaîtront maintenant prêtes à être validées.Exécutez
git commit --amend -m "initial commit"
pour modifier votre commit sur le premier commit et modifier le message de commit, ou si vous souhaitez conserver le message de commit existant, vous pouvez exécutergit commit --amend --no-edit
Courez
git push -f
pour forcer à pousser vos changementsla source