Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Git GUI - Переключение между ветками с удалением и восстановлением файлов

#git #gui #git_branch


Можно, конечно, и объяснением через командную строку, но желательно через Git GUI
(а иначе зачем создавать gui-клиент, который не может того, что может консоль).

Суть в том, что у разных веток разное количество файлов. И часть из файлов используется
'вручную'. В общем, мне нужно, чтобы при переключении с Ветки1 на Ветку2 удалялись
файлы, не используемые Веткой2 и создавались те, что используются ей. Такое возможно?

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


Ответы

Ответ 1



В общем, мне нужно, чтобы при переключении с Ветки1 на Ветку2 удалялись файлы, не используемые Веткой2 и создавались те, что используются ей. В целом так и происходит. Давайте для начала разберёмся с терминологией, чтобы точно понимать друг друга. Ветка - это всего лишь легковесный указатель на коммит. Она реализована просто как файл, а в файле лежит номер (SHA-1) коммита. Переключаясь на другую ветку вы на самом деле переключаетесь на другой коммит. Файлы и папки не используются веткой или коммитом. Правильнее говорить, что файл (или конкретное состояние файла) принадлежит коммиту или сохранено в коммите. Коммит внутри себя содержит структуру файлов и папок, которые в нём были сохранены, в том числе содержимое файлов. По своей сути это такая "фотография" рабочей области вашего проекта. При переключении на другой коммит происходит перестроение всех файлов и папок на то состояние, которое сохранено в том коммите. Давайте представим, что у нас есть две ветки: master и feature и рассмотрим различные ситуации. Здесь буквы - это разные коммиты. D feature / A--B--C/--E master* Мы находимся в master и переключаемся на feature: git checkout feature Пусть у нас есть некоторый файл. Обозначим его содержимое в коммитах C, D, E, в рабочей области проекта (working tree, wt) и результат checkout'a (или его попытки). x - файл удалён 1, 2, 3 - различные варианты содержимого | C | E | D | wt | Результат --------------------------------------------------------------------- | 1 | 1 | 1 | 1 | 1, без изменений | 1 | 1 | 1 | 2 | 2, несохранённое изменение останется | 1 | 1 | 3 | 1 | 3, терять нечего, содержимое просто меняется | 1 | 2 | 1 | 2 | 1, аналогично | 1 | 2 | 3 | 2 | 3, аналогично. # итог: если последнее состояние файла закоммичено (E == wt), # конфликтов никогда не будет | 1 | 1 | 2 | 3 | Fail, будет потеря несохранённых изменений | 1 | 2 | 2 | 3 | 3, git распознаёт, что изменения в коммитах одинаковы. | 1 | 2 | 3 | 3 | Fail. Текущее состояние файла равно сохранённому в D, # но с точки зрения текущего коммита это потеря несохранённых изменений. | 1 | 2 | 1 | 3 | Fail. Даже если файл менялся только в одном коммите, # нельзя применить изменение "2" -> "3" к содержимому "1" # теперь поудаляем. | C | E | D | wt | Результат --------------------------------------------------------------------- | 1 | x | 1 | x | 1. Файл восстановлен, как раз то что вам нужно. | 1 | 1 | x | 1 | x. В той ветке файл удалён. | 1 | 1 | x | 2 | Fail, потеря изменений. | 1 | 1 | 2 | x | Fail, удаление - это тоже изменение. | 1 | 1 | 1 | x | x, изменение есть, но конфликта нет. # Файл независимо появился в разных ветках | x | 1 | 1 | 1 | 1, всё нормально | x | 1 | 2 | 1 | 2, даже если содержимое разное | x | 1 | 2 | 2 | Fail, снова потеря, хоть содержимое и совпадает. Итого, результат checkout для каждого файла можно описать таким псевдокодом: if (E == wt) { // Если нет несохранённых изменений, берём содержимое из D return D } else if (E == D) { // Если содержимое не менялось (или менялось одинаково), // То можно оставить текущее содержимое файла return wt } else { // Иначе вероятна потеря данных fail() } Что можно делать с несохранёнными изменениями: Закоммитить Сложить в карман. Отменить с помощью git reset --hard -- filename - в одном файле git reset --hard - отменить все изменения версионируемых (отслеживаемых) файлов git clean -f - вообще почистить рабочую область, в том числе удалить неверсионируемые файлы. C -fx удалит ещё и игнорируемые файлы, с -fd захватит директории, а не только файлы. Вариант -fdx - выжигание напалмом всего, что не прибито гвоздями.

Ответ 2



При git checkout %branch_name% состояние отслеживаемых файлов в репозитории меняется в состояние крайнего коммита этого бранча (т.е. лишние файлы скроются, а нужные - добавятся). Модифицированные и новые (не зафиксированные) файлы остаются висеть. Чтобы очистить репозиторий от неотслеживаемых папок и файлов можно также выполнить git clean -dfx.

Ответ 3



если файлы 'вручную' не закомичены и не лежат в индексе в ветке1, то для их сохранения необходимо положить их 'на полку до востребования' командой git stash save --include-untracked "имя полки" После этого переключиться на ветку2 Для просмотра всех стешей надо использовать git stash list Для извлечения файлов нужно выполнить git stash apply "stash@{0}" Нужно использовать нужный индекс Аналогичен переход с ветки2

Комментариев нет:

Отправить комментарий