git сброс и git возврат

Git

Резюме

引用评论区 “tomi21634” 同学的简短版总结:
1. git revert 后会多出一条commit,这里可进行回撤操作
2. git reset 直接把之前 commit 删掉,非 git reset --hard 的操作是不会删掉修改代码,如果远程已经有之前代码,需要强推 git push -f

Если вы думаете, что краткая версия все еще не очень понятна, вы можете внимательно прочитать изображение и описание ниже.

git reset

develop ----1      3-----
             \   /
branch a       a

После того, как разработка объединяет ветку, я хочу отозвать слияние, не оставляя следов. на этот раз использоватьgit resetПросто хороший выбор.

Конкретные этапы операции следующие:

  1. переключить ветку на разработку
  2. git log Просмотр журнала текущей ветки

Например, мой журнал выглядит так:

commit 3
Merge 1 2
Author: admin <admin@163.com>
Date: Wed May 30 15:00:00 2018 +0800

    Merge branch 'feature/a' into 'develop'

    close a

    See merge request !20

commit 2
Author: admin <admin@163.com>
Date: Wed May 30 14:00:00 2018 +0800

    close a

commit 1
Author: admin <admin@163.com>
Date: Wed May 30 13:00:00 2018 +0800
    init project

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

  1. Расскажите об определении параметра git reset,Подробности смотрите на официальном сайте
    --soft 回退后a分支修改的代码被保留并标记为add的状态(git status 是绿色的状态)
    --mixed 重置索引,但不重置工作树,更改后的文件标记为未提交(add)的状态。默认操作。
    --hard 重置索引和工作树,并且a分支修改的所有文件和中间的提交,没提交的代码都被丢弃了。
    --merge 和--hard类似,只不过如果在执行reset命令之前你有改动一些文件并且未提交,merge会保留你的这些修改,hard则不会。【注:如果你的这些修改add过或commit过,merge和hard都将删除你的提交】
    --keep 和--hard类似,执行reset之前改动文件如果是a分支修改了的,会提示你修改了相同的文件,不能合并。如果不是a分支修改的文件,会移除缓存区。git status还是可以看到保持了这些修改。
    

Код ветки мне больше не нужен и не понадобится в будущем. следовательно:

git reset 1(粘贴过来的commit号) --hard

Мне все еще нужен код ветки, но я больше не хочу эту фиксацию:

git reset 1

  1. git logПроверьте это:
commit 1
Author: admin <admin@163.com>
Date: Wed May 30 13:00:00 2018 +0800
    init project

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

git push origin develop

![rejected] develop -> develop (non-fast-forward)
error: 无法推送一些引用到 'git@github.cn:...'
提示:更新被拒绝,因为您当前分支的最新提交落后于其对应的远程分支。
。。。

Что ж, моя ветка отстает от ветки удаленной разработки. я нуждаюсь--force.

git push origin develop --force

Total 0 (delta 0), reused 0 (delta 0)
To git@...
+ 83***...23***** develop -> develop (forced update)

Хорошо, вернитесь на github, чтобы проверить сеть. Ну, это то, что я хочу.

git revert

или этот пример

develop ----1      3-----
             \   /
branch a       a

Это все еще предыдущее требование, я не хочу объединять a, я просто хочу, как это выглядит, когда a не объединено.

Шаги:

  1. Филиал для разработки:git checkout develop
  2. Посмотреть журнал:git log , или приведенный выше журнал:
commit 3
Merge 1 2
Author: admin <admin@163.com>
Date: Wed May 30 15:00:00 2018 +0800

    Merge branch 'feature/a' into 'develop'

    close a

    See merge request !20

commit 2
Author: admin <admin@163.com>
Date: Wed May 30 14:00:00 2018 +0800

    close a

commit 1
Author: admin <admin@163.com>
Date: Wed May 30 13:00:00 2018 +0800
    init project

на этот раз иgit resetРазница в том, что я не могу скопироватьcommit 1Этот номер коммита исчерпан, мне нужно скопироватьcommit 2номер фиксации. Поскольку за возвратом следует требуемая ветка, которая была объединена, а не номер коммита, к которому нужно вернуться.

  1. Запустите запасной вариант:git revert 2
Revert "close a"
This reverts commit 2
#.......

Это эквивалентно добавлению еще одного коммита и изменению всех модификаций в ветке обратно.

  1. Ctrl+X, чтобы покинуть страницу с информацией о коммите редактирования.

git logПосмотрите, если это то, что я думаю

