СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

| сохранено

H Готовим git reset правильно в черновиках Recovery Mode Tutorial

Git
Очень короткая заметка из серии «Хозяйке на заметку».

Предисловие


У плохо организованных разработчиков, типа меня, часто так бывает, что накомитишь всякого, а потом оказывается что не то и не туда, но git помнит всё и весь этот разгул анархии остаётся в истории.
Мне всегда казалось что это можно исправить, но сколько раз я не начинал искать ответа на этот вопрос — как в git удалить камиты — столько раз мне это не удавалось.
А всё потому что мои поиски приводили меня к rebase, а надо было искать reset.
На мой вкус вопрос недостаточно освещён и моя заметка призвана закрыть этот пробел.

Алгоритм


  1. git branch // смотрим где мы находимся — в какой ветке
  2. git status // проверяем что у нас актуальная версия
  3. git log // ищем камит к которому мы хотим откатиться
  4. sudo git reset --hard 7bcdf46b14b2dacc286b0ad469d5f9022d797f68 // указываем камит начиная с которого нам надо забыть наши изменения, при этом из локальной ветки все камиты с указанного будут забыты — удалены
  5. git push --force origin feature/draft // заливаем локальную ветку в оригинальную (ветку сервера) — из оригинальной ветки будут удалены все «лишние» камиты
  6. Победа !

Если есть более правильный способ, то прошу озвучить в коментах.

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

комментарии (34)

+10
DrPass ,  
Сначала неплохо было бы эти «камиты» поудалять из вашей заметки.
+10
evgeniy2194 ,  
Очень полезная заметка.

Хотелось бы увидеть заметку о том как дабавить новые камиты
–4
SbWereWolf ,  
в документации к гиту легко найти как сделать ресет, но ни где в документации не сказано как после этого изменения в локальной ветке, накатить на удалённую ветку.

польза заметки — не в том что она рассказывает что такое reset, а в том как в origin залить.

Если у вас не было такой проблемы, то я рад за вас.
0
sl_bug ,   * (был изменён)
–11
SbWereWolf ,  
я не к тому что этого в документации нет, я к тому что не озвучена комбинация reset + push,
товарищам которые из командной строки общаются с git, проблема кажется надуманной,
но есть и другие товарищи которые юзают git через GUI, в gui ( source tree) нет по отдельности push, SourceTree когда видит что у тебя локально камитов недостаёт, предлагает сделать pull и ни какой push --force не предлагается.

но снобам откуда знать о проблемах gui git-клиентов, у них взбурлило, они минуса шлют :)) мой прошлый рекорд всего 12 минусов, тут думаю хотя бы 20 отхвачу, аудитория Хабра не прощает инакомыслия :)
+1
morikvendy ,  
В gui конечно нет кнопок и на половину возможных действий гита и это нормально и правильно, специально для таких случаев есть кнопка «Терминал», которая открывает консоль из которой все это можно сделать.
Мне всегда казалось что это можно исправить, но сколько раз я не начинал искать ответа на этот вопрос — как в git удалить камиты — столько раз мне это не удавалось.
А всё потому что мои поиски приводили меня к rebase, а надо было искать reset.

Вводим в google волшебную фразу «git remove commits from remote branch» вторая ссылка ведет на stackoverflow, и там как раз говорят про сочетание reset + push --force. Более того в статье по первой ссылке тоже это описано в разделе «About History Rewriting» — case 1…
–1
SbWereWolf ,  
«git remove commits from remote branch» — до такого запроса надо дойти, я до него дошёл спустя два часа поисков.
+2
morikvendy ,  
А что же вы гуглили эти два часа? Разве указанный запрос это не ровно то, что вы хотели сделать?
Как то странно выходит, у вас была задача удалить коммиты из удаленной ветки, но вы два часа искали что-то, не вводя в поисковик «удалить коммиты из удаленной ветки», кстати, даже если ввести это на русском, то вторая ссылка приведет на хабр, на статью аналогичную вашей
0
+1 –1
SbWereWolf ,   * (был изменён)
по старой памяти я гуглил rebase, конечно я два часа не только гуглил но и экспериментировал. не только доки гуглил, но больше примеры. и «задавал» вопросы гуглу с разными формулировками.

когда знаешь ответ на вопрос найти его не сложно :) я бы в другой ситуации.

не дал мне Гугл вашу ссылку на Хабр, если бы дал я бы свой пост не делал.
+1
Borz ,  
по старой памяти я гуглил rebase

вы искали в Googl использование команды rebase, а не озвучивали поисковику вашу проблему.
сравните: "git удалить коммиты из удалённой ветки" и "git как с помощью rebase удалить кометы из удалённой ветки".
Проблема преждевременной оптимизации запроса

+2
nick_volynkin ,   * (был изменён)

На Stackoverflow это называют "XY problem". Вместо решения задачи человек ищет решение задачи непременно каким-то инструментом, который ему известен. Оно же: "забиваю гвозди, как правильно держать микроскоп".

+1
Hithroc ,  
Вообще XY problem пошел из IRC, насколько мне известно.
http://mywiki.wooledge.org/XyProblem
0
grossws ,  

