Что может привести к потере данных в git?

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

Я предполагаю git rm, особенно с -r может быть опасно.

Как насчет ветвления, что приводит к перезаписыванию?

Ответ 1

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

Единственное, что вам действительно нужно беспокоиться, это команды, которые удаляют файлы, которые не были проверены, на git. В общем случае Git для этих команд потребуются флаги --force (-f) или --hard.

Здесь приведен быстрый список потенциально опасных команд и что следует учитывать при их использовании:

Может навсегда удалить данные, не привязанные к git:

  • git rm -f - Можно удалить файлы, которые вы еще не отметили.
  • git reset --hard - удалит изменения, которые еще не были проверены, до Git еще
  • git clean -f - удалит файлы, не отслеживаемые git
  • git checkout /path/to/file - может отменить изменения, которые не отмечены, в git
  • git checkout <rev> -f - Может перезаписывать изменения, которые не отмечены, в git
  • rm -rf .git - Не удаляйте каталог .git! Это то, что хранит всю вашу местную историю.

Может удалять данные в удаленных репозиториях (обратимо, но у вас может не быть уровня доступа, необходимого для восстановления фиксации в удаленных репозиториях):

  • git push -f - удаляет историю из ветвей в удаленных репозиториях
  • git push <remote> :<branch> -OR- git push <remote> --delete <branch> - Удаляет удаленные ветки

Может навсегда удалить уже удаленные данные, которые в противном случае можно было бы восстановить (аналогично очистке корзины в вашей операционной системе):

  • git prune - Постоянно удаляет коммиты, недоступные из любой ветки
  • git gc - Навсегда удаляет старые коммиты, недоступные из любой ветки

Может удалять локальные коммиты (их довольно легко восстановить):

  • git reset <revision> - Может удалять историю из ветки (она локально восстанавливается, хотя около двух недель или около того, если вы не запустите git prune)
  • git branch -D <branch> - Удаляет ветвь, которая еще не была объединена (локально восстанавливается)
  • git branch -f <branch> <rev> - Может удалять историю из ветки (локально восстанавливается)

Ответ 2

Моя самая важная вещь для обучения git заключалась в том, что она была ранней и часто фиксировалась. Если у вас есть журнал изменений в управлении версиями, есть способ восстановить его, если вы испортите. У меня было много моментов за последний год, когда я думал, что потерял данные, но поиск через Qaru научил меня некоторым опрятным трюкам. Храните данные на удаленном сервере (например, GitHub или BitBucket), чтобы, если вы полностью уничтожили свое репо, оно все еще где-то. Если вы выполните git branch -D <branch> и удалите ветвь, все фиксации на этой ветке будут удалены из репо.

Единственное, о чем я действительно могу вас предупредить, никогда не переписывать историю, если вы точно не знаете, что делаете. Вещи, которые могут это сделать, git-reset и git-rebase. Никогда не делайте git push <remote> <branch> -f, если вы не знаете, что делаете, поскольку это заставит перезаписать все коммиты с вашим местным репо. Если вы изменили историю веток на местном уровне или если кто-то еще участвовал в репо, это может вызвать серьезные проблемы.

@meager тоже сделал хороший вывод: если вы удалите файл, который еще не отслеживается/не зафиксирован с помощью git, у вас не будет возможности его восстановить.

Как побочная заметка, не бойтесь использовать git-reset и git-rebase, их просто нужно использовать должным образом. Например, я иногда использую git - reset to reset мое рабочее дерево для последней фиксации (отменить все измененные файлы) с помощью git reset --hard HEAD или для отмены последнего сообщения фиксации, сохраняя мое рабочее дерево git reset --soft HEAD^. git rebase также может быть полезен для сквоша/перезаписи нескольких коммитов в вашей истории. Просто имейте в виду, что эти методы могут привести к потере данных, и вы не должны их делать, если вы уже нажали на удаленное репо (с этого времени вам нужно будет сделать git push -f.

Ответ 3

git rm не так опасен, так как после этого вы можете получить свои файлы, начиная с предыдущего коммита.

Как общее правило, позаботьтесь о опции -f: он заставляет Git делать то, что он не хочет делать. (например: branch -f или push -f)

Ответ 4

В зависимости от того, что вы думаете, Git может отслеживать или не отслеживать, Git может "потерять" всякую информацию, которую вы могли бы ожидать от нее. Филиалы и теги могут быть легко потеряны при перетасовке, если у вас нет хорошего понимания внутренних элементов Git или того, как он отличается от других систем.

См. Как использовать Git для потери данных

Ответ 5

Ничего из перечисленного. Очень трудно вызвать потерю данных в Git. Dataloss происходит вне Git, когда вы удаляете файлы, которые Git еще не отслеживает. Любая воспринимаемая "потеря данных", которая встречается внутри Git, может быть восстановлена, если вы попытаетесь восстановить до того, как произойдет сбор мусора, который является окном недель.

Выполняйте свои изменения часто, небольшими шагами. Не беспокойтесь о том, чтобы создавать хорошие сообщения о фиксации или довольно DAG; вы выбросите все это, прежде чем объединить свою ветку функций. Пока вы не совершили свою работу, эта работа находится в опасности потерять.

Ответ 6

В качестве удобного совета, если вы считаете, что удалили ветки, аннотированные теги или reset для более ранней фиксации, вы их не потеряли, все ваши локальные изменения записаны, и вы можете увидеть их с помощью git reflog.

Интересно посмотреть на это, чтобы посмотреть, что он записывает.

В нем перечисляются команды фиксации, которые можно использовать для восстановления ветвей в этом состоянии.

Ответ 7

При неправильном разрешении конфликтов существует риск. В eclipse у нас возникла проблема при разрешении конфликтов файла. a.txt был заявлен для конфликта, в то время как b.txt был выведен/извлечен и показан в индексе. Если пользователь теперь удаляет файл b.txt из индекса обратно в нестационарный - и только добавляет свой разрешенный файл a.txt, а также совершает и толкает - у фиксации будет состояние b.txt из фиксации пользователя PARENT, которую он бы придумал. ПРОБЛЕМА заключается в том, что это изменение не будет отображаться - файл не указан в фиксации. Вы не можете напрямую обнаружить эту проблему. (Только если вы проверяете содержимое файла - в случае двоичного кода вы можете только проверить BLOB.) Усилия litle, вам нужны два пользователя, два репозитория + один голый и два файла. Мы обнаружили это в eclipse/egit - не уверен, что это также проблема с консоли. Вы можете проверить blob с помощью git ls-tree <commit>

Ответ 8

Как сказал meagar, git rm - это удаление, записанное в новой фиксации, поэтому оно может быть восстановлено и может использоваться без страха.

git reset --hard может быть особенно вредным, так как он сбрасывает "текущую фиксацию" (HEAD в Git жаргон) на другую. Поэтому, если предыдущая HEAD не была указана в ветке или теге, она практически потеряна (по крайней мере, без волшебства). Это также приводит к потере ваших незафиксированных изменений.

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

Как и в любой другой ситуации, когда ваши данные ценны (и исходный код), очень желательно иметь зеркало вашего репозитория и регулярно нажимать на него. Это может быть другой локальный репозиторий, частный репозиторий GitHub или просто резервное копирование вашего репозитория с использованием вашей текущей системы резервного копирования. Таким образом, вы всегда можете восстановить вещи.

Как говорят другие, обратите внимание на необработанный файл, который действительно важен. Неотслеживаемые/проигнорированные файлы должны быть только теми, которые генерируются из файлов под управлением версиями: исполняемые файлы и т.д.