Готовим git reset правильно

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

Предисловие


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

Алгоритм


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

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

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

PS2
Более правильного способа не нашлось ( вариации с rebase не более чем вариации ).
Но у товарищей которые считают, что в жизни всё всегда происходит одинаково и поэтому всегда надо действовать единственным правильным образом крышу сорвало от такого вольго обращения с репозиторием.

Товарищи!
Для каждой задачи свои инструменты и свои методы, иногда и git reset — годный метод, особенно когда ты на проекте один разработчик и ты хочешь откатить камиты за последние два часа работы в своей feature ветке.

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 34

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

      Хотелось бы увидеть заметку о том как дабавить новые камиты
        +1
        Я вот так делаю новые камиты — git commit -am 'первый камит'
          –4
          в документации к гиту легко найти как сделать ресет, но ни где в документации не сказано как после этого изменения в локальной ветке, накатить на удалённую ветку.

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

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

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

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

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

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

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

                          +2

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

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

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


          git reset --hard HEAD~5

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

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

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

                +2

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


                sudo chown myusername ~ -R

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

                  +3

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


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

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

                +3

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

                  +3

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

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

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

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

                          0

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


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

                            +1

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

                          +4

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


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

                            Only users with full accounts can post comments. Log in, please.