Удалить файлы из Git commit

Я использую Git, и я сделал несколько файлов, используя

git commit -a

Позже я обнаружил, что файл был ошибочно добавлен в коммит.

Как удалить файл из последнего коммита?

849
задан Mojoy 18 сент. '12 в 19:59
источник поделиться

19 ответов

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

git reset --soft HEAD^ 

или

git reset --soft HEAD~1

Затем reset нежелательные файлы, чтобы оставить их вне коммита:

git reset HEAD path/to/unwanted_file

Теперь повторите попытку, вы можете повторно использовать одно и то же сообщение фиксации:

git commit -c ORIG_HEAD  
1673
ответ дан juzzlin 10 марта '13 в 13:56
источник поделиться

Внимание! Если вы хотите удалить файл из своего предыдущего коммита и сохранить его на диске, прочитайте juzzlin answer чуть выше.

Если это ваша последняя фиксация и вы хотите полностью удалить файл из своего локального и удаленного репозитория, вы можете:

  • удалите файл git rm <file>
  • commit с флагом изменения: git commit --amend

Флаг исправления сообщает git снова зафиксировать, но "слить" (не в смысле слияния двух ветвей) это зафиксировать с последним фиксатором.

И чтобы сказать это как yo, команда rm в git делает то, что делает сама rm!

168
ответ дан CharlesB 18 сент. '12 в 20:22
источник поделиться

Существующие ответы говорят об удалении нежелательных файлов из фиксации last.

Если вы хотите удалить ненужные файлы из старой фиксации (даже нажатой) и не хотите создавать новую фиксацию, что необязательно, из-за действия:

1.

Найдите фиксацию, которой вы хотите, чтобы файл соответствовал.

git checkout <commit_id> <path_to_file>

вы можете сделать это несколько раз, если вы хотите удалить много файлов.

2.

git commit -am "remove unwanted files"

3.

Найти commit_id commit , по которому файлы были добавлены ошибочно, скажем, "35c23c2" здесь

git rebase 35c23c2~1 -i  // notice: "~1" is necessary

Эта команда открывает редактор в соответствии с вашими настройками. По умолчанию используется vim.

Переместить последнюю фиксацию, которая должна быть "удалить ненужные файлы", на следующую строку неправильного коммита ( "35c23c2" в нашем случае) и установить команду как fixup:

pick 35c23c2 the first commit
fixup 0d78b28 remove unwanted files

После сохранения файла вам должно быть хорошо.

Чтобы закончить:

git push -f

Если вы, к сожалению, получаете конфликты, вы должны решить их вручную.

75
ответ дан Brian 27 янв. '15 в 18:24
источник поделиться

Удаление файла с помощью rm удалит его!

Вы всегда добавляете фиксацию в git, а не удаляете, поэтому в этом экземпляре возвращаете файл в состояние, в котором оно находилось до первого коммита (это может быть действие delete "rm", если файл является новым), а затем повторно зафиксировать и файл пойдет.

Чтобы вернуть файл в предыдущее состояние:

    git checkout <commit_id> <path_to_file>

или вернуть его в состояние на удаленной HEAD:

    git checkout origin/master <path_to_file>

затем измените фиксацию, и вы должны найти, что файл исчез из списка (и не удаляется с вашего диска!)

30
ответ дан Bob Flannigon 28 янв. '13 в 17:00
источник поделиться

Если вы не нажали изменения на сервере, вы можете использовать

git reset --soft HEAD~1

Он будет reset всех изменений и вернется к одной фиксации назад

Если вы нажали свои изменения, выполните следующие шаги, как указано в @CharlesB

28
ответ дан Paritosh Singh 18 сент. '12 в 21:28
источник поделиться
git checkout HEAD~ path/to/file
git commit --amend
27
ответ дан Denis Shchepetov 23 авг. '13 в 22:01
источник поделиться

Как показывает принятый ответ, вы можете сделать это, сбросив всю фиксацию. Но это довольно тяжелый подход.
Более чистый способ сделать это - сохранить фиксацию и просто удалить из нее измененные файлы.

git reset HEAD^ -- path/to/file
git commit --amend --no-edit

git reset возьмет файл так же, как и в предыдущем коммите, и сгенерирует его в индексе. Файл в рабочем каталоге не тронут.
Затем git commit фиксирует и выдавливает индекс в текущую фиксацию.

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

25
ответ дан Patrick 25 февр. '17 в 3:06
источник поделиться

Следующее приведет к отключению только файла, который вы намеревались, что и требовал OP.

git reset HEAD^ /path/to/file

Вы увидите что-то вроде следующего...

Изменения, которые необходимо совершить: (используйте "git reset HEAD..." для неустановления)

modified:/path/to/file

Изменения не выполняются для фиксации: (используйте "git add..." для обновления что будет сделано) (используйте "git checkout -...", чтобы отменить изменения в рабочем каталоге)

