Как изменить указанную фиксацию в git?

Я обычно представляю список коммитов для просмотра. Если у меня есть:

  • HEAD
  • Commit3
  • Commit2
  • Commit1

Я знаю, что могу модифицировать head commit с помощью git commit --amend, но как я могу изменить Commit1, учитывая, что это не фиксация HEAD?

1512
задан Sam Liao 27 июля '09 в 8:19
источник поделиться

7 ответов

Вы можете использовать git rebase, например, если вы хотите изменить обратно на commit bbc643cd, запустите

$ git rebase --interactive 'bbc643cd^'

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

$ git commit --all --amend --no-edit

чтобы изменить фиксацию, и после этого

$ git rebase --continue

чтобы вернуться к предыдущему фиксации главы.

ПРЕДУПРЕЖДЕНИЕ. Обратите внимание, что это изменит SHA-1 этого комманда , а также всех детей - другими словами, это переписывает историю с этой точки вперед, Если вы нажмете с помощью команды git push --force

1978
ответ дан ZelluX 27 июля '09 в 8:28
источник поделиться

Используйте потрясающую интерактивную rebase:

git rebase -i @~9   # Show the last 9 commits in a text editor

Найдите требуемую фиксацию, измените pick на e (edit) и сохраните и закройте файл. Git перемотает на эту фиксацию, что позволит вам:

  • используйте git commit --amend для внесения изменений или
  • используйте git reset @~, чтобы отменить последнюю фиксацию, но не изменения в файлах (т.е. дойдя до точки, в которой вы были, когда вы редактировали файлы, но еще не зафиксировали ее).

Последний полезен для выполнения более сложных вещей, таких как разделение на несколько коммитов.

Затем запустите git rebase --continue, а Git воспроизведет последующие изменения поверх измененного коммита. Вас могут попросить исправить некоторые конфликты слияния.

Примечание: @ является сокращением для HEAD, а ~ является фиксацией до указанного фиксации.

Подробнее о переписывании истории в документах Git.


Не бойтесь переустанавливать

ProTip ™: не бойтесь экспериментировать с "опасными" командами, которые переписывают историю * - Git не удаляет ваши фиксации в течение 90 дней по умолчанию; вы можете найти их в reflog:

$ git reset @~3   # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Остерегайтесь опций, таких как --hard и --force, хотя - они могут отбрасывать данные.
* Также не переписывайте историю в каких-либо ветких, с которыми вы сотрудничаете.



Во многих системах git rebase -i откроет Vim по умолчанию. Vim работает не так, как большинство современных текстовых редакторов, поэтому посмотрите как переустановить с помощью Vim. Если вы предпочитаете использовать другой редактор, измените его на git config --global core.editor your-favorite-text-editor.

247
ответ дан Zaz 29 апр. '15 в 20:50
источник поделиться

Интерактивный rebase с --autosquash - это то, что я часто использую, когда мне нужно исправлять предыдущие, фиксирует глубже в истории. Это существенно ускоряет процесс, который иллюстрирует ответ ZelluX, и особенно удобен, когда у вас есть несколько коммитов, которые нужно редактировать.

Из документации:

--autosquash

Когда сообщение журнала фиксации начинается с "squash!..." (или "fixup!..." ), и есть коммит, чей заголовок начинается с того же..., автоматически изменяет список todo reba -i так что фиксация, помеченная для раздачи, появляется сразу после модификации фиксации

Предположим, что у вас есть история, которая выглядит так:

$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1

и у вас есть изменения, которые вы хотите внести в Commit2, затем выполните свои изменения, используя

$ git commit -m "fixup! Commit2"

альтернативно вы можете использовать commit-sha вместо сообщения фиксации, поэтому "fixup! e8adec4 или даже просто префикс сообщения фиксации.

Затем инициируйте интерактивную перезагрузку для фиксации до

$ git rebase e8adec4^ -i --autosquash

ваш редактор откроется с правильно заказанными коммитами

pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3

все, что вам нужно сделать, это сохранить и выйти