commit 4
Author: admin <admin@163.com>
Date: Wed May 30 17:00:00 2018 +0800
    Revert "close a"
    This reverts commit 2
commit 3
Merge 1 2
Author: admin <admin@163.com>
Date: Wed May 30 15:00:00 2018 +0800

    Merge branch 'feature/a' into 'develop'

    close a

    See merge request !20

commit 2
....

Это правда, что добавлен новый коммит.Глядя на код, обнаруживается, что модификация ветки не существует, и она также достигает желаемого эффекта.

  1. нажать на удаленный серверgit push origin develop

Глядя в сети, это так:

develop ----1      3-----revert a------
             \   /
branch a       a

Кажется,git resetа такжеgit revertОба они могут удовлетворить мои текущие потребности, так в чем же разница между ними?После того, как я проверил этот вопрос в Интернете, я подумал, что он немного абстрактен, и я не очень хорошо его понял, поэтому я понял это только после того, как я сам практиковал.

разница

  1. git revert должен откатить предыдущую фиксацию с новой фиксацией, а git reset — удалить указанную фиксацию напрямую.

    Это легко понять, мы уже можем видеть это явление, взглянув на лог в предыдущей операции.

    git resetПосле операции мы видим, что сеть в приведенном выше примере имеет толькоcommit 1,分支aа также合并分支后的commit 3исчез;

    git revertПосле операции операцию ветки а и слияния ветки а все еще можно увидеть в сети, но на основе добавляется обратная фиксация.

  2. git reset должен переместить HEAD назад, а git revert — переместить HEAD вперед, но содержимое нового коммита противоположно возвращаемому содержимому, что может компенсировать возвращаемое содержимое.

    Это видно ясно и ясно, поэтому я не буду объяснять слишком много.

  3. С точки зрения отката эффект аналогичен. Но есть разница при продолжении слияния предыдущей старой версии в будущем. Поскольку git revert использует обратную фиксацию, чтобы «нейтрализовать» предыдущую фиксацию, когда старая ветка будет объединена в будущем, эта часть изменения не появится снова, но git reset напрямую удалит некоторые фиксации в ветке, поэтому, когда старая ветвь снова слита, эти откатные коммиты все равно должны быть введены.

    git revert

    Текущее требование состоит в том, что я вернул ветку a раньше, но теперь мне снова нужен код ветки a. Я написал его однажды раньше и не могу написать снова. Первый способ, о котором я подумал, было бы лучше объединить ветку для разработки.

    git merge a
    

    результат

    Already up-to-date
    

    Какие? Поскольку код ветки, которую мы отправили и объединили ранее, все еще существует, мы не можем повторно объединить ветку.

    Решение: используйте номер фиксации, возвращенный перед возвратом. В приведенном выше примере этоgit revert 4. Таким образом, был добавлен новый коммит, и ранее измененный код был возвращен обратно.конкретная ссылка

git reset

Тем не менее вышеперечисленные требования.

develop -----1-----4-------5------6
              \   / \     / \    /
feature         b      c       d

Теперь я буду разрабатывать reset для фиксации 4 здесь, продолжайте отправлять свой будущий код

develop -----1-----4-------7------8
              \   / \\     /
feature         b     \ e
                        \------5----d
                          \-c-/

Теперь я хочу повторно объединить код из ветки d

 develop -----1-----4-------7------8------9
              \   / \\     /             /
feature         b     \ e              /
                        \------5----d/
                          \-c-/

Вот так это выглядит в сочетании. Другими словами, ветвь d ранее объединила ветвь c, поэтому, если вы хотите объединить ветвь d, код ветви c будет перенесен синхронно.

Сценарии применения

Большинство часто используемых здесь сценариев приложений должны быть относительно ясны.

  1. Если код ветки отката понадобится позже, используйтеgit revertне может быть лучше; Если ветка просто неправильная и бесполезная, и я не хочу, чтобы другие нашли мой неправильный код, тоgit resetБар
  2. Например: в ветке разработки объединились четыре ветки а, б, в и г. Я вдруг обнаружил, что ветка б бесполезна, а код ненужный. В это время сброс использовать нельзя, т.к. ветки есть и после перезагрузки.И пропали. Используйте толькоgit revert b分支commit号, поэтому код для c и d все еще там.

Суммировать

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

Такую подробную статью пишу впервые, в основном из-за знаний найденных в интернете.Для людей с общей системой знаний git читать довольно озадачивает.