Nano Hash - криптовалюты, майнинг, программирование

git: ветки, которые не похожи на ветки

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

git branch -a говорит:

  dashboard
* master
  php7
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/php7

Итак, он говорит, что у меня есть две ветки, кроме master: dashboard и php7. Я хорошо помню php7 — это был большой кусок работы с множеством коммитов. Я не помню dashboard, но имя говорит мне, к какому файлу это относится.

git branch --merged говорит:

  dashboard
* master
  php7

Так что, видимо, оба объединены. Но php7 известен удаленно, а dashboard - нет. Я не помню, какие команды git я сделал, чтобы добраться до этого момента.

Когда я смотрю на журнал в PHPStorm (или с git log --graph), эти два не выглядят так, как я ожидал бы от ветки - на ней нет отведенной строки с коммитами. Вот самый последний раздел журнала: введите здесь описание изображения

Загадки (по крайней мере для меня):

  • Все коммиты, которые я делал в ветке php7, находятся на той же оранжевой линии, что и master. Если я объединил, а затем удалил ветку (логично), почему она вообще все еще указана как ветка?
  • Почему в конце ветки php7 есть дополнительная метка «происхождение»? Я бы подумал, что недавние нажатия заставят удаленный сервер выглядеть так же, как локальный, только с одной меткой «происхождение» в последнем коммите. Конечно, удаленный не считает php7 еще не объединенным - это было бы ужасно, поскольку этот код имеет решающее значение.
  • dashboard удаленно вообще не известен (https://github.com/OsakaWebbie/kizunadb) - как это могло быть?

С другой стороны, ранее в логе была очень очевидная ветка, которая имела два коммита, а затем была слита, которой нет в списке веток: введите здесь описание изображения Я был бы рад удаляю (старые ветки не храню из-за ностальгии), но git branch -d texlabels говорит: error: branch 'texlabels' not found. Самое ветвистое на вид в логе не ветка? У меня болит голова.

Я уверен, что вы, гуру git, сразу поймете, что все это значит и как это убрать — жду ясности.

Обновлять:

Спасибо Ката за исчерпывающий ответ (весьма вероятно, что он будет принят). Но у меня есть несколько дополнительных вопросов, которые было бы трудно прочитать в крошечном комментарии (я бы хотел, чтобы комментарии были длиннее и имели больше форматирования), так что потерпите меня немного дольше. Я думаю, на них можно ответить либо комментарием, либо добавлением Ката к своему ответу - все, что работает.

Потому что не уверен, что в прошлом php7 был объединен с мастером.

Если нет уверенности, что php7 был объединен, почему он указан в --merged? (Меня беспокоит мысль о том, что git «неуверен» в чем-либо...) Я понятия не имею, как переместить голову ветки позже, так что этот сценарий маловероятен. Однако было время, когда я сделал что-то локально, из-за чего Github отказался от отправки (я думаю, что мог изменить файлы в уже отправленную фиксацию) — кто-то еще помог мне просмотреть это, и в итоге я сделал push -f (я' м единственный застройщик). Возможно, это привело к тому, что указатель сместился...

В любом случае, я знаю, что код php7 является частью моей текущей кодовой базы, потому что теперь он успешно работает на PHP7. И я признаю, что несколько коммитов были сделаны в этой ветке. На самом деле, возможно, что все коммиты с момента создания php7 до момента слияния (46 коммитов) были сделаны в этой ветке (т. е. без возврата к мастеру для исправления ошибок). Объясняет ли это, почему в DAG нет дополнительной строки рядом с главной строкой?

Если это так, то, возможно, texlabels — единственная ветвь, которую я когда-либо прервал, чтобы исправить ошибку на главном сервере, поскольку это единственная дополнительная строка в DAG. Кроме того, ни в одной другой ветке нет записи «Ветка слияния« такая-то »» - это потому, что без каких-либо основных коммитов слиянию не нужно изменять какой-либо контент (просто перемещать указатели)?

Потому что dashboard был создан локально и никогда не отправлялся на удаленку.

О, я не понимал, что базовый push не включает информацию о ветке. Судя по всему, Github знает о php7, потому что я, несомненно, делал пуши, пока он проверялся. (Это правильно?)

Я также теперь узнал о тегах и создал тег в тот момент, когда развернул свой проект на новом сервере с PHP7 и другими отличиями. Я был бы рад, если бы больше не было веток php7 или dashboard, пока моя текущая кодовая база остается моей текущей кодовой базой. Но если вы говорите, что существует некоторая неопределенность в отношении их статуса слияния, безопасно ли их удалять? (Удаление вещей звучит пугающе, но если это просто указатель...)

Обновление №2:

После того, как Ката упомянул, что без --all я мог бы не видеть всего, я сделал различие между этим флагом и без него. Я обнаружил, что в самом начале моей работы php7 повторялись первые четыре коммита, сначала на "разветвленной" ветке (видно только в --all), а затем на основной линии со всем остальным. Вот соответствующий фрагмент из git log --graph --decorate --all --oneline:

* 3b1c25a Removal of .html files (won't work with the new server config) and $client in db connect file
* dccc3f3 minor edits
* 20a1aab remove .idea files from repo
* 629d891 Second day of cleanup for PHP7: various things, hacking away at errors one at a time (note: I
* a669fa0 First day of cleanup for PHP7:   * mysql_ to mysqli_ (major functions, anyway)   * convert my
| * 51738d1 (refs/original/refs/heads/php7) minor edits
| * f1aa0f9 remove .idea files from repo
| * 38aef9b (refs/original/refs/remotes/origin/php7) Second day of cleanup for PHP7: various things, ha
| * cfcaa51 First day of cleanup for PHP7:   * mysql_ to mysqli_ (major functions, anyway)   * convert
|/
* 294ef21 Feature: batch category delete

Я предполагаю, что странность была каким-то образом вызвана тем, что я случайно использовал командную строку на своей виртуальной машине, чтобы выполнить два из четырех («удалить .idea ...» и «незначительные правки») вместо OsakaWebbie, как остальные. из них. (Пользователь не отображается в --oneline, но вы можете увидеть это на Github.) Но независимо от того, как это произошло, я предполагаю, что первый набор (от cfcaa51 до 51738d1) исчезнет, ​​когда я удалю ветку, но поскольку они повторяются (и я знаю, что моя текущая кодовая база отражает изменения в этих коммитах), все должно быть в порядке, верно?

06.11.2018

  • Я думаю, вы неправильно поняли, что такое ветка. В другой системе контроля версий, которую я использовал до git, ветвь представляла собой последовательность зафиксированных версий файла. В git это не так. В git ветка — это просто указатель на конкретный коммит. Ветка и тег — это почти одно и то же. Оба они являются ссылками на/псевдонимы для одного конкретного коммита. (Единственное отличие состоит в том, что если вы совершаете коммиты, пока у вас есть извлеченная ветка, вы переместите указатель ветки на новую фиксацию, тогда как тег всегда останется на той же фиксации). 06.11.2018
  • В вашем примере вы объединили ветку texlabels в какой-то момент в прошлом. С этого момента вы удалили ветку texlabels (больше нет ветки, указывающей на коммит в фиолетовой строке истории на картинке). Но у вас все еще есть коммит слияния как часть вашей истории. Этого нельзя изменить, если только вы не перепишете историю (а переписывать историю, как правило, плохо, если вы действительно не знаете, что делаете). 06.11.2018

Ответы:


1

Ветки лучше рассматривать как головки (или указатели). git log показывает вам DAG коммитов и список заголовков, указывающих на конкретные коммиты. То, что вы видите в текущий момент, выглядит примерно так: php7 указывает на этот коммит. Вы не можете знать в прошлом, как двигалась голова php7, поскольку git позволяет нам свободно двигать головы.

Что касается git branch --merged [<commit>], загляните в его документ, команда просто показывает все головы, которые могут быть достиг от <commit>. В вашем случае <commit> это HEAD, что означает master. Таким образом, результат очевиден: dashboard, master и php7 достижимы из HEAD. Обратите внимание, что по умолчанию git branch не показывает удаленные головки, добавьте для этого опцию -a.

Теперь я думаю, что на ваши вопросы можно ответить.

Все коммиты, которые я делал в ветке php7, находятся на той же оранжевой линии, что и master. Если я объединил, а затем удалил ветку (логично), почему она вообще все еще указана как ветка?

Потому что нет уверенности, что в прошлом php7 было объединено в master. Даже если это так, всегда может случиться так, что в какой-то момент php7 голова была перемещена, поэтому мы не можем увидеть остатки слияния, вызванного php7.

Почему в последней ветке php7 есть дополнительная метка «происхождение»? Я бы подумал, что недавние нажатия заставят удаленный сервер выглядеть так же, как локальный, только с одной меткой «происхождение» в последнем коммите. Конечно, удаленный не считает, что php7 еще не объединен - ​​это было бы ужасно, так как этот код имеет решающее значение.

Эта метка просто означает, что в настоящее время есть 2 головки — php7 и origin/php7 — указывающие на этот коммит.

панель мониторинга вообще не известна удаленному пользователю (https://github.com/OsakaWebbie/kizunadb) - как это могло быть?

Потому что dashboard был создан локально и никогда не передавался удаленно.

Я бы с удовольствием удалил его (старые ветки не храню из-за ностальгии), но git branch -d texlabels пишет: ошибка: ветка 'texlabels' не найдена. Самая разветвленная вещь в журнале — это не ветка? У меня болит голова.

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

Обновлять:

Чтобы ответить на некоторые вопросы @OsakaWebbie

Параметр --merged назван на основе того факта, что при нормальной разработке (т. е. вы не двигаете головками ненормально, например, с git reset), если голова child может дотянуться до головы parent, она означает, что parent было объединено с child в какой-то момент в прошлом. Другими словами, child наследует parent.

----------------------- child
         /
        /
     parent

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

Возвращаясь к истории с твоей php7 головой, я думаю, теперь ситуация должна быть ясна.

Слияние не обязательно приводит к объединению двух путей в один. Действительно, как вы сказали, поскольку вы переключились на php7 и добавили к нему 46 коммитов, вы не добавили ни одного коммита к master, поэтому история до слияния выглядит так:

----------------- master
                    \
                     ----------------- php7

Затем вы снова переключились на master и сделали слияние: git merge php7. Поскольку php7 является потомком master, результатом слияния должно быть ровно php7. Таким образом, git просто переместит master вперед и укажет на фиксацию, на которую указывает php7. Такое слияние называется ускоренной перемоткой вперед. Тогда у вас есть:

-------------------
                    \
                     ----------------- php7, master

что по сути:

-------------------------------------- php7, master

Но перемотка вперед не происходила при слиянии texlabels головы. Вы создали голову, переключились на нее, что-то закодировали и добавили какие-то коммиты. Затем вы снова переключились на master, также кое-что закодировали и добавили несколько коммитов. Так что у тебя есть:

----------------- master
     \
      ----------- texlabels

Как видите, texlabels не ребенок master. Следовательно, это не может быть перемотка вперед, объединение texlabels в master вызовет:

----------------- (old master) -- master
     \                         /
      ----------- texlabels

Вот почему это единственная ветвистая на вид вещь в истории.

Что касается ваших двух последних опасений:

О, я не понимал, что базовый push не включает информацию о ветке. По-видимому, Github знает о php7, потому что я, несомненно, делал пуши, пока он проверялся. (Это правильно?)

git push <remote> [<head>] только подталкивает предоставленный <head> (и его предок, конечно, фиксирует). Если <head> не указан, то будет использоваться головка, на которую указывает HEAD — в вашем случае это php7. Чтобы сдвинуть все головы, используйте опцию --all.

Но если вы говорите, что существует некоторая неопределенность в отношении их статуса слияния, безопасно ли их удалять? (Удаление вещей звучит пугающе, но если это просто указатель...)

Да, головы — это просто указатели, но будьте осторожны: после удаления головы некоторые коммиты могут быть заброшены — т. е. к ним нельзя получить доступ ни с одной головы — и они будут очищены (удалены) GC из git. Если вы уверены в том, что удаляете, продолжайте.


Еще несколько заметок:

  1. push -f здесь не при чем, он вызывает непредвиденные вещи на удаленке (например, потеря некоторых коммитов), а не в локальном.
  2. По умолчанию git log показывает только те коммиты, которые могут быть достигнуты из HEAD, используйте опцию --all, чтобы показать все коммиты.

Обновление №2:

О четырех дополнительных коммитах

Весьма вероятно, что при фиксации 51738d1 minor edits вы ввели git filter-branch команду для массового изменения кое-что об этих 4 коммитах (изменить имена авторов, я думаю). Затем у вас было создано 4 новых коммита (от a669fa0 до 3b1c25a). 4 старых коммита (от cfcaa51 до 51738d1) все еще там, потому что они все еще доступны из головок refs/original/.... Эти головы были созданы резервным механизмом git filter-branch.

Вы можете безопасно удалить эти 4 дополнительных коммита. Они совершенно не связаны с 4 «основными» коммитами.

06.11.2018
  • Спасибо за чудесно обстоятельный ответ. Я начинаю понимать больше, но у меня есть вспомогательные вопросы, основанные на вашем ответе и том, что я изучил с тех пор. Пожалуйста, проверьте раздел «Обновление» моего вопроса. 07.11.2018
  • Еще раз спасибо. Грязь в моем мозгу определенно очищается. Я уже принял ваш ответ, но я надеюсь, что вы ответите еще раз - я добавил короткое обновление № 2 к моему вопросу. Это должен быть последний обход. 07.11.2018
  • Ваша ссылка предполагает, что я вручную удаляю весь кусок структуры каталогов? rm -Rf .git/refs/original? Просто подтверждаю, так как это кажется радикальным, и я не понимаю его достаточно хорошо, чтобы предвидеть побочные эффекты. Я попытался окунуться, выполнив только git gc, но это не удалило четыре коммита. 08.11.2018
  • Эта папка содержит головы, которые вы хотите удалить. Так что удаляйте, это безопасно. 08.11.2018
  • Удалено. Но тогда git gc не работает - хочет удалить файлы, но не может. Всегда есть одно: rm: cannot remove ‘/var/www/kizunadb/public/.git/objects/pack/old-pack-[somenumber].pack’: Operation not permitted, а иногда и сотни предупреждений типа: unable to unlink .git/objects/01/[somenumber]: Operation not permitted. Это виртуальная машина - я могу удалить файлы на хосте Windows (я пробовал только старые пакеты - я боюсь делать другие, на случай, если они понадобятся gc до отвязки), но не на гость CentOS, даже как root. Гугление никаких подсказок не дало. 08.11.2018
  • вы можете попробовать это stackoverflow.com/questions/22827676/ 08.11.2018
  • Спасибо, но этот поток был еще менее применим, чем тот, который я нашел ранее: reject" title="Предупреждение о проверке git невозможно отменить разрешение на отмену файлов"> stackoverflow.com/questions/7199496/ Я даже пытался остановить и перезапустить свою виртуальную машину, но безрезультатно. Это становится не по теме, поэтому я напишу новый вопрос для этой проблемы. 08.11.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..