Видалити видалений файл у git


504

Зазвичай, щоб скасувати зміни у файлі, ви зробили б:

git checkout -- <file>

Що робити, якщо зміна, яку я хочу скасувати, - це видалення файлу? Вищенаведений рядок призведе до помилки:

error: pathspec '<file>' did not match any file(s) known to git.

Яка команда відновить цей єдиний файл, не скасовуючи інші зміни?

бонусний бал: А що робити, якщо зміна, яку я хочу скасувати, додає файл? Я хотів би також знати, як знехтувати ці зміни.


1
Відмовитись від змін та зняття змін - це дві різні речі, які ви намагаєтесь зробити?
Ендрю Маршалл

1
Це два різні питання та проблеми в одному дописі. Це робить відповіді занадто занадто і непотрібними заплутаними.
Давид Сопко

Відповіді:


778

Якщо припустити, що ви хочете скасувати наслідки git rm <file>чи rm <file>слідувати за ними git add -Aчи щось подібне:

# this restores the file status in the index
git reset -- <file>
# then check out a copy from the index
git checkout -- <file>

Щоб скасувати git add <file>, достатньо першого рядка вище, якщо ви ще не зробили цього.


69
--Є ключовим. git reset <file>не працює, що мене привело сюди.

Але це також відновить усі модифікації. що робити, якщо я хочу відновити лише всі видалені файли. І не змінюйте всі модифікації.
Дайній Крейвіс

2
Чому це end-of-options-markerпотрібно лише у випадку видаленого файлу?
haridsv

4
@handsv Це не суворо потрібно (ви можете по черзі робити це git reset HEAD <file>, що еквівалентно), але git resetперший аргумент раніше трактується end-of-options-markerяк ім'я посилання, а не ім'я файлу. Чи можна було це написати трохи гнучкіше? Мабуть. Чому не було? Напевно, лише розробники знають точно.
twalberg

2
@twalberg git reset filenameпрекрасно працює для видалених файлів.
Брайан Гордон

56

На обидва запитання відповідає відповідь git status.

Щоб нестабільно додати нове використання файлу git rm --cached filename.ext

# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   test

Щоб нестабільно видалити використання файлу git reset HEAD filename.ext

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    test

З іншого боку, git checkout --ніколи нестабільна, вона просто відкидає нестадійні зміни.


5
Я не бачу підказки на видалений файл у git 1.7.2.5 на Debian.
tripleee

Приємно бачити git statusцитованими; показує користувачам спосіб самостійної допомоги зараз та в наступний раз, а також у випадку, якщо інформація буде додана або оновлена ​​у майбутніх версіях git.
Буде Каїн

Це неправильно. "Зміни, які потрібно здійснити" - це те, що ви бачите перед цим git reset. Після цього git reset, ви бачите "Змінено, але не оновлено", що, мабуть, означає "Зміни не інсценовані" рідною мовою авторів git. Що ще важливіше, вся догма про те, що "git status говорить вам усе, що ви знаєте" - брехня. (Менеджери, які кажуть, що витрачають час на людей і повинні бути звільнені.)
personal_cloud

11

Відповіді на ваші два запитання пов'язані. Почну з другого:

Після того як ви інсценіруєте файл (часто з git add, хоча деякі інші команди неявно також стадіюють зміни, як-от git rm), ви можете відмовитись від зміни git reset -- <file>.

У вашому випадку ви, мабуть, використовували git rmдля видалення файлу, що еквівалентно простому його видаленню, rmа потім інсценізації цієї зміни. Якщо ви спочатку його знеструмите, git reset -- <file>ви можете відновити його git checkout -- <file>.


7

Якщо він був інсценований та скоєний, то файл скине:

git reset COMMIT_HASH file_path
git checkout COMMIT_HASH file_path
git add file_path

Це буде працювати для видалення, яке відбулося декілька попередніх комісій.


1
Це ефективнішеgit revert COMMIT_HASH
Flair

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