Почему Git разрешил мне создать две ветки с тем же именем?
Я по-прежнему относительно новичок в Git, и я немного испортил свой репозиторий. Я надеюсь, что есть способ исправить это без повторного клонирования.
У меня есть репозиторий, который я клонировал из Github. В репозитории имеется несколько веток. Некоторое время я работал над ведущей веткой, но затем мне нужно было переключиться на одну из других ветвей.
Итак, у меня было:
$ git branch --all
* master
remotes/origin/abc
remotes/origin/def
remotes/origin/HEAD -> origin/master
remotes/origin/ghi
Проблема: Я хотел переключиться на ветвь 'abc', но вместо git checkout remotes/origin/abc
я случайно сделал git branch remotes/origin/abc
, который оставил меня со следующим:
$ git branch --all
* master
remotes/origin/abc
remotes/origin/abc
remotes/origin/def
remotes/origin/HEAD -> origin/master
remotes/origin/ghi
Мои вопросы:
- Почему на Земле Git позволяет создавать две ветки с одинаковыми
имя?
- Как определить, какова реальная ветвь пультов/источник/abc?
- Как удалить нежелательные удаленные файлы /origin/abc, которые я создал
авария?
Любая помощь очень ценится.
Ответы
Ответ 1
Вы не можете создать две локальные ветки или две отдаленные ветки с тем же именем.
-
Здесь у вас есть локальная ветвь с именем remotes/origin/abc
и удаленная ветвь с именем abc
на пульте дистанционного управления origin
. Они не имеют одинакового имени, но, похоже, вы используете команду git branch --all
.
-
Чтобы определить, какая ветвь есть, вы можете показать локальные ветки с помощью git branch
или показать удаленные ветки с помощью git branch --remote
. Вы также можете легко отличить их даже при использовании git branch --all
с окраской синтаксиса ветвей (git config --global color.branch auto
).
-
Чтобы удалить случайно созданную локальную ветвь abc
, вы должны сделать git branch -d abc
(или git branch -d abc
для принудительного удаления, см. man git-branch
).
Ответ 2
Истинная история состоит в том, что Git имеет схему упрощения для своих "refs" (a Git lingo для "ссылок", которая является термином, используемым для обозначения ветвей, тегов и т.д.). Фактически, ссылки живут в своих пространствах имен, которые с помощью ссылки Git являются просто каталогами под .git
. Например, ваш локальный филиал "master" действительно "refs/heads/master" — файл с именем "master", расположенный в каталоге .git/refs/heads
. Существуют также пространство имен "refs/tags" и пространство имен "refs/remotes" — для тегов и удаленных ветвей (созданных командой git fetch
).
Теперь, когда вы сообщаете Git создать ветку remotes/origin/abc
, она действительно создает refs/heads/remotes/origin/abc
, которая не сталкивается с refs/remotes/origin/abc
, потому что правила для работы с этой схемой упрощения делают прежний козырь последним. В любое время вы можете использовать полную форму именования для удаления любых значений.
Очерки о том, как Git интерпретирует имена ссылок, описаны в разделе "Указание ревизий" руководства git-rev-parse
:
<refname> мастер, головки/мастер, refs/heads/master
Символическое имя ссылки. Например. master обычно означает объект фиксации, на который ссылаются refs/heads/master. Если у вас есть обе головки/мастер и теги/мастер, вы можете явно сказать головам/мастерам, чтобы сказать Git, что вы имеете в виду. При двусмысленности, <refname> устраняется путем принятия первого совпадения в следующих правилах:
Если $GIT_DIR/<refname> существует, что вы имеете в виду (обычно это полезно только для HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD и CHERRY_PICK_HEAD);
в противном случае, refs/<refname> если он существует;
в противном случае, refs/tags/<refname> если он существует;
иначе, refs/heads/<refname> если он существует;
иначе, refs/remotes/<refname> если он существует;
в противном случае refs/remotes/<refname> /HEAD, если он существует.
& hellip;
Ответ 3
Git помещает очень мало ограничений на имена ветвей и, например, слэши в названиях веток отлично. Также удаление ветки на пульте дистанционного управления выполняется, например,
$ git push origin :abc
при удалении локальной ветки, например,
$ git branch -d remotes/origin/abc
где нет двусмысленности, поскольку эти два объекта живут в разных пространствах имен.
Ответ 4
Используйте gitk
или gitk --all
для проверки ветвей. Там вы можете видеть локальные и удаленные ветки разного цвета. И создавайте, проверяйте, удаляйте локальные ветки с легкостью и без двусмысленности, просто щелкая правой кнопкой мыши по ним.
Для удаленных ветвей отслеживания вы можете использовать git gui
, создать меню ветки, просто выбрать удаленную ветку и соответствующую идею локального наименования. Таким образом, это довольно сложно испортить.
Что касается первого вопроса: вы не можете создавать ветки с тем же именем, но подобное синтетическое имя может произойти, если вы будете бороться за него. С помощью правильных инструментов они не путаются, поэтому нет причин запрещать сценарий.