Из usenet'а IIRC

–1
+2 –3
TyVik ,  
Тут не в инакомыслии дело. Просто то, что Вы предлагаете — недопустимо. От слова совсем. Нельзя делать push --force после rebase — таким образом можно порушить работу стороннего человека. При этой операции создаётся отдельная ветка, которая считается HEAD. Rebase можно применять очень осторожно и только локально. Пожалуйста, прочитайте Pro Git, это очень полезная и в то же время интересная книга.
0
+1 –1
sl_bug ,  
Всегда делаю форс пуши в свои ветки. И именно после rebase — squash. Просто нельзя в одной ветке нескольким людям работать.
0
voronElf ,  
А у вас тестировщики не пуллят код на тестовом серваке после форс пушей на фиксах багов?
Зачем публиковать ветку в центральном репозитории, если ей никто кроме вас не пользуется?
+1
+2 –1
sl_bug ,  
Я вот так делаю новые камиты — git commit -am 'первый камит'
+3
saggid ,   * (был изменён)

Ну, можно ещё написать вот так:


git reset --hard HEAD~5

Что эквивалентно откату назад на 5 камитов) Очень удобно так делать) Кстати, лучше не выполнять эту команду через sudo — иначе от суперюзера появятся файлы в проекте, что может в итоге привести к проблемам с правами доступа при работе приложения.

–8
SbWereWolf ,  
без sudo почему то не работает, наверное потому что надо вносить изменения в файлы которые были сделаны из под супер юзера.
+10
alexyr ,  
Исправить права под нужного юзера и больше не создавать файлы под рутом.
И вообще, статьи типа «тем, кто не осилил man» на хабре не очень любят
0
nick_volynkin ,  

Хуже, когда автор статьи не осилил man.

+2
saggid ,  

Выполните волшебную команду :)


sudo chown myusername ~ -R

Она присвоит текущего пользователя всем файлам в вашей домашней директории линукса) И дальше уже можно спокойно всё делать без sudo.

+3
saggid ,   * (был изменён)

Даже лучше вот так, чтобы точно текущего пользователя:


sudo chown `whoami`:`whoami` ~ -R
+2
apro ,  
А всё потому что мои поиски приводили меня к rebase, а надо было искать reset.

А почему собственно не rebase,
делаешь git rebase -i HEAD~5 в появившемся редакторе удаляешь нужные
строчки, сохраняешь и выходишь из редактора. Намного же проще чем несколько команд?

+3
+4 –1
demfloro ,  

Думаю лучше порекомендовать бесплатную книгу Pro Git, доступна на английском и на русском.

+3
Alex_ME ,  

Мне кажется, что это способ отстрелить себе ноги, если удаленную ветку кто-то до этого себе скачал.

+6
AlexLeonov ,  
Я бы посоветовал удалить вам эту статью. Всё равно она будет набирать только минусы. А кому-то начинающему может стать сборником вредных советов, если он случайно придёт на эту статью из поисковика.
–1
SbWereWolf ,  
для меня это полезная статья, если люди одно правило применяют ко всем ситуациям то это их проблемы, я выбираю способы в зависимости от условий, в моих условиях это правильное решение.

и если кому то хочется свою ненависть выразить в минусе — сколько угодно. Собака лает, караван идёт.
+6
WildZero ,  
Надо на хабре добавить функцию скрытия опасных статей. Чувствую завтра будет много запоротых репозиториев от подобных «заметок хозяйке»
0
+1 –1
Finesse ,   * (был изменён)

Это не уровень Хабра. Такие заметки лучше постить на Stack Overflow в формате «сам спросил, сам ответил».

0
nick_volynkin ,  

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


Имхо, лучше вообще не постить такие заметки, а вместо этого внимательно читать маны, Хабр и StackOverflow.

+1
Finesse ,   * (был изменён)

Именно поэтому и надо постить на StackOverflow, потому что ответ автора заминусуют, он уйдёт вниз, а правильный ответ попадёт наверх. В итоге, случайный посетитель из Google увидит правильный ответ.

+4
nick_volynkin ,  

Попробую подвести итоги. В статье есть несколько существенных ошибок:


  • Статья на самом деле решает задачу "как удалить коммиты из локальной ветки, а потом из ветки на удаленном репозитории", но из заголовка и текста этого не понять.
  • Статья не обучает использованию команды git reset:
    • Не рассказывает о других популярных вариантах использования: reset без параметров, reset --soft. Да и про reset --hard толком не рассказывает.
    • Поскольку git reset --hard переписывает историю, обязательно нужно было рассказать 0) как удалять коммиты, не теряя изменения 1) что переписывать историю можно только в своих фиче-ветках, 2) как восстанавливать коммиты с помощью git reflog.
  • При любом упоминании git push --force нужно подробно рассказывать, куда нельзя и куда можно форс-пушить. Иначе кто-нибудь запушит в master – далеко не везде используется и правильно настроена защита стабильных веток.
  • Выполнять операции с репозиторием под рутом нельзя, потому что после этого в нем появляются принадлежащие руту файлы (как починить).
0
Eldhenn ,  
I like to come it, come it!