Maison > Article > interface Web > Travailler avec Merge dans Git
Dans le blog de cette semaine, je souhaite partager mes réflexions et mon expérience après avoir terminé mon atelier sur le travail avec git merge.
Après avoir terminé un récent laboratoire axé sur l'utilisation de Git, j'ai acquis une compréhension plus approfondie des deux principales stratégies de fusion utilisées par Git : les fusions à avance rapide et récursive à trois voies (récursive-ort).
Fusion rapide : cela se produit lorsque la branche principale n'a pas de nouveaux commits depuis la création de la branche de fonctionnalités. Dans ce scénario, Git déplace simplement le pointeur de la branche principale vers la dernière validation de la branche de fonctionnalités. Ce type de fusion ne crée pas de validation de fusion distincte, ce qui la rend simple et linéaire.
Fusion récursive à 3 voies : cette approche est utilisée lorsque la branche principale et la branche de fonctionnalités ont des validations divergentes. Git calcule un ancêtre commun et tente de fusionner les modifications des deux branches. Des conflits peuvent survenir si des modifications ont été apportées aux mêmes lignes ou fichiers dans les deux branches, nécessitant une résolution manuelle. Au départ, j'avais l'impression que des conflits surviendraient toujours lors de la modification du même fichier dans différentes branches. Cependant, les conflits ne se produisent que lorsque la même ligne de code est modifiée dans les deux branches.
Pour cet atelier, j'ai travaillé sur l'ajout de deux fonctionnalités à mon référentiel, VShell, ce qui impliquait la création de branches distinctes pour chaque fonctionnalité. Ces fonctionnalités ont été conçues pour améliorer les fonctionnalités de l'outil en prenant en charge plusieurs fichiers/dossiers d'entrée et une sortie en streaming.
La première fonctionnalité consistait à permettre à l'outil de traiter simultanément plusieurs fichiers et chemins de dossiers. Auparavant, l'outil ne gérait que les entrées de fichiers individuels, mais avec cette amélioration, les utilisateurs peuvent désormais transmettre plusieurs fichiers ou répertoires comme arguments. Tous les fichiers contenus dans les répertoires sont traités.
Pour implémenter cela, j'ai étendu la logique existante pour parcourir de manière récursive le contenu des dossiers, en convertissant les chemins de fichiers en chemins absolus et en stockant tous les fichiers pertinents dans un tableau. L'extrait pertinent :
files.forEach((file) => { // convert a file path to an absolute path const filePath = path.resolve(file); ... const directoryFiles = fs .readdirSync(filePath) .map((f) => path.join(filePath, f)); allFiles = allFiles.concat(directoryFiles); ... const results = allFiles.map((file) => { process.stderr.write(`Debug: Processing file: ${file}. \n`); return fs.readFileSync(file, "utf-8"); }); return results.join("\n"); }
Ce code garantit que les fichiers individuels et tous les fichiers des répertoires sont traités en conséquence.
La deuxième fonctionnalité a ajouté la prise en charge du streaming à l'outil, permettant la sortie en temps réel des réponses sur la sortie standard à l'aide de l'indicateur -s/--stream. Il s'agit d'une amélioration significative par rapport à l'implémentation précédente, où les réponses n'étaient écrites que dans un fichier de sortie ou affichées dans leur intégralité une fois le traitement terminé.
Pour y parvenir, j'ai introduit l'itération asynchrone en utilisant la boucle for wait...of pour gérer les morceaux de données au fur et à mesure de leur diffusion. De plus, j'ai suivi l'utilisation des jetons en temps réel, car les informations sur les jetons ne sont disponibles que dans le bloc de réponse final. Voici la logique de base :
if (options.stream) { // Handle streaming response const { response, tokenInfo } = await readStream(chatCompletion); return { response, tokenInfo }; }
async function readStream(stream) { let response = ""; let tokenInfo; for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content; if (content) { process.stdout.write(content); response += content; } // The last chunk will contain the usage information if (chunk?.x_groq?.usage) { // Retrieve Token Usage from Response const usage = chunk?.x_groq?.usage; const promptToken = usage?.prompt_tokens || 0; const completionToken = usage?.completion_tokens || 0; const totalToken = usage?.total_tokens || 0; tokenInfo = { promptToken, completionToken, totalToken }; } } return { response, tokenInfo }; }
L'approche de diffusion en temps réel a nécessité des ajustements dans le suivi des jetons, par opposition à la méthode plus simple utilisée pour les réponses non diffusées, où les données d'utilisation sont accessibles directement.
Pour le streaming, l'objet d'utilisation du jeton n'est accessible qu'après avoir traité le dernier morceau de la boucle.
// The last chunk will contain the usage information if (chunk?.x_groq?.usage) { // Retrieve Token Usage from Response const usage = chunk?.x_groq?.usage; ... }
Par défaut, lors de l'utilisation de l'indicateur -s/--stream sans spécifier de fichier de sortie via -o/--output, la réponse sera diffusée et affichée dans la console en temps réel. Cependant, si l'utilisateur souhaite exporter la réponse dans un fichier, il peut spécifier le fichier de sortie à l'aide de l'indicateur -o/--output.
Après avoir terminé les deux fonctionnalités, j'ai lancé le processus de fusion, en commençant par fusionner la fonctionnalité 1 dans la branche principale, suivie de la fonctionnalité 2. Étant donné que les fonctionnalités ont été développées dans des fichiers séparés, aucun conflit ne s'est produit pendant le processus de fusion. Cependant, Git a utilisé la stratégie de fusion ORT (Ostensously Recursive's Twin), qui est la stratégie par défaut à partir de Git 2.34. La stratégie ORT est une réécriture de la stratégie de fusion récursive classique, offrant de meilleures performances et précision dans la gestion de scénarios de fusion complexes.
Mon hachage final de validation de fusion était : 286e23c
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!