Удалите конфиденциальную ветку с удаленного, но сохраняйте файлы, зафиксированные локально - PullRequest
1 голос
/ 01 мая 2020

Мой локальный репозиторий git имеет 2 пульта: private и public. По ошибке я запустил git push public feature_branch, поэтому теперь код на feature_branch стал опубликован c, хотя он должен был оставаться скрытым (на данный момент). Это не большая проблема с конфиденциальностью, но я все же хотел бы ее исправить.

Я уже удалил ветку, используя GitHub GUI. Мне нужно сделать что-нибудь еще? Я не ожидаю, что кому-то удалось клонировать репозиторий за 30 секунд, когда ветвь была общедоступна - меня интересуют только кеши или другие вещи, которые fre sh git clone может загрузить прямо сейчас.

Running git push public --delete feature_branch теперь дает error: unable to delete 'feature_branch': remote ref does not exist, так что это выглядит правильно.

Мне известно о git filter-branch, но я читаю это так, как это имеет дело с данными, которые не должны иметь был зафиксирован в первую очередь - я хочу зафиксировать код, но не делаю его общедоступным, пока не решу сделать это позже.

1 Ответ

1 голос
/ 01 мая 2020

В этом случае вы сделали все, что вам нужно сделать.

(Вы можете остановиться здесь, если хотите.)

Long-i sh: как об этом думать

Git - это действительно commits . Репозиторий Git можно рассматривать как большую базу данных коммитов - или, на самом деле, Git объектов , но коммиты находятся на уровне, с которым вы работаете - и вы, или Git по крайней мере, получит эти объекты по их ключам, которые являются их sh идентификаторами.

Более точная картина хранилища Git, однако, выглядит как две базы данных : большой из Git объектов, включая коммиты, и маленький (или, по крайней мере, обычно намного меньший) одно из имен . Эти имена включают все имена ветвей и тегов.

Причина, по которой имена существуют, двояка:

  • Ха sh Идентификаторы большие и некрасивые, и ни один человек не может вспомнить их. Каждое имя помнит один га sh ID для нас.

  • Фиксирует, в частности, в виде цепочек. Git находит старые коммиты, чтобы найти последний коммит - чей идентификатор ha sh хранится в имени ветви - и работать в обратном направлении.

  • Подтверждает, что не может быть найден таким способом - который не может быть достигнут, начиная с имени и, если необходимо, работая в обратном направлении - удаляется. Может быть, не сразу, но достаточно скоро для целей большинства людей. (Средства безопасности, с которыми вы столкнулись - случайная фиксация, а затем отправка конфиденциальных данных - это то место, где «достаточно скоро» нельзя или, по крайней мере, нельзя предположить.)

Итак имена позволяют нам найти коммитов. Если у них нет имени, мы не можем их найти, и они могут также не существовать (и скоро их не будет). Имя не должно найти их напрямую, только косвенно. Но как только коммит сделан, ничто в нем не может измениться. Так что фиксирует все, всегда, указывает только назад , от дочерних коммитов до их родителей. Новые коммиты не влияют на существующие коммиты. Git может работать только в обратном направлении , от имени до коммита, от родителя до бабушки и дедушки и т. Д. c.

Акт клонирования репозитория состоит (в середине) из выполнения этих двух вещи, хотя и не совсем в таком порядке - все это внутренне немного перемешано:

  • Во-первых, у них была база данных имен. Наш Git обычно принимает этот набор имен и выбрасывает большинство из них:

    • У нас нет ни одного, ни нескольких, ни всех тег имен в различных условиях, которые не стоит здесь описывать.

    • Мы сохраняем их ответвления имен, но переименовываем их в наши дистанционное отслеживание имен (например, origin/master вместо master).

    • Если мы хотим сохранить все имена без изменений мы можем использовать git clone --mirror (что имеет много последствий, которые мы здесь пропустим). Обычно мы этого не делаем, так как это бесполезно для нормальной работы.

  • Последнее, оригинальный репозиторий передает все коммиты - или все те, которые могут в любом случае, по именам, которые мы скопировали.

В результате получается новый репозиторий: новая пара баз данных. 1

Я сказал в середине выше, потому что git clone на самом деле имеет шесть шагов:

  1. создать новый пустой каталог (или использовать существующий пустой каталог);
  2. создать хранилище в этом каталоге и выполнять всю остальную работу там;
  3. добавить remote с именем origin или другое выбранное имя, чтобы сохранить URL;
  4. выполнить любую дополнительную конфигурацию;
  5. запустить git fetch, которая выполняет копирование базы данных;
  6. запустить git checkout.

Это последний шаг - git checkout - это создает имя branch в новом клоне. В этом шаге выбрана ветка, рекомендованная Git в origin, обычно master или другим именем по вашему выбору в командной строке git clone. 2

Когда вы использовали GitHub GUI для удаления имени ветви в Git в GitHub, это:

  • удалил имя из базы данных имен;
  • , как следствие, сделал некоторые коммиты недоступными , чтобы их не видели и, следовательно, не видели копирование.

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


1 Репозитории также включают в себя немного больше, чем только эти две базы данных. Например, каждое имя - каждая ref или ссылка в терминах Git - может иметь свою собственную мини-базу данных ранее сохраненных идентификаторов ha sh. Это reflogs , которые на самом деле являются просто текстовыми файлами в .git/logs/. Но они не копируются. Копируются только две основные базы данных, а имена не копируются как есть: они восстанавливаются с помощью шага выборки.

Обычно, когда вы работаете с коммитами в репозитории, вы получаете Git extract снимок одного конкретного коммита в ваше рабочее дерево . Рабочее дерево, в довольно сильном смысле, не является частью самого репозитория: репозиторий - это материал в каталоге .git. Так называемый клон bare не имеет рабочего дерева, но все еще является хранилищем; большинство Git на стороне сервера, такие как GitHub, являются голыми клонами.

2 Вы можете, если хотите, выбрать имя tag здесь, в в этом случае git checkout приводит к отделенным именам веток HEAD и no в новом клоне.

3 Git никогда сделал особенно сильные обещания security , поэтому могут быть некоторые способы обмануть другой Git - в origin - чтобы позволить копировать коммиты. Но вы пытаетесь предотвратить случайный, а не преднамеренный доступ.

...