Як змінити минулу комісію, щоб включити пропущений файл?


98

Я вніс зміни та забув додати файл до набору змін. Після інших комітів я зрозумів, що файл зараз відсутній у HEAD^4коміті.

Як переписати попередній коміт, щоб включити відсутній файл?


ти штовхнув ці 4 коміти?
mvp

@mvp nope, вони є лише в моєму локальному сховищі git.
kolrie

Відповіді:


53

Використовуйте git rebase --interactive HEAD~4та встановлюйте editпараметр для коміту, який ви хочете змінити.

Пам’ятайте, що не слід таким чином змінювати коміти, що надсилаються до віддаленого сховища. У такому випадку краще додати новий коміт із відсутнім файлом.


Дякую. Це так, навіть якщо я єдиний користувач віддаленого репо? Чи не дозволило б мені це зробити, git push -fякщо я впевнений, що вище течія не змінилося?
kolrie

1
Якщо ви єдиний користувач віддаленого репо, це нормально зробити примусовий натиск.
Rafał Rawicki

7
Я думаю, ці інструкції недостатньо деталізовані. Коли я спробував це вперше, мені сказали: "Неможливо перезавантажити: Ваш індекс містить невідомі зміни". Я вже addвикористовував пропущені файли, тому я зробив посилання на "xxx" як повідомлення. Потім я виконав команду rebase і змінив команду "xxx" з "pick" на "edit". Тоді я зробив "git rebase - продовжувати". Тепер, коли я дивлюся на історію, у мене є "ххх" як остання фіксація, а попередня фіксація, до якої я хотів додати їх, не змінюється! Цікаво, де була моя помилка?
Даррен Кук

2
Скасування останнього комітету не додасть файл у HEAD ~ 4.
Джастін

1
git add editedFiles; git počin -m "Blah"; git rebase -i HEAD ~ 5; // як тепер додано нове фіксування, тому нам потрібно було перезавантажити 5 замість 4. Тепер перенесіть команду "Blah" на другий рядок і змінимо її з "Pick" на "s" (сквош), який дозволить скосити команду HEAD ~ 5, оскільки команди виконуються зверху вниз
zstring

274

Я усвідомлюю, що люди можуть google і прийти сюди, щоб знайти більш просту відповідь: Що робити, якщо це був лише останній вчинок? (Питання ОП полягає у фіксації 4-ї комісії ще в історії)

У випадку, коли ви здійснюєте та розумієте, що забули додати якийсь файл негайно , просто зробіть:

# edited file-that-i-remember.txt
git add file-that-i-remember.txt
git commit

# realize you forgot a file
git add file-that-i-forgot.txt
git commit --amend --no-edit

Де --no-editзбережеться те саме повідомлення про фіксацію.

Простенька!


21
Це відповідь.
Адам Біттлінгмайєр

5
Варто згадати, якщо комітети не висуваються на пульт.
Ram Patra

1
Так, тут варто згадати тут у коментарях: Це для використання перед натисканням . Дякуємо, що вказали на це.
Д-р Беко

2
Одне зауваження - це те, що до і після цього --amendє різні хеши
sonlexqt

5
Дякую, але цього не може бути: OP попросив HEAD^4. Це нормально, як є, лише як доповнення для довідки. ;)
Д-р Беко

11

Якщо ви НЕ пересунули ці 4 коміти, ви можете зробити це наступним чином:

Створіть файли виправлень для всіх цих комітів:

git format-patch -4

Перемотати назад на 4 коміти:

git reset --hard HEAD~4

Додати відсутній файл:

git add missing-file

Зверніть це з --amend:

git commit --amend

Застосувати всі збережені виправлення назад:

git am *.patch

Якщо ви натиснули, НЕ слід використовувати цей метод. Натомість просто визнайте свою помилку та створіть ще одну фіксацію поверх HEAD, яка вирішує цю проблему.


Якщо ви хочете зробити це поетапно, то легше буде вибирати вишні після модифікованого, ніж експортувати їх як патч.
Rafał Rawicki

1
Це справа смаку. Мені подобається git format-patch/ git amнабагато краще. Найголовніше, це надає вам більше впевненості, якщо ви щось псуєте - коміт, збережений як виправлення у фізичному файлі, є вашим найкращим захисним мережею.
mvp

Справжня впевненість полягає в тому, що, працюючи в сховищі git, ви ніколи не видаляєте нічого. Старі замовлення доступні, поки ви не запустите git gc:)
Rafał Rawicki

Це банально і очевидно для вас і для мене. Але для користувача, який тільки починає роботу і, мабуть, нічого не розуміє про git - цей факт зовсім не очевидний.
mvp

2
Ці вказівки здавалися довгомотивними, але були досить простими та легкими в дотриманні. Дякую. (Я б просто додати останній крок: rm *.patch)
Darren Кук

9

Незважаючи на те, що прийнята відповідь є правильною, вона не має детальних інструкцій щодо того, як виконати редагування комітету під час процесу відновлення.

  • По-перше, запустіть процес відновлення бази даних:

    git rebase --interactive HEAD~4
    
  • Список фіксацій буде представлений, виберіть Комміт ви хочете відредагувати, змінивши слово pickв editі зберегти файл.

  • Внесіть необхідні зміни у свій код (не забудьте викликати git addнові файли)

  • Після того, як всі модифікації будуть зроблені, видайте git commit --amend- це дозволить змінити зобов’язання, позначене якedit

  • Викликати, git rebase --continueщо завершить процес (якщо є більше комісій, позначених як edit, вищезазначені кроки потрібно повторити)

Важливі примітки:

  • НЕ видаляйте рядки, позначені такими, pickякі ви не хочете редагувати - залиште їх такими, як є. Видалення цих рядків призведе до видалення відповідних комісій

  • GIT примушує вас до stashвипуску, якщо ваш робочий каталог не є чистим; Ви можете, проте, git stash pop / git stash applyпід час ребазування, щоб змінити ці зміни (тобто зміни, приховані перед початком процесу відновлення), до комітету, позначеного якedit

  • якщо щось пішло не так, і ви хочете повернути зміни, внесені під час процесу відновлення, перед тим, як він закінчився (тобто ви хочете повернутися до точки перед початком відновлення), використовуйте git rebase --abort- також читайте: Як скасувати інтерактивну ребауз, якщо --abort doesn ' т працює?

  • Як сказано у прийнятій відповіді:

    Пам’ятайте, що ви не повинні змінювати комісії, висунуті у віддалений сховище таким чином. У цьому випадку краще додати нову комісію з відсутнім файлом.

    Відповідь чому, є у Git Book (параграф під назвою " Небезпеки звільнення "):

    Не перебазуйте коміти, які існують поза вашим сховищем.

    Якщо ви будете дотримуватися цих вказівок, у вас все буде добре. Якщо ви цього не зробите, люди будуть ненавидіти вас, і ви будете зневажати друзів та родичів.

    Коли ви перебазуєте матеріали, ви відмовляєтеся від існуючих комітів і створюєте нові, схожі, але різні. Якщо ви куди-небудь натискаєте комітети, а інші витягують їх і базують на них роботу, а потім ви переписуєте ці комісії з git rebase і знову підштовхуєте їх, вашим співробітникам доведеться знову об'єднати свою роботу, і все стане брудно, коли вони намагаються потягніть їх роботу назад у вашу.

    [...]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.