Reset або повернути конкретний файл в конкретну ревізію за допомогою Git?

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

Я зробив git log разом з git diff , щоб знайти потрібний мені варіант, але просто не знаю, як повернути файл до свого попереднього стану в минулому.

3786
19 окт. заданий Hates_ 19 Жовтня. 2008-10-19 02:34 '08 о 2:34 2008-10-19 2:34
ответ 31 відповідь
  • 1
  • 2

Припускаючи, що хеш коммітов, який ви хочете, c5f567 :

 git checkout c5f567 -- file1/to/restore file2/to/restore 

Сторінка керівництва git checkout дає більше інформації.

Якщо ви хочете повернутися до фіксації до c5f567 , додайте ~1 (працює з будь-яким числом):

 git checkout c5f567~1 -- file1/to/restore file2/to/restore 

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

5117
19 окт. відповідь дан Greg Hewgill 19 Жовтня. 2008-10-19 02:39 '08 о 2:39 2008-10-19 2:39

Ви можете швидко переглянути зміни, внесені в файл, використовуючи команду diff:

 git diff <commit hash> <filename> 

Потім, щоб повернути конкретний файл цього фіксатора, використовуйте команду reset:

 git reset <commit hash> <filename> 

Можливо, вам доведеться використовувати опцію --hard , якщо у вас є локальні модифікації.

border=0

Хорошим документообігом для управління точками є використання тегів для чистоти точок на вашій часовій шкалі. Я не можу зрозуміти ваше останнє речення, але те, що вам може знадобитися, - це розбіжність гілки з попереднього моменту часу. Для цього використовуйте зручну команду checkout:

 git checkout <commit hash> git checkout -b <new branch name> 

Потім ви можете перевстановити це проти своєї основної лінії, коли будете готові об'єднати ці зміни:

 git checkout <my branch> git rebase master git checkout master git merge <my branch> 
541
17 дек. відповідь дан Chris Lloyd 17 дек. 2008-12-17 09:59 '08 о 9:59 2008-12-17 9:59

Ви можете використовувати будь-яке посилання на фіксацію git, включаючи SHA-1, якщо це найзручніше. Справа в тому, що команда виглядає так:

git checkout [commit-ref] -- [filename]

319
08 апр. відповідь дан foxxtrot 08 Квітня. 2009-04-08 00:48 '09 в 0:48 2009-04-08 00:48
 git checkout -- foo 

Це буде reset foo для HEAD. Ви також можете:

 git checkout HEAD^ foo 

для однієї ревізії і т.д.

256
29 авг. відповідь дан Greg Hewgill 29 Серпня. 2008-08-29 23:56 '08 о 23:56 2008-08-29 23:56

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

 git checkout HEAD file/to/restore 
114
14 янв. відповідь дан CDR 14 Січня. 2012-01-14 09:15 '12 о 9:15 2012-01-14 9:15

У мене була така ж проблема тільки зараз, і я знайшов цю відповідь найпростіше зрозуміти ( commit-ref - значення SHA зміни в журналі, який ви хочете відправити назад):

 git checkout [commit-ref] [filename] 

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

102
27 мая '09 в 20:52 2009-05-27 20:52 відповідь дан bbrown 27 травня '09 о 20:52 2009-05-27 20:52

Якщо ви знаєте, скільки коммітов вам потрібно повернутися, ви можете використовувати:

 git checkout master~5 image.png 

Передбачається, що ви перебуваєте в гілці master , а бажана версія - 5.

88
07 апр. відповідь дан Ron DeVera 07 Квітня. 2009-04-07 17:03 '09 о 17:03 2009-04-07 17:03

Я думаю, що знайшов ... від http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

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

Почніть з:

$ git log

який показує вам список останніх коммітов і їх хеш SHA1.

Потім введіть:

$ git reset --hard SHA1_HASH

щоб відновити стан для даної фіксації і стерти всі нові записи з записи назавжди.

78
17 дек. відповідь дан jdee 17 дек. 2008-12-17 09:53 '08 в 9:53 2008-12-17 9:53

Це спрацювало для мене:

 git checkout <commit hash> file 

Потім зафіксуйте зміна:

 git commit -a 
61
26 авг. відповідь дан v2k 26 Серпня. 2011-08-26 01:12 '11 о 1:12 2011-08-26 1:12

