Как я могу архивировать ветки git?

У меня есть несколько старых ветвей в моем репозитории git, которые больше не находятся в активной разработке. Я хотел бы архивировать ветки так, чтобы они не отображались по умолчанию при запуске git branch -l -r. Я не хочу их удалять, потому что хочу сохранить историю. Как я могу это сделать?

Я знаю, что можно создать ref за пределами refs/heads. Например, refs/archive/old_branch. Есть ли последствия этого?

Ответ 1

Я считаю, что правильный способ сделать это - пометить ветку. Если вы удалите ветку после того, как вы отметили ее, вы эффективно сохранили ветвь, но она не будет загромождать список ветвей.

Если вам нужно вернуться в ветку, просто проверьте тег. Он эффективно восстановит ветку из тега.

Для архивирования и удаления ветки:

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

Чтобы восстановить ветвь спустя некоторое время:

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

История ветки будет сохранена точно так же, как и когда вы отметили ее.

Ответ 2

Ответ Джереми в принципе правильный, но IMHO команды, которые он задает, не совсем правильные.

Здесь, как архивировать ветку в тег без необходимости проверять ветку (и, следовательно, без необходимости проверки на другую ветку, прежде чем вы сможете удалить эту ветку):

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

А вот как восстановить ветку:

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

Ответ 3

Вы можете архивировать ветки в другом репозитории. Не совсем так элегантно, но я бы сказал, что это жизнеспособная альтернатива.

git push git://yourthing.com/myproject-archive-branches.git yourbranch
git branch -d yourbranch

Ответ 4

Да, вы можете создать ссылку с нестандартным префиксом, используя git update-ref. (например, git update-ref refs/archive/old-topic your-commit)

В отличие от обычных веток или тегов, эти ссылки не будут отображаться в обычной git branch git log git tag (хотя вы можете увидеть их с помощью git log --all или git for-each-ref как git log --all ниже).

Создание ссылки имеет некоторые преимущества перед простым копированием SHA1. SHA1 достаточно на короткий срок, но коммиты без каких-либо ссылок будут GC'd через 3 месяца (или пару недель без рефлога), не говоря уже о ручном git gc --prune. Коммиты с рефами безопасны от GC.

Я использую следующие псевдонимы:

[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

Кроме того, вы можете настроить удаленные функции, такие как push = +refs/archive/*:refs/archive/* для автоматической push = +refs/archive/*:refs/archive/* (или git push origin refs/archive/*:refs/archive/* для одноразового использования).

Редактировать: нашел реализацию perl той же идеи от @ap: git-attic attic

Редактировать ^ 2: нашел сообщение в блоге, где сам Гитстер использовал ту же технику.

Ответ 5

Расширение Steve answer, чтобы отразить изменения на пульте дистанционного управления, я сделал

 git tag archive/<branchname> <branchname>
 git branch -D <branchname>
 git branch -d -r origin/<branchname>
 git push --tags
 git push origin :<branchname>

Для восстановления с удаленного устройства см. этот вопрос.

Ответ 6

Вот псевдоним для этого:

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

Добавьте его так:

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

Помните, что есть команда git archive, поэтому вы не можете использовать archive в качестве псевдонима.

Также вы можете определить псевдоним, чтобы просмотреть список "архивных" ветвей:

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

о добавлении псевдонимов

Ответ 7

Я использую следующие псевдонимы, чтобы скрыть архивные ветки:

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

So git br, чтобы показать активно развитые ветки и git bra, чтобы показать все ветки, включая "архивные".

Ответ 8

Я бы не архивировал ветки. Иными словами, архивы веток. Вы хотите, чтобы информация, относящаяся к археологам, была найдена надежными средствами. Надежность в том, что они помогают повседневной разработке и не добавляют дополнительного шага к процессу выполнения работы. То есть, я не верю, что люди не захотят добавить тег, когда они закончили с веткой.

Вот два простых шага, которые значительно помогут археологии и развитию.

Что это. Зачем? Потому что, как археолог кода, я редко начинаю с того, что хочу знать, какая работа была выполнена в филиале. Гораздо чаще это почему во всех кричащих девяти адах код написан таким образом?! Мне нужно сменить код, но у него есть некоторые необычные функции, и мне нужно их разгадать, чтобы не сломать что-то важно.

Следующим шагом является git blame, чтобы найти связанные коммиты, а затем надеюсь, что сообщение журнала объяснимо. Если мне нужно копать глубже, я выясню, была ли работа выполнена в ветке и прочитала ветку в целом (вместе со своим комментарием в трекере проблем).

Скажем, git blame указывает на фиксацию XYZ. Я открываю браузер истории Git (gitk, GitX, git log --decorate --graph и т.д.), Нахожу фиксацию XYZ и вижу...

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

Там моя ветка! Я знаю, что QQ, UU, XYZ, JJ и MM являются частью одной ветки, и я должен посмотреть их сообщения журнала для деталей. Я знаю, что GG будет слиянием и будет иметь имя ветки, которая, надеюсь, связана с проблемой в трекере.

Если по какой-то причине я хочу найти старую ветку, я могу запустить git log и искать имя ветки в транзакции слияния. Это достаточно быстро даже на очень больших хранилищах.

Вот что я имею в виду, когда говорю, что ветки архивы сами.

Пометка каждой ветки добавляет ненужную работу для достижения цели (критический процесс, который должен быть беспощадно обтекаемым), десны вверх по списку тэгов (не говоря о производительности, но читаемость для человека) с сотнями тегов, которые очень редко полезны, и даже не очень полезен для археологии.

Ответ 9

Мой подход заключается в том, чтобы переименовать все ветки, которые меня не интересуют, с префиксом trash_, а затем использовать:

git branch | grep -v trash

(с привязкой ключа оболочки)

Чтобы сохранить окраску активной ветки, потребуется:

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

Ответ 10

Вы можете использовать script, который будет архивировать ветку для вас

archbranch

Он создает тэг для вас с префиксом archive/, а затем удаляет ветвь. Но проверьте код, прежде чем использовать его.


Использование - $/your/location/of/script/archbranch [branchname] [defaultbranch]

Если вы хотите запустить script, не записывая местоположение, добавьте его в свой путь

Затем вы можете называть его

$ archbranch [branchname] [defaultbranch]

[defaultbranch] - это ветвь, к которой он будет обращаться, когда выполняется архивирование. Есть некоторые проблемы с цветовым кодированием, но другие, что он должен работать. Я использую его в проектах в течение длительного времени, но он все еще находится в разработке.

Ответ 11

Я иногда архивирую ветки следующим образом:

  1. Создайте файлы исправлений, например, format-patch <branchName> <firstHash>^..<lastHash> (получите firstHash и lastHash, используя git log <branchName>.
  2. Переместите сгенерированные файлы исправлений в каталог на файловом сервере.
  3. Удалить ветку, например, git branch -D <branchName>

"Примените" патч, когда вам нужно снова использовать ветку; однако применение файлов исправлений (см. git am) может быть сложным в зависимости от состояния целевой ветки. С другой стороны, этот подход имеет то преимущество, что позволяет коммитам веток собирать мусор и экономить место в вашем репо.