Як повернути всі локальні зміни проекту, керованого Git, до попереднього стану?


1913

У мене є проект, в який я балотувався git init. Після кількох комітетів я зробив це, в git statusякому розповів, що все актуально, і місцевих змін не було.

Тоді я вніс кілька послідовних змін і зрозумів, що хочу відкинути все і повернутися до свого початкового стану. Чи зробить це командування для мене?

git reset --hard HEAD

Відповіді:


3388

Якщо ви хочете відновити зміни, внесені до вашої робочої копії, зробіть це:

git checkout .

Якщо ви хочете повернути зміни, внесені до індексу (тобто додані вами), зробіть це. Попередження це скине всі ваші незапущені зобов'язання для майстра! :

git reset

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

git revert <commit 1> <commit 2>

Якщо ви хочете видалити незатребувані файли (наприклад, нові файли, згенеровані файли):

git clean -f

Або неперевірені каталоги (наприклад, нові або автоматично створені каталоги):

git clean -fd

133
fwiw через такий довгий час git checkout path/to/fileповерне лише місцеві зміни доpath/to/file
Matijs

29
+1 у відповідях нижче, також згадується git clean -f (для видалення неперевірених змін) та -fd (щоб також видалити незатребувані каталоги)
ptdev

3
і якщо ви хочете , щоб очистити ваші неотслежіваемих файли, читати цей stackoverflow.com/questions/61212 / ...
Surasin Танчароен

9
git checkout .і git reset [--hard HEAD]нічого не вийшло, мені довелося зробити git clean -fdскасування змін.
BrainSlugs83

7
git resetне скидає зміни, git reset --hardчи це робить.
Серін

388

Примітка. Ви також можете запустити

git clean -fd

як

git reset --hard

буде НЕ видаляти файли неотслежіваемих, де , як ГИТ-чистий видалять файли з гусеничної кореневої директорії, що не знаходиться під мерзотником трекінгу. Попередження - будьте обережні з цим! Корисно спочатку запустити сухий запуск з git-clean, щоб побачити, що воно видалить.

Це також особливо корисно, коли ви отримуєте повідомлення про помилку

~"performing this command will cause an un-tracked file to be overwritten"

Що може статися під час виконання декількох речей, одна з них - це оновлення робочої копії, коли ви та ваш друг додали новий файл з тим самим іменем, але він переніс його спочатку в керування джерелом, і вам не байдуже видалення вашої нерозробленої копії .

У цій ситуації сухе виконання також допоможе показати вам список файлів, які будуть перезаписані.


13
Команда clean file - "git clean -f". Неназвані каталоги видаляються з "git clean -d"
Джонатан Мітчелл

35
git clean -fd (сила потрібна для -d)
electblake

14
-n або --dry-run - це прапори для бігової роботи.
stephenbez

2
git clean -ffd, якщо у вашому сховищі git є ще одне сховище git. Без подвійного f його не було б знято.
Трисмегістос

148

Повторний клон

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Видаляє локальні, не натиснуті коміти
  • ✅ Повертає зміни, які ви внесли до відстежуваних файлів
  • Відновлення відстежених файлів, які ви видалили
  • ✅ Видаляє файли / бруски, перелічені в .gitignore(як файли збірки)
  • Видаляє файли / бруски, які не відстежуються та не входять .gitignore
  • This Ви не забудете такий підхід
  • 😔 Пропускна здатність відходів

Далі йдуть інші команди, які я щодня забуваю.

Очистити та скинути

git clean --force -d -x
git reset --hard
  • ❌ Видаляє локальні, не натиснуті коміти
  • ✅ Повертає зміни, які ви внесли до відстежуваних файлів
  • Відновлення відстежених файлів, які ви видалили
  • ✅ Видаляє файли / бруски, перелічені в .gitignore(як файли збірки)
  • Видаляє файли / бруски, які не відстежуються та не входять .gitignore

Чисто

