Як можна скасувати останню додавання git?


193

Чи можна знехтувати останню поетапну (не вчинену) зміну в git ? Припустимо, в поточній гілці було багато файлів, деякі ставили, а деякі ні. У якийсь момент якийсь нерозумний програміст випадково стратив:

git add -- .

...замість:

git checkout -- .

Чи може тепер цей програміст не відчути останніх змін за допомогою якоїсь магічної команди git ? Або він повинен був здійснити, перш ніж експериментувати в першу чергу?


Хе. Однак ми отримали корисне запитання та відповідь.
steveha

2
можливий дублікат Undo 'git add' перед фіксацією
Jim Fell

Я вважаю, що це не дублікат. ОП в іншому запитанні просить спосіб скасувати це або видалити ці файли з фіксації. Я хочу (редагувати) точно і лише скасувати зміни, додані останньою git addкомандою, особливо для файлів, які вже мали поетапні зміни та мали деякі зміни, які слід було скасувати, а не поетапно. Не можу сказати, що інше питання не пов'язане.
Септаграма

1
Можливо, він повинен був / був / вчинений перед експериментом в першу чергу.
android.weasel

@ android.weasel так, це було багато років тому ...
Септаграма

Відповіді:


299

Можна використовувати git reset. Це призведе до нестабільності всіх файлів, які ви додали після останнього виконання.

Якщо ви хочете видалити лише деякі файли, використовуйте git reset -- <file 1> <file 2> <file n>.

Також можна усунути деякі зміни у файлах, використовуючи git reset -p.


3
Як сумно. Я думаю, що в моїх практиках вчинення справді щось не так. Приймаючи цю відповідь, тому що ви згадали -pперемикач. Дякую! :)
Септаграма

Породжує (для мене) помилку: фатально: Не вдалося вирішити 'HEAD' як дійсний номер. Я ще нічого не зробив (нове репо) тільки що додав git add. і шкодував про це. Я не хочу скидати всю додавання, лише одну директорію. git reset - dir /*.* генерує помилку вище.
Френсіс Деві

... Ах, я бачу, що в мене відбувається. У мене нічого не було, щоб HEAD вказував, і тому скидання git не вдалося (оскільки воно працює на HEAD).
Френсіс Деві

42

Ви не можете скасувати останнє додавання git, але ви можете скасувати всі adds з моменту останнього виконання. git resetбез аргументу комісії скидає індекс (нестабільність поетапних змін):

git reset

2
"Ви не можете скасувати останнє додавання git": О, це дивно і потенційно боляче. Чи є для цього остаточне джерело? Також, чи є вагома причина, що так і має бути? Дякую!
Ендрю Майлан

@AndrewMoylan: ну, немає автоматичного способу зробити це. Ви завжди можете resetстворити один файл або використати reset -pдля відмежування певного елемента.
knittl

15

Тож справжня відповідь на

Чи може тепер цей програміст не відчути останніх змін за допомогою якоїсь магічної команди git?

насправді: Ні, ви не можете знімати лише останню git add.

Тобто, якщо ми трактуємо питання як у такій ситуації:

Початковий файл:

void foo() {

}

main() {
    foo();
}

Перша зміна, а потім git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Друга зміна з наступним git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

У цьому випадку git reset -pне допоможе, оскільки його найменша деталізація - це лінії. gitне знає, що про проміжний стан:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

більше.


Я підкреслив, тому що, як новий користувач git, це дійсно важлива відмінність, яка підкреслює те, що мої друзі описують як "хороша гігієна перевірки" ... мій особистий досвід - це було описано як "автопоїзд" (погано!).
benc


3

На сьогоднішній день підказки git:

  1. use "git rm --cached <file>..." to unstageякщо файлів не було в репо. Це знеструмлює файли, що зберігають їх там.
  2. use "git reset HEAD <file>..." to unstageякщо файли були в репо, і ви додаєте їх як змінені. Він зберігає файли такими, які вони є, і знеструмлює їх.

git add --Наскільки мені відомо, ви не можете скасувати, але ви можете скасувати список файлів, як згадувалося вище.


2
  • Вийміть файл з індексу, але нехай він залишається впорядкованим і залишений із невиправленими змінами в робочій копії:

    git reset head <file>
    
  • Скиньте файл до останнього стану з HEAD, скасувавши зміни та видаливши їх з індексу:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Це потрібно, оскільки git reset --hard HEADне працюватиме з одним файлом.

  • Видаліть <file>з індексу та версії, зберігаючи необроблений файл із змінами в робочій копії:

    git rm --cached <file>
    
  • <file>Повністю видаліть із робочої копії та версії версії:

    git rm <file>
    

2

Якщо ви хочете видалити всі додані файли з git для фіксації

git reset

Якщо ви хочете видалити окремий файл

git rm <file>

1

Можна використовувати

git reset

щоб скасувати нещодавно додані локальні файли

 git reset file_name

щоб скасувати зміни для певного файлу


0

Залежно від розміру і масштабу складно, ви можете створити подряпину (тимчасову) гілку і здійснити там поточну роботу.

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

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

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