Как я могу архивировать ветки 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
Я иногда архивирую ветки следующим образом:
- Создайте файлы исправлений, например,
format-patch <branchName> <firstHash>^..<lastHash>
(получите firstHash и lastHash, используя git log <branchName>
. - Переместите сгенерированные файлы исправлений в каталог на файловом сервере.
- Удалить ветку, например,
git branch -D <branchName>
"Примените" патч, когда вам нужно снова использовать ветку; однако применение файлов исправлений (см. git am
) может быть сложным в зависимости от состояния целевой ветки. С другой стороны, этот подход имеет то преимущество, что позволяет коммитам веток собирать мусор и экономить место в вашем репо.