IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Un bon développeur est un développeur flemmard !

[Retour][Git]Du gestionnaire de source maison à Git

Noter ce billet
par , 04/11/2015 à 15h49 (944 Affichages)
Bonjour,

Dans ma mission actuelle, je fait partie d'une équipe qui maintient un logiciel qui a plus de 20 ans. Et sur ce logiciel la gestion des sources est maison.

Évidement depuis que je suis dans cette équipe, je rêve de retrouver git. Pour deux raisons principales :
  • Ne plus faire le repport de correction à la main
  • Avoir un historique des sources


Pour le moment, la situation est la suivante :
Sur un serveur distant, on a pour chaque version du logiciel un dossier contenant les sources. Via une application maison, on réserve et met à jour les différentes versions.
Mais ! Récemment, j'ai appris qu'à chaque fois qu'une personne met à jour les sources, l'application crée un zip contenant la nouvelles version des fichiers. Et cela avec un fichier texte contenant le descriptif de la fiche de livraison (le commentaire de commit).

De plus, pour initialiser une version, il est réalisé un zip de la version précédent !

Citation Envoyé par Sur le coup du ras-le-bol
Ça me soule, je vais tenter un truc !
Je vais me faire mon dépôt local. Importer tous ces zip pour avoir enfin un historique propre.
Au pire ça marche pas...
Pour cela, je me base principalement sur 4 commandes git :
Code bat : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
REM Commande d ajout de fichier
git add .
REM Commande de commit classique
git commit -m "Mon message de commit"
REM Commande pour changer la date du dernier commit
git commit --amend --date="2014-10-30 17:50:00 +0000" --no-edit
REM commande pour connaitre la date du dernier commit
git log -1 --format=%ad --date=iso

L'idée étant d'appliquer les ZIP de modifications un par un pour rejouer l'historique.Vue la taille de l'historique, je me suis écris un programme pour repasser l'historique d'un version :

Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
 
public class Patcher {
 
	/**
         * Emplacement du dépôt git
         */
	private static final String GIT_FOLDER = "C:\\DEPOT";
 
	/**
         * Emplacement des ZIP de delta
         */
	private static final String DELTA_FOLDER = "N:\\HISTORIQUE";
	/**
         * Taille du buffer pour copier les fichiers contenus dans le zip.
         */
	static final int BUFFER = 2048;
 
	public static void main(String[] args) throws Exception {
		File directory = new File(DELTA_FOLDER);
		File[] files = directory.listFiles();
 
		// Réalisation d'un premier filtre sur l'extention de fichier et la date du zip
		long timelimite = getLastCommitDate().getTime();
		Object[] tmp = Arrays.stream(files).filter(x -> x.getName().toLowerCase().endsWith(".zip"))
					.filter(x-> x.lastModified()> timelimite)
				.toArray();
		files = Arrays.copyOf(tmp, tmp.length, File[].class);
 
		// On trie les zip en fonction de la date pour les appliquer dans l'ordre.
		Arrays.sort(files, new Comparator<File>(){
		    public int compare(File f1, File f2)
		    {
		        return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
		    } });
		// Formater de date pour mettre à jour la date du commit à la date de création du zip
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
		File folder = new File(GIT_FOLDER);
		/* Pour chaque ZIP de modification 
		 * 1. Copie des fichiers dans le dépôt
		 * 2. Ajout des modifications au prochain commit
		 * 3. Si nécessaire commit + amend pour mettre à jour la date
		 */
		for (File file : files) {
			if(file.getName().toLowerCase().endsWith(".zip")){
				String ficheWithTrigramme = file.getName().replace(".zip", "").replace(".ZIP", "");
				System.out.println("Traitement de la fiche => "+ficheWithTrigramme);
				handleFicheZip(file);
 
				Runtime rt = Runtime.getRuntime();
				String message = getMessageFiche(ficheWithTrigramme);
				System.out.println("Adding to git");
				rt.exec("git add .",null, folder).waitFor();
 
				if(isCommitNeeded() ){
					Thread.sleep(200);
					System.out.println("git commit -m \""+file.getName()+": "+message+"\"");
					rt.exec("git commit -m \""+file.getName()+": "+message+"\"",null, folder).waitFor();
					Thread.sleep(200);
					rt.exec("git commit --amend --date=\""+df.format(new Date(file.lastModified()))+"\" --no-edit",null, folder).waitFor();
				}
				Thread.sleep(1000);
			}
		}
	}
 
