diff --git a/app/models/communication/website/git_file.rb b/app/models/communication/website/git_file.rb
index 99993d0e5b72ce8fcc5c8fe2258f3f41b6227288..0f414e31fab00a776f9593ba2cde9deb34f369da 100644
--- a/app/models/communication/website/git_file.rb
+++ b/app/models/communication/website/git_file.rb
@@ -59,13 +59,13 @@ class Communication::Website::GitFile < ApplicationRecord
   end
 
   def path
-    about.send "git_path_#{identifier}"
+    @path ||= about.send "git_path_#{identifier}"
   end
 
   def sha
     # Git SHA-1 is calculated from the String "blob <length>\x00<contents>"
     # Source: https://alblue.bandlem.com/2011/08/git-tip-of-week-objects.html
-    OpenSSL::Digest::SHA1.hexdigest "blob #{to_s.bytesize}\x00#{to_s}"
+    @sha ||= OpenSSL::Digest::SHA1.hexdigest "blob #{to_s.bytesize}\x00#{to_s}"
   end
 
   def to_s
diff --git a/app/models/concerns/with_git.rb b/app/models/concerns/with_git.rb
index 5d505ed0033e01e1d1e373ba84f8c671a5b764ca..981a0b1022ac4e0762adb29d6bb1016316f45e32 100644
--- a/app/models/concerns/with_git.rb
+++ b/app/models/concerns/with_git.rb
@@ -8,7 +8,6 @@ module WithGit
               dependent: :destroy
   end
 
-  # Needs override
   def git_path_static
     raise NotImplementedError
   end
@@ -34,39 +33,38 @@ module WithGit
   def destroy_and_sync
     destroy_from_git
     destroy
-    true
   end
 
-  def destroy_from_git
-    websites_with_fallback.each do |website|
+  def sync_with_git
+    websites_for_self.each do |website|
       identifiers(website: website).each do |identifier|
-        Communication::Website::GitFile.sync website, self, identifier, destroy: true
-        dependencies = send "git_destroy_dependencies_#{identifier}"
+        Communication::Website::GitFile.sync website, self, identifier
+        dependencies = send "git_dependencies_#{identifier}"
         dependencies.each do |object|
-          Communication::Website::GitFile.sync website, object, identifier, destroy: true
+          Communication::Website::GitFile.sync website, object, identifier
         end
       end
       website.git_repository.sync!
     end
   end
+  handle_asynchronously :sync_with_git
 
-  def sync_with_git
-    websites_with_fallback.each do |website|
+  def destroy_from_git
+    websites_for_self.each do |website|
       identifiers(website: website).each do |identifier|
-        Communication::Website::GitFile.sync website, self, identifier
-        dependencies = send "git_dependencies_#{identifier}"
+        Communication::Website::GitFile.sync website, self, identifier, destroy: true
+        dependencies = send "git_destroy_dependencies_#{identifier}"
         dependencies.each do |object|
-          Communication::Website::GitFile.sync website, object, identifier
+          Communication::Website::GitFile.sync website, object, identifier, destroy: true
         end
       end
       website.git_repository.sync!
     end
   end
-  handle_asynchronously :sync_with_git
 
   protected
 
-  def websites_with_fallback
+  def websites_for_self
     if is_a? Communication::Website
       [self]
     elsif respond_to?(:websites)
diff --git a/app/models/concerns/with_media.rb b/app/models/concerns/with_media.rb
index 30f0b3cd7b80f5f9e7326b3f9aea986eca203873..0387cea3f40962723fd814f21045392b71ffe565 100644
--- a/app/models/concerns/with_media.rb
+++ b/app/models/concerns/with_media.rb
@@ -13,6 +13,13 @@ module WithMedia
     blobs_with_ids [best_featured_image]
   end
 
+  # Can be overwrite to get featured_image from associated objects (ex: parents)
+  def best_featured_image(fallback: true)
+    featured_image
+  end
+
+  protected
+
   def rich_text_reflection_names
     @rich_text_reflection_names ||= _reflections.select { |name, reflection| reflection.class_name == "ActionText::RichText" }.keys
   end
@@ -23,13 +30,6 @@ module WithMedia
     }.flatten
   end
 
-  # Can be overwrite to get featured_image from associated objects (ex: parents)
-  def best_featured_image(fallback: true)
-    featured_image
-  end
-
-  protected
-
   def blobs_with_ids(ids)
     university.active_storage_blobs.where(id: ids.flatten.compact)
   end
diff --git a/app/models/education/program.rb b/app/models/education/program.rb
index 81a5f9a3684272dfefa9ec29c0b883fcd211e092..8a873afe20ff49eedb95a733d060185bfb4897d8 100644
--- a/app/models/education/program.rb
+++ b/app/models/education/program.rb
@@ -111,6 +111,10 @@ class Education::Program < ApplicationRecord
     active_storage_blobs
   end
 
