J'ai un dépôt git dont la structure ressemble à:
+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+webapp
|
+---------+manage.py
+---------+modules
+---------+templates
+---------+static
+---------+...
+---------+...
Je voudrais déplacer le contenu du dossier webapp
d'un niveau vers le haut. Mon repo résultant devrait ressembler à:
+--repo.git
|
+----+bootstrap.py
+----+buildout.cfg
+----+.gitignore
+----+manage.py
+----+modules
+----+templates
+----+static
+----+...
+----+...
Puis-je le faire en déplaçant simplement tous les fichiers du répertoire webapp
d'un niveau vers le haut, en supprimant le répertoire vide webapp
puis en validant les modifications? Cela conserverait-il l'historique de validation des fichiers dans le répertoire webapp
?
Bien qu'il s'agisse d'une question très simple pour beaucoup d'entre vous, j'aimerais en être sûr. La dernière chose que je voudrais, c'est une soupe au git.
J'ai essayé de déplacer les fichiers mais j'ai perdu l'historique des validations car git ne gère pas vraiment un déplacement ou un renommage. Je sais que même s'il apparaît en tant que nouveau fichier dans les journaux, il est toujours possible d'afficher l'historique de validation du fichier en utilisant certaines options dans git log
.
D'après ce que j'ai lu, la meilleure façon d'y parvenir serait d'utiliser git-filter
. Je ne suis pas très bon avec Shell ou git, alors quelqu'un pourrait-il me dire ce que je devrais exécuter pour faire ce qui précède.
Je viens de le faire, et c'est assez simple en fait. La bonne façon de le faire est -
git mv repo.git/webapp/* repo.git/.
et alors
git rm repo.git/webapp
suivi d'un
git add *
git commit -m "Folders moved out of webapp directory :-)"
Une autre variante de la réponse de Sumeet - dans le répertoire du référentiel au-dessus de "webapp", exécutez la commande suivante:
git mv webapp/* ./ -k
-k - inclut des fichiers qui ne sont pas encore sous contrôle de version, sinon vous obtenez:
fatal: not under version control, source=webapp/somefile, destination=somefile
La solution que vous avez mentionnée devrait fonctionner, car git suit les modifications en fonction du hachage des fichiers d'abord, puis de leur emplacement.
Cela ne fonctionnera pas si dans le cadre du déplacement du fichier, vous modifiez le contenu des fichiers.
En bas, essayez-le, et si cela ne fonctionne pas, vous pouvez annuler les modifications, avant de pousser les modifications dans le référentiel maître :). C'est l'une des raisons pour lesquelles j'aime vraiment git.
J'ai oublié de mentionner que pour voir les changements après un changement de nom, vous devez utiliser le paramètre '--follow'. Vérifiez cet exemple
Tout d'abord, j'ai créé un nouveau dépôt git
94:workspace augusto$ mkdir gittest
94:workspace augusto$ cd gittest/
94:gittest augusto$ git init
Initialized empty Git repository in /Volumes/Data/dev/workspace/gittest/.git/
Puis créé un fichier dans dossier/test
94:gittest augusto$ mkdir folder
94:gittest augusto$ vi folder/test
94:gittest augusto$ git add folder/test
94:gittest augusto$ git commit -am "added file"
[master (root-commit) 7128f82] added file
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 folder/test
Ensuite, déplacé le fichier vers nouveau dossier/test
94:gittest augusto$ mkdir newfolder
94:gittest augusto$ mv folder/test newfolder/
94:gittest augusto$ git add newfolder/test
94:gittest augusto$ git commit -am "moved/renamed file"
[master 4da41f5] moved/renamed file
1 files changed, 0 insertions(+), 0 deletions(-)
rename {folder => newfolder}/test (100%)
Et git log --follow newfolder/test
affiche l'historique complet (j'ai ajouté le paramètre -p pour afficher plus d'informations, comme le chemin d'accès).
94:gittest augusto$ git log --follow -p newfolder/test
commit 4da41f5868ab12146e11820d9813e5a2ac29a591
Author: Augusto Rodriguez <[email protected]>
Date: Sat Aug 20 18:20:37 2011 +0100
moved/renamed file
diff --git a/folder/test b/newfolder/test
similarity index 100%
rename from folder/test
rename to newfolder/test
commit 7128f8232be45fd76616f88d7e164a840e1917d5
Author: Augusto Rodriguez <[email protected]>
Date: Sat Aug 20 18:19:58 2011 +0100
added file
diff --git a/folder/test b/folder/test
new file mode 100644
index 0000000..3b2aed8
--- /dev/null
+++ b/folder/test
@@ -0,0 +1 @@
+this is a new file
J'espère que ça aide!
dans les fenêtres, vous pouvez faire ce qui suit:
Pendant que vous êtes dans le dossier enfant
for /f %f in ('dir /b') do git mv %f ../
Le résultat tous les objets dans le dossier enfant seront dans le dossier parent
Veuillez noter: certaines erreurs peuvent survenir lorsque vous avez un objet dans le dossier enfant avec un nom égal au dossier enfant
Si vous utilisez PowerShell, vous pouvez exécuter cette commande à partir de la racine de votre projet et elle y placera le contenu de la webapp.
Get-ChildItem .\webapp\ | ForEach-Object { git mv $_.FullName .\ }
Oui, vous pouvez simplement déplacer les fichiers. Cependant, vous devez dire à git que les anciens fichiers du dossier webapp ont disparu, c'est-à-dire que git doit mettre à jour son index des fichiers finis/validés.
Vous pouvez donc utiliser git add -A .
pour faire remarquer à git toutes les modifications, ou utilisez le git mv <files>
pour dire à git de faire le mouvement lui-même. Voir la page de manuel de git mv .
--mise à jour.
Vous avez remarqué que vous pensiez ".. git ne gère pas vraiment un mouvement ou un renommage .." - J'étais aussi confus au début et je n'avais pas complètement compris le fonctionnement de l'Index. D'une part, les gens disent que git ne prend que des instantanés et ne suit pas les renommages, mais vous obtenez alors un échec si vous mettez à jour .gitignore
, ou mv
un fichier, etc. Cet "échec" est une confusion sur le fonctionnement de l'index.
Ma visualisation est que la zone Index/Staging est un endroit, comme un mur de storyboard, où vous placez une copie de votre dernier et meilleur fichier "fini", y compris son chemin, (en utilisant git add
), et c'est cette copie qui est validée. Si vous ne retirez pas cette copie du mur du story-board (c'est-à-dire git rm
), alors git continuera à le valider, et la confusion abondera (voir de nombreuses questions SO ...). L'index est également utilisé par git pendant merge
s dans un manière similaire
J'ai pu le faire fonctionner simplement en faisant cela depuis le dossier de destination:
git mv webapp/* .
Il semble que cela ne fonctionne pas dans le shell Windows (échoue avec une erreur Bad source
), mais cela fonctionnera fonctionnera sous Windows si vous utilisez le Git Bash Shell, qui étend le *
caractère générique.
Oui, git suivra les modifications du contenu passé. Il utilise des hachages du contenu du fichier, donc quel que soit leur emplacement dans la structure de répertoires, ce sera le même fichier.
Par conséquent, vous devez effectuer le déplacement dans une validation, puis corriger toutes les modifications dans une validation ultérieure. Cela permettra à Git de déterminer la redirection avec une efficacité maximale et ne fera aucune différence dans la quantité de données stockées dans le référentiel (puisque vous feriez ces modifications de toute façon).
Sous Windows, en utilisant Bash, les éléments suivants ont fonctionné:
git mv /c/REPO_FOLDER/X_FOLDER/Y_FOLDER/Z_FOLDER/* /c/REPO_FOLDER/X_FOLDER/Y_FOLDER