web-dev-qa-db-fra.com

Comment puis-je archiver des branches git?

J'ai quelques vieilles branches dans mon dépôt git qui ne sont plus en développement actif. J'aimerais archiver les branches afin qu'elles ne s'affichent pas par défaut lors de l'exécution de git branch -l -r. Je ne veux pas les supprimer, parce que je veux conserver l'historique. Comment puis-je faire ceci?

Je sais qu'il est possible de créer une référence en dehors de références/têtes. Par exemple, réfs/archive/old_branch. Y at-il des conséquences à cela?

238
dan-manges

Je crois que la bonne façon de faire est de marquer la branche. Si vous supprimez la branche après l'avoir étiquetée, la branche est conservée, mais elle n'encombrera pas votre liste de branches.

Si vous avez besoin de retourner à la succursale, vérifiez simplement l'étiquette. Cela restaurera effectivement la branche à partir de la balise.

Pour archiver et supprimer la branche:

git tag archive/<branchname> <branchname>
git branch -d <branchname>

Pour restaurer la branche un peu plus tard:

git checkout -b <branchname> archive/<branchname>

L'historique de la branche sera conservé exactement tel qu'il était lorsque vous l'avez marqué.

314
Jeremy Wall

La réponse de Jeremy est correcte en principe, mais à mon humble avis, les commandes qu'il a spécifiées ne sont pas tout à fait correctes. 

Voici comment archiver une branche dans une balise sans avoir à extraire la branche (et donc sans avoir à extraire une autre branche avant de pouvoir supprimer cette branche):

> git tag archive/<branchname> <branchname>
> git branch -D <branchname>

Et voici comment restaurer une branche:

> git checkout -b <branchname> archive/<branchname>
99
Steve

Vous pouvez archiver les branches dans un autre référentiel. Pas aussi élégant, mais je dirais que c'est une alternative viable.

git Push git://yourthing.com/myproject-archive-branches.git yourbranch
git branch -d yourbranch
17
August Lilleaas

Oui, vous pouvez créer une référence avec un préfixe non standard en utilisant git update-ref . (par exemple, git update-ref refs/archive/old-topic topic)

Contrairement aux branches ou aux étiquettes normales, ces références n'apparaîtront pas dans les codes git branch, git log et git tag habituels (vous pourrez les voir avec git log --all).

Créer une référence présente certains avantages par rapport à la simple copie de SHA1. SHA1 est suffisant pour le court terme, mais commet sans aucune référence sera GC'd après 3 mois (ou quelques semaines sans refonte) , encore moins manuel git gc --Prune. Les commits avec les références sont à l'abri de GC.

J'utilise les alias suivants:

[alias]
    archive-ref = "!git update-ref refs/archive/$(date '+%Y%m%d-%s')"
    list-archive-ref = for-each-ref --sort=-authordate --format='%(refname) %(objectname:short) %(contents:subject)' refs/archive/
    rem = !git archive-ref
    lsrem = !git list-archive-ref