+  def git_destroy_dependencies_static
+    explicit_active_storage_blobs
+  end
+
   def update_children_paths
     children.each do |child|
       child.update_column :path, child.generated_path
diff --git a/app/services/git/repository.rb b/app/services/git/repository.rb
index 00d92847acfcd751a550f272147947d703d53b95..ca126526acd714e91ed4aa74ce670748c0a43a15 100644
--- a/app/services/git/repository.rb
+++ b/app/services/git/repository.rb
@@ -25,7 +25,7 @@ class Git::Repository
 
   protected
 
-  # TODO add gitlab
+  # Enhancement add gitlab
   def provider
     @provider ||= Git::Providers::Github.new(website&.access_token, website&.repository)
   end
@@ -48,7 +48,7 @@ class Git::Repository
 
   def mark_as_synced
     git_files.each do |git_file|
-      git_file.update_columns previous_path: sanitized_path(git_file.path), previous_sha: git_file.sha
+      git_file.update previous_path: sanitized_path(git_file.path), previous_sha: git_file.sha
     end
   end
 
diff --git a/app/views/admin/communication/websites/static.html.erb b/app/views/admin/communication/websites/static.html.erb
index b35a0af7b690453e82bb7c08246805543c8d66d7..db284ce5d7dc0923aa7f892e92620021f3746d3f 100644
--- a/app/views/admin/communication/websites/static.html.erb
+++ b/app/views/admin/communication/websites/static.html.erb
@@ -1,17 +1,2 @@
 title: >
   <%= @website.to_s %>
-<% if @website.about_school? %>
-school:
-  name: >
-    <%= @website.about.to_s %>
-  address: >
-    <%= @website.about.address %>
-  zipcode: >
-    <%= @website.about.zipcode %>
-  city: >
-    <%= @website.about.city %>
-  country: >
-    <%= @website.about.country %>
-  phone: >
-    <%= @website.about.phone %>
-<% end %>
diff --git a/docs/websites/export.md b/docs/websites/export.md
index be773adafc5a324a54c4f6fe02e47ed817972711..5f0b61974f450f1637bce05eed426f9bb89897a1 100644
--- a/docs/websites/export.md
+++ b/docs/websites/export.md
@@ -44,7 +44,7 @@ Lors de l'enregistrement d'un objet, il faut, pour chaque website :
             - push
             - mettre à jour les previous_path et les SHA des git_files
 
-Ce flux cause un problème majeur : tout ce qui est analysé disparaît en asynchrone
+Ce flux cause un problème majeur : tout ce qui est analysé disparaît en asynchrone.
 
 ### Version 2
 
@@ -76,8 +76,6 @@ def reorder
   pages.first.sync_with_git
 end
 ```
-TODO vérifier que tous les cas de déplacement sont correctement gérés.
-TODO gérer la suppression correctement.
 
 ## Code
 
@@ -89,17 +87,19 @@ Le website a un trait WithRepository qui gère son rapport avec le repository Gi
 
 Tous les objets qui doivent être exportés vers Git :
 - doivent utiliser le concern `WithGit`, qui gère l'export vers les repositories des objets et de leurs dépendances
-- doivent présenter une méthode `websites`, éventuellement avec un seul website dans un tableau
 - peuvent intégrer le concern `WithMedia` s'il utilise des médias (`featured_image` et/ou images dans des rich texts)
-- peuvent présenter une méthode `static_files` qui liste les identifiants des git_files à générer, pour les objets qui créent plusieurs fichiers
+- peuvent présenter une méthode `identifiers` qui liste les identifiants des git_files à générer, pour les objets qui créent plusieurs fichiers (le fichier par défaut s'appelle `static`)
+- peuvent présenter une méthode `git_dependencies_static` qui liste les dépendances de l'identifiant par défaut `static`
+- peuvent présenter une méthode `git_destroy_dependencies_static` qui liste les dépendances à supprimer en cascade de l'identifiant par défaut `static`
+- peuvent présenter des méthodes `git_dependencies_author` et/ou `git_destroy_dependencies_author` qui liste les dépendances de l'identifiant `author`
 
-### GitFile
+### Modèle Communication::Website::GitFile
 
 La responsabilité de la synchronisation repose sur Communication::Website::GitFile, notamment :
 - l'information est-elle intègre, synchronisée avec le repo ? (previous_sha et previous_path cohérents avec le repo git)
-- le fichier doit-il être créé ? (non intègre, ou pas de previous_sha/previous_path)
-- le fichier doit-il être mis à jour ? (non intègre, ou previous_sha/previous_path différent du sha/path)
-- le fichier doit-il être supprimé ? (TODO)
+- le fichier doit-il être créé ? (pas à supprimer et (non intègre, ou pas de previous_sha/previous_path))
+- le fichier doit-il être mis à jour ? (pas à supprimer et (non intègre, ou previous_sha/previous_path différent du sha/path))
+- le fichier doit-il être supprimé ? (path nil ou marquage à détruire)
 
 
 Pour cela, le git_file dispose des propriétés suivantes :