	private static boolean isCommitNeeded() throws IOException {
		File folder = new File(GIT_FOLDER);
		Runtime rt = Runtime.getRuntime();
		Process proc = rt.exec("git status",null, folder);
 
		BufferedReader stdInput = new BufferedReader(new 
			     InputStreamReader(proc.getInputStream()));
 
		String s = null;
		while ((s = stdInput.readLine()) != null) {
		    System.out.println(s);
		    if(s.contains("nothing to commit, working directory clean")){
		    	return false;
		    }
		}
		return true;
	}
 
 
	private static String getMessageFiche(String fiche) throws IOException {
		BufferedReader buff = new BufferedReader(new FileReader(DELTA_FOLDER+File.separator+fiche+".txt"));
		String line = buff.readLine();
		buff.close();
		// On échappe les " pour ne pas avoir de problème lors du commit !
		return line.replace("\"", "\\\"");
	}
 
 
	private static void handleFicheZip(File file) throws IOException {
		ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
		ZipEntry ze = zis.getNextEntry();
		File folder = new File(GIT_FOLDER);
		while (ze != null) {
			// It's a client file / folder
			if (ze.getName().contains("DEVPART")) {
				System.out.println(ze.getName());
				String relativeName = ze.getName().split("DEVPART")[1];
				// On crée les répertoires parents si nécessaire !
				new File(folder.getAbsoluteFile() + File.separator + relativeName).getParentFile().mkdirs();
				FileOutputStream fos = new FileOutputStream(
						folder.getAbsoluteFile() + File.separator + relativeName);
				BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
				byte data[] = new byte[BUFFER];
				int count;
				while ((count = zis.read(data, 0, BUFFER)) != -1) {
					dest.write(data, 0, count);
				}
				dest.close();
				fos.close();
			}
 
			ze = zis.getNextEntry();
		}
		zis.close();
	}
 
	private static Date getLastCommitDate() throws Exception {
		File folder = new File(GIT_FOLDER);
		Runtime rt = Runtime.getRuntime();
		Process proc = rt.exec("git log -1 --format=%ad --date=iso",null, folder);
 
		BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
		return toDate(stdInput.readLine());
	}
 
	/** Transform ISO 8601 string to Calendar. */
    public static Date toDate(final String iso8601string)
            throws ParseException {
        String s = iso8601string.substring(0, 18);
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s);
        return date;
    }
 
}

Le tout fonctionne proprement ! J'ai maintenant 3 ans d'historique, 566 commit avec les commentaires :

Nom : Git_tree_historique.png
Affichages : 120
Taille : 445,6 Ko

L'historique n'est pas parfait. Par exemple, je n'ai pas changé la date des commit pour l’initialisation des différents branches.
Cependant, je n'aurai plus à rechercher pendant des jours qui a fait quel modification ou ce qui a été changé depuis qu'on a livrer le client X ou Y ! Et surtout, certains de mes collègues ne pourront plus me sortir "Oui, mais c'est toi qui y à touché en dernier !", parce que... J'ai modifié le contenu d'une pop-up !
Je ne me fait pas d’illusion, le gestionnaire maison restera là... Trop d'outils d'intégration basé dessus. Mais, c'est déjà ça !

Enfin, je voulais partager avec vous, avoir votre avis... Et on sait jamais peut-être que cela pourra aider une autre personne.

Cordialement,
Patrick Kolodziejczyk.

Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Viadeo Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Twitter Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Google Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Facebook Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Digg Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Delicious Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog MySpace Envoyer le billet « [Retour][Git]Du gestionnaire de source maison à Git » dans le blog Yahoo

Mis à jour 24/04/2016 à 21h57 par LittleWhite (Coloration code)

Tags: git, java, retour
Catégories
Sans catégorie

Commentaires

  1. Avatar de stendhal666
    • |
    • permalink
    Merci pour ce billet que je découvre un peu tard!
    Juste une réflexion: pour un gestionnaire de versions à la main créé il y a vingt ans, il était tout de même drôlement bien fait puisque tu as pu retrouver presque toutes les infos pertinentes en quelques dizaines de lignes de Java (d'ailleurs, pour moi qui ne suis pas un fan de ce langage, je dois tout de même tirer mon chapeau en voyant tout ce qu'on peut faire en restant dans la bibliothèque standard). Dommage tout de même que tu n'aies pas essayé de proposer un passage à Git, puisque tu n'étais plus très loin d'une conversion complète quand tu as fait ton repo perso.