Ви повинні бути обережні, коли говорите "відкат". Якщо ви використовували одну версію файлу в commit $ A, а потім зробили два зміни в двох окремих коммітов $ B і $ C (так що ви бачите, це третя ітерація файлу), і якщо ви скажете "Я хочу повернутися до першого", ви дійсно це маєте на увазі?

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

 $ git checkout $A file 

а потім ви фіксуєте результат. Команда запитує "Я хочу перевірити файл зі стану, записаного фіксацією $ A".

З іншого боку, те, що ви мали на увазі, це позбавитися від зміни другої ітерації (тобто зробити $ B), при збереженні того, що зафіксував файл $ C в файлі, ви хотіли б повернути $ B

 $ git revert $B 

Зверніть увагу: хоч би хто створював commit $ B, можливо, не був дуже дисциплінований і міг зробити абсолютно незв'язані зміни в одній і тій же фіксації, і це повернення може стосуватися файлів, відмінних від файлу, який ви бачите, образливі зміни, тому ви можете перевірити результат ретельно після цього.

54
11 янв. відповідь дан gitster 11 Січня. 2009-01-11 11:13 '09 о 11:13 2009-01-11 11:13

Цікаво, 'git checkout foo' не працюватиме, якщо робоча копія знаходиться в каталозі з іменем foo; однак, як "w20> checkout HEAD foo" і "git checkout./foo" буде:

 $ pwd /Users/aaron/Documents/work/foo $ git checkout foo D foo Already on "foo" $ git checkout ./foo $ git checkout HEAD foo 
36
30 авг. відповідь дан Aaron Maenpaa 30 Серпня. 2008-08-30 00:26 '08 в 0:26 2008-08-30 00:26

Тут rebase працює:

 git checkout <my branch> git rebase master git checkout master git merge <my branch> 

Припустимо, що у вас є

 ---o----o----o----o master \---A----B <my branch> 

Перші дві команди ... зробити git виписка git майстер переустановлення

... перевірте гілка змін, які ви хочете застосувати до гілки master . Команда rebase бере коммітов з <my branch> (які не знайдені в master ) і повторно застосовує їх до заголовку master . Іншими словами, батьківський елемент першого коммітов в <my branch> більше не є попереднім фіксатором в історії master , а поточним заголовком master . Дві команди такі ж, як:

 git rebase master <my branch> 

Можливо, було б легше запам'ятати цю команду, так як гілки "base" і "modify" явно.

. Кінцевий результат:

 ---o----o----o----o master \----A'----B' <my branch> 

Останні дві команди ...

 git checkout master git merge <my branch> 

... виконайте швидке злиття для застосування всіх змін <my branch> на master . Без цього кроку фіксація rebase не додають до master . Кінцевий результат:

 ---o----o----o----o----A'----B' master, <my branch> 

master і <my branch> обидві посилання B' . Крім того, з цієї точки можна безпечно видалити посилання <my branch> .

 git branch -d <my branch> 
32
24 февр. відповідь дан cmcginty 24 февр. 2009-02-24 12:43 '09 о 12:43 2009-02-24 12:43

git -аліаси, awk і функції оболонки для порятунку!

 git prevision <N> <filename> 

де <N> - це кількість виправлень файлу для відкату для файлу <filename> .
Наприклад, щоб перевірити негайну попередню ревізію одного файлу x/y/zc , запустіть

 git prevision -1 x/y/zc 

Як працює git предікція?

Додайте в свій gitconfig

наступне:
 [alias] prevision = "!f() { git checkout `git log --oneline $2 | awk -v commit="$1" 'FNR == -commit+1 {print $1}'` $2;} ;f" 

Команда в основному

  • виконує git log в зазначеному файлі і
  • вибирає відповідний ідентифікатор фіксації в історії файлу і
  • виконує git checkout ідентифікатор commit для зазначеного файлу.

По суті, все, що можна було б зробити вручну в цій ситуації,
загорнутий в один красивий, ефективний git -alias - git-prevision

21
01 мая '15 в 4:46 2015-05-01 04:46 відповідь дан TheCodeArtist 01 травня '15 в 4:46 2015-05-01 4:46