modified:/path/to/file

  • "Изменения, которые необходимо совершить" - это предыдущая версия файла перед фиксацией. Это будет выглядеть как удаление, если файл никогда не существовал. Если вы сделаете это изменение, появится ревизия, которая вернет изменение в файл в вашей ветке.
  • "Изменения не поставлены для фиксации" - это сделанное вами изменение и текущее состояние файла

В этот момент вы можете делать все, что захотите, в файл, например, сбросить в другую версию.

Когда вы готовы к фиксации:

git commit --amend -a

или (если у вас есть другие изменения, которые вы еще не хотите совершать)

git commit add /path/to/file
git commit --amend
24
ответ дан ThatsAMorais 07 дек. '14 в 10:13
источник поделиться

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

git checkout origin/<remote-branch> <filename>
git commit --amend
8
ответ дан mattexx 17 июня '13 в 23:07
источник поделиться
git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "removed unwanted file from git"

оставит вас локальным файлом. Если вы также не хотите, чтобы файл был локальным, вы можете пропустить параметр --cached.

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

git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit --squash <commit_id>
git add <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "brand new file!"
git rebase --interactive <commit_id>^

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

6
ответ дан Bryan Buckley 23 февр. '16 в 9:22
источник поделиться

Использование git GUI может упростить удаление файла из предшествующего коммита.

Предполагая, что это не разделяемая ветка, и вы не возражаете переписываете историю, затем выполните:

git gui citool --amend

Вы можете отменить файл, который был ошибочно зафиксирован, а затем нажать "Зафиксировать".

enter image description here

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

6
ответ дан JDiMatteo 18 мая '15 в 22:50
источник поделиться

Выполните последовательность из следующих команд:

//to remove the last commit, but preserve changes  
git reset --soft HEAD~1

//to remove unneded file from the staging area  
git reset HEAD `<your file>` 

//finally make a new commit  
git commit -m 'Your message'
5
ответ дан Sergey Onishchenko 10 сент. '15 в 14:51
источник поделиться

Я объясню вам пример Пусть A, B, C - 3 последовательных фиксации. Commit B содержит файл, который не должен был быть зафиксирован.

  • $git log # take A commmit_id
  • $git rebase -i "A_ID"
  • изменить фиксацию на 'e' в rebase vim
  • $git rm unwanted_file
  • $git rebase continue
  • $git push -force
3
ответ дан Moaz Rashad 17 авг. '17 в 12:52
источник поделиться

Просто хотел дополнить верхний ответ, поскольку мне пришлось выполнить дополнительную команду:

git reset --soft HEAD^
git checkout origin/master <filepath>

Ура!

3
ответ дан andrepo 25 мая '16 в 18:24
источник поделиться

Что-то, что сработало для меня, но все же думаю, что должно быть лучшее решение:

$ git revert <commit_id>
$ git reset HEAD~1 --hard

Просто оставьте изменение, которое вы хотите отменить в другом коммите, проверьте других.

$ git commit --amend // or stash and rebase to <commit_id> to amend changes
2
ответ дан saiyancoder 14 авг. '14 в 8:34
источник поделиться

На самом деле, я думаю, что более быстрый и простой способ - использовать интерактивный режим git.

git rebase -i head~1  

(или голова ~ 4, как далеко вы хотите идти)

а затем вместо 'pick' используйте 'edit'. Я не понял, насколько мощным является "редактирование".

https://www.youtube.com/watch?v=2dQosJaLN18

Надеюсь, вам понравится.

1
ответ дан Matt 19 мая '16 в 23:58
источник поделиться

Имел ту же проблему, когда у меня есть изменения в локальной ветке, где я хотел вернуть только один файл. Что для меня работало -

(feature/target_branch), где у меня есть все мои изменения, в том числе те, которые я хотел отменить для определенного файла)

(origin/feature/target_branch) - это удаленная ветка, в которую я хочу внести изменения)

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

  • Создайте локальную ветку из моего origin/feature/target_branch - назвали ее функцией/постановкой

  • Слияние моей локальной локальной ветки feature/target_branch с веткой

  • Проверено функция/постановка, затем git reset --soft ORIG_HEAD (теперь все изменения из функции/стадии "будут организованы, но незафиксированный.)

  • Неустановленный файл, который я ранее проверил, с ненужными изменениями

  • Изменена ветвь восходящего потока для функции/постановки в origin/feature/target_branch

  • Переделал остальные поэтапные изменения и нажал вверх по течению до моего удаленного источника/функции/target_branch

1
ответ дан user1201303 23 янв. '17 в 7:13
источник поделиться

Если вы еще не нажали фиксацию, GitHub Desktop легко решает эту проблему:

  • Выберите репозиторий → Отменить последнюю фиксацию
  • Отмените выбор файла, который вы по ошибке добавили. Ваше предыдущее сообщение о фиксации будет уже в диалоговом окне.
  • Нажмите кнопку фиксации!
1
ответ дан Ron 14 марта '17 в 22:41
источник поделиться

Если вам больше не нужен этот файл, вы можете сделать

git rm file
git commit --amend
git push origin branch
0
ответ дан tven 29 сент. '17 в 0:49
источник поделиться

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