43
ответ дан thrau 29 сент. '15 в 20:59
источник поделиться

Run:

$ git rebase --interactive commit_hash^

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

Используя Vim, вы изменяете слова pick на reword для коммитов, которые вы хотите изменить, сохранить и выйти (:wq). Затем git предложит вам каждую фиксацию, которую вы пометили как переименование, чтобы вы могли изменить сообщение фиксации.

Каждое сообщение фиксации, которое вы должны сохранить и выйти (:wq), перейти к следующему сообщению фиксации

Если вы хотите выйти без применения изменений, нажмите :q!

EDIT: для перехода в vim используйте j для перехода вверх, k, чтобы пойти вниз, h, чтобы идти влево, и l, чтобы перейти вправо (все в режиме NORMAL нажмите ESC, чтобы перейти в режим NORMAL). Чтобы отредактировать текст, нажмите i, чтобы войти в режим INSERT, где вы вставляете текст. Нажмите ESC, чтобы вернуться в режим NORMAL:)

UPDATE. Здесь отличная ссылка из списка github Как отменить (почти) что-нибудь с git

27
ответ дан betoharres 02 июля '15 в 22:11
источник поделиться

Если по какой-то причине вам не нравятся интерактивные редакторы, вы можете использовать git rebase --onto.

Предположим, вы хотите изменить Commit1. Сначала ветвь от Commit1:

git checkout -b amending [commit before Commit1]

Во-вторых, возьмите Commit1 с помощью cherry-pick:

git cherry-pick Commit1

Теперь измените свои изменения, создав Commit1':

git add ...
git commit --amend -m "new message for Commit1"

И, наконец, после того, как вы спрятали любые другие изменения, пересаживайте остальную часть своих коммитов до master поверх вашего new commit:

git rebase --onto amending Commit1 master

Читайте: "rebase, на ветку amending, все совершает транзакции между Commit1 (не включительно) и master (включительно)". То есть Commit2 и Commit3 полностью разрезают старый Commit1. Вы могли бы просто выбрать вишню, но это проще.

Не забудьте очистить ветки!

git branch -d amending
11
ответ дан FeepingCreature 22 окт. '16 в 15:19
источник поделиться

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

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

Предположим, вы хотите изменить commit 0, и вы в настоящее время находитесь на feature-branch

some-commit---0---1---2---(feature-branch)HEAD

Ознакомьтесь с этой фиксацией и создайте quick-branch. Вы также можете клонировать свою ветку функций как точку восстановления (перед запуском).

?(git checkout -b feature-branch-backup)
git checkout 0
git checkout -b quick-branch

Теперь у вас будет что-то вроде этого:

0(quick-branch)HEAD---1---2---(feature-branch)

Изменения в сцене, запишите все остальное.

git add ./example.txt
git stash

Заменить изменения и возврат обратно на feature-branch

git commit --amend
git checkout feature-branch

Теперь у вас будет что-то вроде этого:

some-commit---0---1---2---(feature-branch)HEAD
           \
             ---0'(quick-branch)

Rebase feature-branch на quick-branch (разрешить любые конфликты на этом пути). Примените stash и удалите quick-branch.

git rebase quick-branch
git stash pop
git branch -D quick-branch

И вы получите:

some-commit---0'---1'---2'---HEAD(feature-branch)

Git не будет дублировать (хотя я не могу сказать, в какой степени) 0 совершает при перезагрузке.

Примечание: все хеши фиксации изменены, начиная с фиксации, которую мы изначально планировали изменить.

6
ответ дан Olga 01 июня '16 в 14:57
источник поделиться

Для меня это было для удаления некоторых учетных данных из репо. Я попытался переустановить и столкнулся с тонкой, казалось бы, несвязанными конфликтами на пути, когда пытался переустановить, - продолжайте. Не утруждайте себя попыткой перезагрузить себя, используйте инструмент под названием BFG (brew install bfg) на mac.

0
ответ дан Pellet 07 нояб. '17 в 10:24
источник поделиться

Другие вопросы по меткам