En outre, vous souhaiterez peut-être configurer des télécommandes telles que Push = +refs/archive/*:refs/archive/* sur Push automatiquement (ou git Push Origin refs/archive/*:refs/archive/* pour one-shot).

Edit: Trouvé une implémentation Perl de la même idée par @ap : git-attic

Edit ^ 2: Trouvé un article de blog où Gitster utilise lui-même la même technique.

14
snipsnipsnip

Étendre le answer de Steve pour refléter les changements sur la télécommande

 git tag archive/<branchname> <branchname>
 git branch -D <branchname>
 git branch -d -r Origin/<branchname>
 git Push --tags
 git Push Origin :<branchname>

Pour restaurer depuis la télécommande, voir cette question .

10
Liam

Voici un alias pour ça:

arc    = "! f() { git tag archive/$1 $1 && git branch -D $1;}; f"

Ajoutez le comme ceci:

git config --global alias.arc '! f() { git tag archive/$1 $1 && git branch -D $1;}; f'

N'oubliez pas qu'il existe déjà une commande git archive, vous ne pouvez donc pas utiliser archive comme nom d'alias.

Vous pouvez également définir un alias pour afficher la liste des branches 'archivées':

arcl   = "! f() { git tag | grep '^archive/';}; f"

sur l'ajout d'alias

8
Alexey

J'utilise les alias suivants pour masquer les branches archivées:

[alias]
    br = branch --no-merge master # show only branches not merged into master
    bra = branch                  # show all branches

Donc git br pour afficher les branches développées activement et git bra pour afficher toutes les branches, y compris "archivées" ones.

5
Pitr

Mon approche est de renommer toutes les branches qui ne me dérangent pas avec un préfixe "trash_", puis utilisez:

git branch | grep -v trash

(avec une liaison clé Shell)

Pour conserver la coloration de la branche active, il faudrait:

git branch --color=always | grep --color=never --invert-match trash
2
Sridhar-Sarnobat

Je n'archiverais pas les branches. En d'autres termes, les branches archivent elles-mêmes. Ce que vous voulez, c'est que les informations pertinentes pour les archéologues puissent être trouvées par des moyens fiables. Fiables dans la mesure où ils facilitent le développement quotidien et n’ajoutent pas d’étape supplémentaire au processus d’exécution du travail. C'est-à-dire que je ne crois pas que les gens se souviendront d'ajouter une étiquette une fois qu'ils ont terminé avec une branche.

Voici deux étapes simples qui aideront grandement le développement de l'archéologie et.

  1. Liez chaque branche de tâche à un problème associé dans le suivi des problèmes en utilisant une convention de dénomination simple .
  2. Utilisez toujours git merge --no-ff pour fusionner les branches de tâches. vous voulez cette validation de fusion et cette bulle historique, même pour une seule validation.

C'est tout. Pourquoi? En tant qu'archéologue de code, je commence rarement par vouloir savoir quel travail a été effectué sur une branche. Beaucoup plus souvent c'est pourquoi dans tous les neuf enfers qui crient, le code est-il écrit de cette façon?! J'ai besoin de changer de code, mais il a des fonctionnalités étranges, et je dois les résoudre pour éviter de casser quelque chose d'important.

La prochaine étape est git blame pour rechercher les validations associées et espérer que le message de journalisation est explicatif. Si j'ai besoin de creuser plus profondément, je vais vérifier si le travail a été effectué dans une branche et lire la branche dans son ensemble (avec son commentaire dans le suivi des problèmes).

Disons git blame points au commit XYZ. J'ouvre un navigateur d'historique Git (gitk, GitX, git log --decorate --graph, etc ...), trouve commit XYZ et vois ...

AA - BB - CC - DD - EE - FF - GG - II ...
     \                       /
      QQ - UU - XYZ - JJ - MM

Voilà ma branche! Je sais que QQ, UU, XYZ, JJ et MM font tous partie de la même branche et je devrais consulter leurs messages de journal pour plus de détails. Je sais que GG sera un commit de fusion et portera le nom de la branche qui, espérons-le, est associée à un problème dans l'outil de suivi.

Si, pour une raison quelconque, je souhaite rechercher une ancienne branche, je peux exécuter git log et rechercher le nom de la branche dans la validation de fusion. Il est assez rapide même sur de très grands dépôts.

C'est ce que je veux dire quand je dis que les archives des branches elles-mêmes.

Le balisage de chaque branche ajoute un travail inutile à la réalisation de tâches (processus critique qui devrait être simplifié sans ménagement), gomme la liste des balises (sans parler de performance, mais de lisibilité humaine) avec des centaines de balises qui ne sont que très occasionnellement utiles et qui t même très utile pour l'archéologie.

2
Schwern

Vous pouvez utiliser un script qui archivera la branche pour vous. 

archbranch

Il crée une balise pour vous avec le préfixe archive/puis supprime la branche. Mais vérifiez le code avant de l'utiliser.


Utilisation - $/your/location/of/script/archbranch [branchname] [defaultbranch]

Si vous voulez exécuter le script sans écrire l'emplacement, ajoutez-le à votre chemin.

Ensuite, vous pouvez l'appeler par

$ archbranch [branchname] [defaultbranch]

Le [defaultbranch] est la branche à laquelle il ira lorsque l'archivage sera terminé. Il y a quelques problèmes avec le code de couleur mais d'autres que cela devrait fonctionner. Je l'utilise depuis longtemps dans des projets, mais il est encore en développement.

1
Banezaka

J'archive parfois des branches comme suit:

  1. Générez des fichiers de correctif, par exemple, format-patch <branchName> <firstHash>^..<lastHash> (obtenez firstHash et lastHash en utilisant git log <branchName>.
  2. Déplacez les fichiers de correctif générés dans un répertoire sur un serveur de fichiers.
  3. Supprimer la branche, par exemple, git branch -D <branchName>

"Appliquer" le correctif lorsque vous devez utiliser la branche à nouveau. Toutefois, l'application des fichiers de correctif (voir git am) peut être difficile en fonction de l'état de la branche cible. Sur le plan positif, cette approche présente l’avantage de permettre aux commits de la branche d’être récupérés et d’économiser de l’espace dans votre rapport. 

0
Bill Hoag