Мені потрібно підключити EasyGit тут, який є обгорткою, щоб зробити git більш доступним для новачків, які не заплутуючи досвідчених користувачів. Одна з речей, які вона робить, - дає більше значень git revert . В цьому випадку ви просто скажете:

eg revert foo/bar foo/baz

20
19 окт. відповідь дан Aristotle Pagaltzis 19 Жовтня. 2008-10-19 03:16 '08 в 3:16 2008-10-19 3:16

У разі, якщо ви хочете повернути файл в попередню фіксацію (і файл, який ви хочете повернути вже зафіксовано), ви можете використовувати

 git checkout HEAD^1 path/to/file 

або

 git checkout HEAD~1 path/to/file 

Потім просто виконайте етап і зафіксуйте "нову" версію.

Озброївшись знаннями про те, що в разі злиття commit може мати двох батьків, ви повинні знати, що HEAD ^ 1 є першим батьком, а HEAD ~ 1 є другим батьком.

Або буде працювати, якщо в дереві є тільки один батько.

20
11 янв. відповідь дан ModernIncantations 11 Січня. 2014-01-11 03:29 '14 в 3:29 2014-01-11 3:29

Перша Reset Голова для цільового файлу

 git reset HEAD path_to_file 

Друга перевірка цього файлу

 git checkout -- path_to_file 
19
04 апр. відповідь дан Gulshan Maurya 04 Квітня. 2017-04-04 13:25 '17 о 13:25 2017-04-04 13:25

Зверніть увагу, що git checkout ./foo і git checkout HEAD ./foo неточно одне і те ж; приклад:

 $ echo A > foo $ git add foo $ git commit -m 'A' foo Created commit a1f085f: A 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 foo $ echo B >> foo $ git add foo $ echo C >> foo $ cat foo A B C $ git checkout ./foo $ cat foo A B $ git checkout HEAD ./foo $ cat foo A 

(Другий add обробляє файл в індексі, але він не отримує скоєно.)

git checkout ./foo означає повернення шляху ./foo до індексу ; додавання HEAD інструктує Git повернути цей шлях в індекс до його HEAD до цього.

19
31 авг. відповідь дан Damien Diederen 31 Серпня. 2008-08-31 14:54 '08 о 14:54 2008-08-31 14:54

Тут багато пропозицій, більшість з них в дусі git checkout $revision -- $file . Пара неясних альтернатив:

 git show $revision:$file > $file 

А також, я часто використовую це тільки для того, щоб тимчасово побачити конкретну версію:

 git show $revision:$file 

або ж

 git show $revision:$file | vim -R - 

(OBS: $file повинен починатися з префікса ./ якщо це відносний шлях для git show $revision:$file to work)

І тим більше дивно

 git archive $revision $file | tar -x0 > $file 
14
08 янв. відповідь дан Peter V. Mørch 08 Січня. 2016-01-08 01:19 '16 в 1:19 2016-01-08 1:19

Щоб перейти до попередньої версії файлу фіксації, отримаєте номер фіксації, скажімо, eb917a1 то

 git checkout eb917a1 YourFileName 

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

 git reset HEAD YourFileName git checkout YourFileName 

Це приведе вас до останнього зафіксованого станом файлу

11
25 февр. відповідь дан shah1988 25 февр. 2014-02-25 17:01 '14 о 17:01 2014-02-25 17:01

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

У мене є commit abc1 , і після нього я зробив кілька (або одну модифікацію) файлу file.txt .

Тепер скажіть, що я щось зіпсував в файлі file.txt , і я хочу повернутися до попереднього commit abc1 .

1. git checkout file.txt : це призведе до видалення локальних змін, якщо вони вам не потрібні.

2. git checkout abc1 file.txt : це призведе ваш файл до вашої бажаної версії

3. git commit -m "Restored file.txt to version abc1" : це призведе до вашої реверсії.

  1. git push : це призведе все в віддалений репозиторій

Між кроками 2 і 3, звичайно, ви можете зробити git status , щоб зрозуміти, що відбувається. Зазвичай ви повинні бачити, що file.txt вже доданий, і тому немає необхідності в git add .

10
23 марта '17 в 0:33 2017-03-23 00:33 відповідь дан kalmanIsAGameChanger 23 березня '17 в 0:33 2017-03-23 00:33

git checkout ref | commitHash - filePath