git clean --force -d -x
  • ❌ Видаляє локальні, не натиснуті коміти
  • ❌ Повертає зміни, які ви внесли до відстежуваних файлів
  • Відновлення відстежених файлів, які ви видалили
  • ✅ Видаляє файли / бруски, перелічені в .gitignore(як файли збірки)
  • Видаляє файли / бруски, які не відстежуються та не входять .gitignore

Скидання

git reset --hard
  • ❌ Видаляє локальні, не натиснуті коміти
  • ✅ Повертає зміни, які ви внесли до відстежуваних файлів
  • Відновлення відстежених файлів, які ви видалили
  • ❌ Видаляє файли / бруски, перелічені в .gitignore(як файли збірки)
  • Видаляє файли / бруски, які не відстежуються та не входять .gitignore

Примітки

Тест для підтвердження всього вищесказаного (використовуйте bash або sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

Дивись також

  • git revert робити нові коміти, які скасовують попередні зобов’язання
  • git checkout щоб повернутися в часі до попередніх комісій (може знадобитися спочатку виконання вище команд)
  • git stashте саме, що git resetвище, але ви можете скасувати його

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

1
Я майже впевнений, що перший варіант ( повторний клон ) насправді "видаляє локальні, не натиснуті коміти" :)
Маранділ

1
@styfle ✅ це те, що він робить, ❌ це те, чого не робить
William Entriken

3
@FullDecent Читати це щось незрозуміло. "❌ НЕ видаляє локальні, не натиснуті коміти". Це означає, що він НЕ видаляється. Подвійний мінус означає, що він видаляє?
стифл

1
Про прапор -x у git clean -f -d -x: якщо вказано параметр -x, ігноровані файли також видаляються. Наприклад, це може бути корисно для видалення всіх
Алекс

82

Якщо ви хочете відновити всі зміни ТА бути в курсі поточного віддаленого майстра (наприклад, ви виявите, що головна HEAD рухалася вперед з моменту розгалуження, а ваш поштовх "відхилений"), ви можете використовувати

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.

Здається, важливо вказати originв git reset --hard origin/master(що працює) - без нього (тобто git reset --hard) нічого, здається, не змінилося.
Джейк

У мене були деякі локальні зміни, і я не зміг їх позбутися жодною командою, яку я змінив - git reset --hard origin / master, і він також зміг втягнути зміни господаря
abhishek Ringia

50

Загляньте в git-reflog. У ньому будуть перераховані всі стану, які він запам'ятовує (за замовчуванням - 30 днів), і ви можете просто перевірити потрібне. Наприклад:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d

спасибі тоні Вільгельма, за git reflog. Я скидаю дерево до старої версії і не знаю, як повернутися до останньої. ваш git reflog врятував мене. Ще раз дякую
palaniraja

1
врятував і мене! У моєму випадку моя пригода з git rebase -iпішла не так (врешті-решт, витираючи деякі повідомлення через помилку редагування). Завдяки цій підказці я знову в хорошому стані!
paneer_tikka

Що ви маєте на увазі за замовчуванням 30 днів !?
Mohe TheDreamy

@MoheTheDreamy Я маю на увазі, що є обмеження в часі. Врешті-решт сміттєзбірник видалить недосяжні посилання, коли їх вік перевищить цю межу. За замовчуванням раніше було (а може й досі) 30 днів. Тому старі посилання можуть бути недоступними.
Вільям Перселл

36

НЕБЕЗПЕЧНО ВЗАЄМО: (будь ласка, прочитайте коментарі. Виконання команди, запропонованої у моїй відповіді, може видалити більше, ніж ви хочете)

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

git clean -f -d

13
Щоб врятувати комусь біль, яку я щойно пережив: це також видалить .gitignore-d файли!
лендос

вибачте, якщо я заподіяв вам якісь клопоти. Тоді я просто намагався повернути та видалити все, що знаходиться в цій папці. Я не пам'ятаю точних обставин, але "-d" було єдиним, що працювало для мене. Сподіваюся, я не заподіяв вам занадто сильного болю :-)
Тобіас Гассманн

1
шкоди не завдано. У мене були резервні копії, але це, ймовірно, є підставою для відмови;)
приземлення

