Éditer l'histoire sans la réécrire
Parfois vous voulez épisser des histoires (un import Subversion converti rencontrant une continuation, par exemple) sans réécrire les commits. Les grafts et l'espace de noms refs/replace/ permettent à Git de prétendre que le parent d'un commit est un autre commit, laissant les objets originaux intacts.
Grafts (legacy)
# .git/info/grafts
<child-sha> <new-parent-sha>
Replace refs
git replace --graft <child> <new-parent>
git replace --graft v3.0.0 v2.99.0
git replace --convert-graft-file
git replace -d <sha>
git replace -l
Cas d'usage : épisser des imports
git replace --graft $(git rev-list --max-parents=0 main | head -1) svn-history-tip
Partage
git push origin 'refs/replace/*:refs/replace/*'
Désactivation temporaire
git --no-replace-objects log
GIT_NO_REPLACE_OBJECTS=1 git log
Erreurs courantes
Confondre replace avec réécriture — replace ne change pas les SHAs d'objet, donc les signatures restent valides.