283 votes

Insérer un commit avant la validation de la racine dans Git?

J'ai demandé avant sur la façon de squash les deux premiers s'engage dans un dépôt git.

Alors que les solutions sont plutôt intéressantes, et pas vraiment l'esprit de déformation que quelques autres choses dans git, ils sont quand même un peu de la proverbiale sac de mal si vous avez besoin de répéter la procédure plusieurs fois au long du développement de votre projet.

Donc, je préfère passer par la douleur qu'une seule fois, et ensuite être capable de toujours utiliser la norme rebase interactif.

Ce que je veux faire, c'est d'avoir un vide initial de commettre ce qui existe uniquement dans le but d'être le premier. Pas de code, pas de rien. Juste en prenant de l'espace de sorte qu'il peut être la base pour rebase.

Ma question est alors, d'avoir un référentiel existant, comment dois-je aller sur l'insertion d'un nouveau, vide s'engager avant le premier, et le déplacement, tout le monde avant?

396voto

Aristotle Pagaltzis Points 43253

Voici un nettoyeur de mise en œuvre de la même solution, en ce qu'elle fonctionne sans avoir besoin de créer un dépôt supplémentaire, futz autour avec des télécommandes, et de corriger d'un décollement de la tête:

# first you need a new empty branch; let's call it `newroot`
git checkout --orphan newroot
git rm -rf .

# then you apply the same steps
git commit --allow-empty -m 'root commit'
git rebase --onto newroot --root master
git branch -d newroot

Voila, vous avez fini sur master avec son histoire réécrite de façon à inclure une racine vide commettre.


NB.: sur les anciennes versions de Git qui manque l' --orphan commutateur checkout, vous avez besoin de la plomberie pour créer un vide branche:

git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d

36voto

Antony Hatchkins Points 5831

Fusion des réponses d'Aristote Pagaltzis et d'Uwe Kleine-König et du commentaire de Richard Bronosky.

 git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d
# touch .gitignore && git add .gitignore # if necessary
git commit --allow-empty -m 'initial'
git rebase --onto newroot --root master
git branch -d newroot
 

(juste pour mettre tout en un seul endroit)

12voto

Kent Points 304

J'ai, comme dit Aristote. Mais trouve que pour un grand dépôt (>5000 engage les) filter-branch fonctionne mieux que cela pour plusieurs raisons 1) c'est plus rapide 2) il ne nécessite pas l'intervention de l'homme quand il y a un conflit de fusion. 3) on peut réécrire les balises -- les préserver. Notez que filter-branch fonctionne car il n'y a pas de question sur le contenu de chaque commit -- c'est exactement le même qu'avant cette "rebase'.

Mes étapes sont les suivantes:

# first you need a new empty branch; let's call it `newroot`
git symbolic-ref HEAD refs/heads/newroot
git rm --cached -r .
git clean -f -d

# then you apply the same steps
git commit --allow-empty -m 'root commit'

# then use filter-branch to rebase everything on newroot
git filter-branch --parent-filter 'sed "s/^\$/-p <sha of newroot>/"' --tag-name-filter cat master

Notez que le '--tag-name-filtre de chat", les options, les balises seront réécrits à point pour le nouvellement créé s'engage.

4voto

Uwe Kleine-König Points 1020

git rebase --root --onto $emptyrootcommit

devrait faire le tour facilement

2voto

kch Points 25855

Eh bien, voici ce que j'ai trouvé:

 # Just setting variables on top for clarity.
# Set this to the path to your original repository.
ORIGINAL_REPO=/path/to/original/repository

# Create a new repository…
mkdir fun
cd fun
git init
# …and add an initial empty commit to it
git commit --allow-empty -m "The first evil."

# Add the original repository as a remote
git remote add previous $ORIGINAL_REPO
git fetch previous

# Get the hash for the first commit in the original repository
FIRST=`git log previous/master --pretty=format:%H  --reverse | head -1`
# Cherry-pick it
git cherry-pick $FIRST
# Then rebase the remainder of the original branch on top of the newly 
# cherry-picked, previously first commit, which is happily the second 
# on this branch, right after the empty one.
git rebase --onto master master previous/master

# rebase --onto leaves your head detached, I don't really know why)
# So now you overwrite your master branch with the newly rebased tree.
# You're now kinda done.
git branch -f master
git checkout master
# But do clean up: remove the remote, you don't need it anymore
git remote rm previous
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X