Почему я могу оформить ветку, которая была удалена на GitHub?


26

В нашем репозитории GitHub сотрудник удалил ветку с именем release. Но когда я бегу git checkout releaseлокально, я всегда получаю удаленную ветку release. То же самое, даже когда я проверил другую ветку, удалил releaseветку с помощью git branch -D releaseи снова запустился git checkout release.

Что-то нужно исправить в репозитории GitHub, или я должен что-то исправить локально?


1
Что git branch --remoteвыводит, после запуска git fetch? Возможно, вам придется сократить, git fetch -pчтобы забыть удаленные ветви.
Стивен Китт

2
Если эта ветвь когда-либо была отправлена ​​на GitHub, и вы потянули ее после этого, то у вас также есть копия ветки. Каждый git-репозиторий самодостаточен, если только вы не использовали мелкий клон или что-то в этом роде.
Муру

@StephenKitt: Спасибо. git branch --remoteвывод origin/release. Вы хотите запустить git fetch -pбез дополнительных аргументов и удалит ли он все удаленные удаленные ветви?
Тим

1
Да, git fetch -pбез дополнительных аргументов удалит все удаленные удаленные ветки.
Стивен Китт

1
Добро пожаловать в мир распределенного контроля версий!
Хрилис - по забастовке -

Ответы:


24

После удаления ветви на удаленной стороне вы все еще можете увидеть эту ранее извлеченную удаленную ветку локально, см.

$ git branch -a
[...]
release
remotes/origin/release
[...]

Вы только удалили «релиз», но не «пульты / происхождение / релиз». Удалить это так:

$ git branch -rd origin/release

Или удалите все извлеченные ветви, которые больше не существуют на удаленной стороне:

$ git remote prune origin 

Спасибо. Во git branch -rd origin/releaseчто это -rзначит? Значит так -dже, как -D? Можно git branch -rd origin/releaseзаменить на git branch -d remotes/origin/release?
Тим

@Tim: из руководства; -r: List or delete (if used with -d) the remote-tracking branches.; -D:Shortcut for --delete --force.
петлитель

Спасибо. Можно git branch -rd origin/releaseзаменить на git branch -d remotes/origin/release?
Тим

@Tim no -rотносится к удаленным веткам, это необходимо. Локальные и удаленные филиалы хранятся в разных каталогах, сравниваются ls -l .git/refs/headsи ls -l .git/refs/remotes. Вы могли бы также иметь местное отделение под названием , remotes/origin/releaseкоторое было бы без удаления -r. Это может показаться странным, но вы можете просто поиграть, создать ветки со странными именами и посмотреть, как это выглядит .git/.
rudimeier

15

Когда ветки удаляются удаленно, вам нужно сократить локальный репозиторий - самый простой способ сделать это с

git fetch -p

Это обновит ваш локальный репозиторий со всеми изменениями, внесенными в удаленный репозиторий, но без обновления каких-либо локальных филиалов. После запуска этого,

git branch --remote

больше не будет показывать удаленную удаленную ветку.

git репозитории завершены, будь то в вашей собственной системе или на сервере. Поэтому, когда вы впервые клонируете репозиторий, вы получаете полную копию, и ваш локальный git «знает» обо всех удаленных филиалах, а также о ваших локальных филиалах. Эта информация не синхронизируется автоматически, поэтому, когда ваш коллега удалил releaseветку на сервере, ваш локальный git-репозиторий не потерял свое представление об удаленной releaseветке. Синхронизация с git fetchобновлениями всей локальной информации в удаленных ветвях, чтобы они соответствовали состоянию на сервере (строго говоря, удаленный репозиторий, где бы он ни находился), но без удаления какой-либо локальной информации в удаленных ветвях. Удаление с помощью git fetch -p(или git fetch --prune, или git remote prune) удаляет локальную информацию об удаленных ветвях, которые были удалены.


Спасибо. msgstr "обновить ваш локальный репозиторий со всеми изменениями, внесенными в удаленный репозиторий, но без обновления каких-либо локальных веток". Что это за обновление, учитывая, что это не обновление моих локальных филиалов?
Тим

Это все удаленные обновления. Ваш локальный репозиторий git различает ваши локальные ветки и удаленные ветки, но удаленные ветки магически не синхронизируются с сервером - они тоже существуют локально (например, хранятся в вашем локальном репозитории git). Извлечение синхронизирует ваш локальный репозиторий с удаленным репозиторием и обновляет состояние удаленных веток; по умолчанию удаленные удаленные ветви не удаляются из локальной информации об удаленных филиалах, -p( --prune) форсирует это.
Стивен Китт

Спасибо. Почему не удалили releaseветку git branch -D releaseдо git checkout releaseтого, как она git checkout releaseперестала получать releaseветку?
Тим

1
Потому git checkout releaseчто автоматически создаст ветку, если есть удаленная ветка с таким именем.
Стивен Китт

Под «удаленной веткой» вы подразумеваете ветку в моем локальном репозитории или Github? Если git branch -D releaseраньше, уже удалил releaseветку в моем локальном хранилище; В последнем случае сотрудник удалил releaseветку на GitHub; Так что я до сих пор не уверен, почему «будет автоматически воссоздавать ветку, если есть удаленная ветка с таким именем»?
Тим

3

Тим: Git - это распределенная VCS, поэтому, когда вы клонируете репозиторий с удаленного на локальный, он клонирует все (историю). Поэтому, когда вы клонировали свое репо, у него была ветка с названием release. Так как ваш коллега удалил ветку релиза удаленно, пока вы не git fetch -pудалите или не удалите эту ветвь явно, ваша локальная ветка будет иметь эту ветку.


3
Чем этот ответ отличается от уже имеющихся ответов?
Стивен Раух

1

Возможно, это немного косвенно, но перспектива этого сайта может помочь понять общую тему удаления веток:

http://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/

Есть некоторые совпадения с тем, что уже обсуждалось здесь, но основное внимание уделяется ведению домашнего хозяйства: удалению веток, удаленных и локальных, которые больше не нужны в среде совместной работы. В частности, git branch --mergedкоманда определяет ветви, которые можно безопасно удалить из-за слияния с вашей основной линией (или любой другой веткой, которая вас интересует). Если вы сотрудничаете, некоторые из таких мини-сценариев, как этот, представят вещи в хорошем, удобном для восприятия формате с датами и авторами.

for branch in `comm -12  <(git branch --merged|awk '{print($1)}') <(git branch -r --merged|awk '{print($1)}'|awk -F \/ '{print($2)}')`; do echo -e `git show --format="%ci %cr %an" $branch | head -n 1` \\t$branch; done | sort -r

(К сожалению, «хороший, легко усваиваемый» не относится к форматированию самих сценариев.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.