Ce que vous voulez est - git filter-branch
, qui peuvent se déplacer d'un ensemble de référentiel dans une sous-arborescence, la préservation de l'histoire en faisant croire que si elle l'a toujours été. Sauvegarder votre dépôt avant d'utiliser ce!
Voici la magie. En /foo/bar
, exécutez:
git filter-branch --commit-filter '
TREE="$1";
shift;
SUBTREE=`echo -e 040000 tree $TREE"\tbar" | git mktree`
git commit-tree $SUBTREE "$@"' -- --all
Que va faire l' /foo/bar
respository avoir un autre", le " bar du sous-répertoire avec l'ensemble de son contenu tout au long de toute l'histoire. Vous pouvez ensuite déplacer l'ensemble de pensions jusqu'à l' foo
niveau et ajouter baz
code.
Mise à jour:
Bon, voilà ce qu'il se passe. Un commit est un lien vers un "arbre" (pensez-y comme un SHA représentant un ensemble de système de fichiers sous-répertoire de contenu) et de certaines "parent" SHA et certaines métadonnées lien auteur/message/etc. L' git commit-tree
de commande est le faible niveau des bits qui enveloppe tout cela ensemble. Le paramètre --commit-filter
se fait traiter comme une fonction shell et les exécuter à la place de git commit-tree
pendant le processus de filtrage, et a à agir comme il.
Ce que je fais est de prendre le premier paramètre -- l'origine de l'arbre de commettre -- et de construire un nouvel "objet de l'arborescence" qui indique que c'est dans un sous-dossier par git mktree
, un autre bas-niveau de la commande git. Pour ce faire, j'ai des tuyaux en elle quelque chose qui ressemble à un arbre git -- un ensemble de (mode SP SP SHA ONGLET nom de fichier) lignes; ainsi, la commande echo. La sortie de l' mktree
remplace alors le premier paramètre quand j'ai de la chaîne du réel commit-tree
; "$@"
est un moyen de passer tous les autres paramètres intact, ayant dépouillé le premier sur avec shift
. Voir git help mktree
et git help commit-tree
pour l'info.
Donc, si vous avez besoin de plusieurs niveaux, vous devez nid à quelques niveaux supplémentaires, des objets de l'arborescence (ce n'est pas testé mais l'idée générale):
git filter-branch --commit-filter '
TREE="$1"
shift
SUBTREE1=`echo -e 040000 tree $TREE"\tbar" | git mktree`
SUBTREE2=`echo -e 040000 tree $SUBTREE1"\tb" | git mktree`
SUBTREE3=`echo -e 040000 tree $SUBTREE2"\ta" | git mktree`
git commit-tree $SUBTREE3 "$@"' -- --all
Qui devrait passer au contenu réel vers le bas en a/b/bar
(noter l'inversion de l'ordre).
Mise à jour: Intégré des améliorations De Matthieu Alpert de réponse ci-dessous. Sans -- --all
cela ne fonctionne que sur les extraits de la branche, mais puisque la question se pose à propos de l'ensemble de pensions, il est plus logique de le faire de cette façon que la succursale par ranch.