35

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

Ось мій поточний сценарій bash для його виконання, який працює весь час.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

Запустити з робочого кореневого каталогу копіювання.


10
Остання команда дає меніerror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L

1
Мені це спрацювало, коли я вийняв "-". git checkout HEAD
Шут

4
git reset --hardповертає відслідковані файли (поетапно чи ні), git clean -f -dвидаляє не відстежені файли, git checkout -- HEADнавіщо нам це потрібно?
в.шашенко

Нам не потрібен подвійний дефіс. Повинно бути друком.
Farax

35

просто виконати -

git stash

це видалить усі ваші локальні зміни. і ви також можете використовувати його пізніше, виконавши -

git stash apply 

3
використання git stash popавтоматично видалить кращі приховані зміни для вас
Arrow Cen

8
git stash dropщоб видалити останнє сховане стан, не застосовуючи робочу копію.
deerchao

git stash застосувати звичку додати новостворені файли
Ravistm

27

Я зустрів подібну проблему. Рішення полягає в тому, git logщоб знайти, яка версія локального комітету відрізняється від віддаленої. (Наприклад, версія є3c74a11530697214cbcc4b7b98bf7a65952a34ec ).

Потім скористайтеся git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ecдля відновлення зміни.


16

Я шукав подібну проблему,

Хотіли викинути місцеві комітети:

  1. клонований сховище (git clone)
  2. перейшов на відділення dev (git checkout dev)
  3. зробив декілька комітів (git commit -m "počinши 1")
  4. але вирішив відкинути ці місцеві зобов’язання, щоб повернутися до віддаленого (origin / dev)

Це робилося нижче:

git reset --hard origin/dev

Перевірка:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

тепер місцеві комітети втрачені, повертаючись до початкового клонованого стану, пункт 1 вище.


1
дякую, це єдине, що працювало для мене - "git reset - тверде походження"
Nisim Naim

рада дізнатися, що це допомогло.
Манохар Редді Поредді

7

Вам не обов’язково потрібно / потрібно зберігати свою роботу / файли у робочому каталозі, а натомість просто позбутися від них повністю. Командаgit clean зробить це за вас.

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

Майте на увазі, що ви хочете бути дуже обережними щодо цієї команди, оскільки вона призначена для видалення файлів із локального робочого каталогу, які НЕ ВІДКРИТИ. якщо ви раптом передумаєте після виконання цієї команди, немає можливості повернутися до вмісту видалених файлів. Більш безпечною є альтернатива

git stash --all

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

Однак якщо ви дійсно хочете видалити всі файли та очистити робочий каталог, вам слід виконати

git clean -f -d

Це видалить будь-які файли, а також будь-які підкаталоги, у яких в результаті команди немає елементів. Розумна річ, яку потрібно зробити перед виконанням git clean -f -dкоманди, - це запустити

git clean -f -d -n

який покаже попередній перегляд того, що буде видалено після виконання git clean -f -d

Отже, ось короткий опис ваших варіантів від найбільш агресивних до найменш агресивних


Варіант 1 : Видалити всі файли локально (найбільш агресивно)

git clean -f -d

Варіант 2 : Попередній перегляд вищевказаного впливу (Попередній перегляд найбільш агресивного)

git clean -f -d -n

Варіант 3 : Заховайте всі файли (найменш агресивні)

`git stash --all` 

6

Спробуйте це відновити всі зміни, не виконані в місцевому відділенні

$ git reset --hard HEAD

Але якщо ви бачите подібну помилку:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

Ви можете перейти до папки ".git", а потім видалити файл index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

Нарешті, запустіть ще раз команду:

$ git reset --hard HEAD

0

Це питання стосується більш широкого скидання / відновлення сховища, але у випадку, якщо ви зацікавлені в тому, щоб змінити окремі зміни - тут я додав подібну відповідь:

https://stackoverflow.com/a/60890371/2338477

Відповіді на запитання:

  • Як відновити окремі зміни із збереженням змін без збереження в історії git

  • Як повернутися до старої версії, щоб перезапустити з того самого стану

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