наприклад.

 git checkout HEAD~5 -- foo.bar or git checkout 048ee28 -- foo.bar 
10
26 сент. відповідь дан Amos Folarin 26 сент. 2013-09-26 20:04 '13 о 20:04 2013-09-26 20:04

Багато відповідей тут вимагають використовувати git reset ... <file> або git checkout ... <file> , але при цьому ви втратите всі зміни в <file> , вчинені після коммітов, який ви хочете повернути.

Якщо ви хочете скасувати зміни тільки від одного фіксації тільки в одному файлі, як це зробив би git revert , але тільки для одного файлу (або, скажімо, підмножини файлів фіксації), я пропоную використовувати як git diff , так і git apply як це ( з <sha> = хеш коммітов, який ви хочете повернути):

 git diff <sha>^ <sha> path/to/file.ext | git apply -R 

В принципі, він спочатку згенерує патч, відповідний змін, які ви хочете повернути, а потім скасуйте застосування патча, щоб відкинути ці зміни.

Звичайно, він не працює, якщо ревертірованние рядки були змінені будь-яким фіксацією між <sha1> і HEAD (конфліктом).

8
07 дек. відповідь дан Vince 07 дек. 2016-12-07 17:43 '16 о 17:43 2016-12-07 17:43

Використовуйте git log для отримання хеш-ключа для конкретної версії, а потім використовуйте git checkout <hashkey>

Примітка. Не забудьте ввести хеш перед останнім. Останній хеш вказує поточну позицію (HEAD) і нічого не змінює.

8
05 дек. відповідь дан mustafakyr 05 дек. 2011-12-05 23:09 '11 о 23:09 2011-12-05 23:09

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

 cd <working copy> git revert master 

відміняє останню вчинення, яке, як видається, робить.

Ян

7
16 дек. відповідь дан Ian Davis 16 дек. 2011-12-16 06:03 '11 о 6:03 2011-12-16 6:03

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

  1. дерево з відкритим вихідним кодом, змініть цей Комміт

2019

23 авг. відповідь дан saber tabatabaee yazdi 23 Серпня. 2018-08-23 12:53 '18 о 12:53 2018-08-23 12:53

Ви можете зробити це в 4 етапи:

  1. скасувати весь Комміт з файлом, який ви хочете спеціально скасувати - це створить новий Комміт у вашій гілці
  2. soft reset that commit - видаляє Комміт і переміщує зміни в робочу область
  3. відібрати файли вручну, щоб повернути і зафіксувати їх
  4. кинути всі інші файли у вашій робочій області

Що потрібно набрати в своєму терміналі:

  1. git revert <commit_hash>
  2. git reset HEAD~1
  3. git add <file_i_want_to_revert> git commit -m 'reverting file'
  4. git checkout.

хай щастить

4
08 мая '18 в 13:26 2018-05-08 13:26 відповідь дан Nir M. 08 травня '18 о 13:26 2018-05-08 13:26
 git revert <hash> 

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

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

4
17 дек. відповідь дан Otto 17 дек. 2008-12-17 21:56 '08 о 21:56 2008-12-17 21:56

Ось мій шлях.

a) У Android Studio відкрийте файл.

b) git → Показати історію, знайти попередню фіксацію, до якої я хочу повернутися. Отримайте commit_id (тобто Commit hash).

c) git checkout commit_id file_path

1
13 марта '17 в 11:10 2017-03-13 11:10 відповідь дан Francis Bacon 13 березня '17 об 11:10 2017-03-13 11:10

Якщо ви використовуєте Git Extensions і хочете повернутися до батьківського фіксації для файлу, ви можете вибрати фіксацію, що містить зміни, які хочете повернути, потім вибрати вкладку "Diff" в деталях клацніть правою кнопкою миші файл, який ви хочете повернути, потім Reset файл на " .... ", потім" A "(батьківський)

1
26 сент. відповідь дан Johnny 26 сент. 2017-09-26 04:48 '17 в 4:48 2017-09-26 4:48

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

 # git checkout <previous commit_id> <file_name> # git commit --amend 

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

1
24 янв. відповідь дан Abhishek Dwivedi 24 Січня. 2019-01-24 20:21 '19 о 20:21 2019-01-24 20:21
  • 1
  • 2

Інші питання по мітках або Задайте питання