Reset або повернути конкретний файл в конкретну ревізію за допомогою Git?
Я вніс деякі зміни в файл, який був переданий кілька разів як частина групи файлів, але тепер хочу reset / повернути зміни на нього назад в попередню версію.
Я зробив git log
разом з git diff
, щоб знайти потрібний мені варіант, але просто не знаю, як повернути файл до свого попереднього стану в минулому.
- 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
Як примітка, мені завжди було незручно з цією командою, тому що вона використовувалася як для звичайних речей (перемикання між гілками), так і для незвичайних, руйнівних речей (виключаючи зміни в робочому каталозі).
Ви можете швидко переглянути зміни, внесені в файл, використовуючи команду diff:
git diff <commit hash> <filename>
Потім, щоб повернути конкретний файл цього фіксатора, використовуйте команду reset:
git reset <commit hash> <filename>
Можливо, вам доведеться використовувати опцію --hard
, якщо у вас є локальні модифікації.

Хорошим документообігом для управління точками є використання тегів для чистоти точок на вашій часовій шкалі. Я не можу зрозуміти ваше останнє речення, але те, що вам може знадобитися, - це розбіжність гілки з попереднього моменту часу. Для цього використовуйте зручну команду 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>
Ви можете використовувати будь-яке посилання на фіксацію git, включаючи SHA-1, якщо це найзручніше. Справа в тому, що команда виглядає так:
git checkout [commit-ref] -- [filename]
git checkout -- foo
Це буде reset foo
для HEAD. Ви також можете:
git checkout HEAD^ foo
для однієї ревізії і т.д.
І щоб повернутися до останньої завершеної версії, яка найбільш часто необхідна, ви можете використовувати цю простішу команду.
git checkout HEAD file/to/restore
У мене була така ж проблема тільки зараз, і я знайшов цю відповідь найпростіше зрозуміти ( commit-ref
- значення SHA зміни в журналі, який ви хочете відправити назад):
git checkout [commit-ref] [filename]
Це ставить цю стару версію в ваш робочий каталог, і звідти ви можете її зафіксувати, якщо хочете.
Якщо ви знаєте, скільки коммітов вам потрібно повернутися, ви можете використовувати:
git checkout master~5 image.png
Передбачається, що ви перебуваєте в гілці master
, а бажана версія - 5.
Я думаю, що знайшов ... від http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html
Іноді ви просто хочете повернутися і забути про всі зміни за певний момент, тому що всі вони не мають рації.
Почніть з:
$ git log
який показує вам список останніх коммітов і їх хеш SHA1.
Потім введіть:
$ git reset --hard SHA1_HASH
щоб відновити стан для даної фіксації і стерти всі нові записи з записи назавжди.
Це спрацювало для мене:
git checkout <commit hash> file
Потім зафіксуйте зміна:
git commit -a
Ви повинні бути обережні, коли говорите "відкат". Якщо ви використовували одну версію файлу в commit $ A, а потім зробили два зміни в двох окремих коммітов $ B і $ C (так що ви бачите, це третя ітерація файлу), і якщо ви скажете "Я хочу повернутися до першого", ви дійсно це маєте на увазі?
Якщо ви хочете позбутися від змін як другий, так і третій ітерації, це дуже просто:
$ git checkout $A file
а потім ви фіксуєте результат. Команда запитує "Я хочу перевірити файл зі стану, записаного фіксацією $ A".
З іншого боку, те, що ви мали на увазі, це позбавитися від зміни другої ітерації (тобто зробити $ B), при збереженні того, що зафіксував файл $ C в файлі, ви хотіли б повернути $ B
$ git revert $B
Зверніть увагу: хоч би хто створював commit $ B, можливо, не був дуже дисциплінований і міг зробити абсолютно незв'язані зміни в одній і тій же фіксації, і це повернення може стосуватися файлів, відмінних від файлу, який ви бачите, образливі зміни, тому ви можете перевірити результат ретельно після цього.
Цікаво, '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
Тут 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>
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
Мені потрібно підключити EasyGit тут, який є обгорткою, щоб зробити git більш доступним для новачків, які не заплутуючи досвідчених користувачів. Одна з речей, які вона робить, - дає більше значень git revert
. В цьому випадку ви просто скажете:
eg revert foo/bar foo/baz
У разі, якщо ви хочете повернути файл в попередню фіксацію (і файл, який ви хочете повернути вже зафіксовано), ви можете використовувати
git checkout HEAD^1 path/to/file
або
git checkout HEAD~1 path/to/file
Потім просто виконайте етап і зафіксуйте "нову" версію.
Озброївшись знаннями про те, що в разі злиття commit може мати двох батьків, ви повинні знати, що HEAD ^ 1 є першим батьком, а HEAD ~ 1 є другим батьком.
Або буде працювати, якщо в дереві є тільки один батько.
Перша Reset Голова для цільового файлу
git reset HEAD path_to_file
Друга перевірка цього файлу
git checkout -- path_to_file
Зверніть увагу, що 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
до цього.
Тут багато пропозицій, більшість з них в дусі 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
Щоб перейти до попередньої версії файлу фіксації, отримаєте номер фіксації, скажімо, eb917a1 то
git checkout eb917a1 YourFileName
Якщо вам просто потрібно повернутися до останньої зареєстрованої версії
git reset HEAD YourFileName git checkout YourFileName
Це приведе вас до останнього зафіксованого станом файлу
Для мене жоден відповідь не здавався дійсно ясним, і тому я хотів би додати мій, який здається супер простим.
У мене є 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"
: це призведе до вашої реверсії.
-
git push
: це призведе все в віддалений репозиторій
Між кроками 2 і 3, звичайно, ви можете зробити git status
, щоб зрозуміти, що відбувається. Зазвичай ви повинні бачити, що file.txt
вже доданий, і тому немає необхідності в git add
.
git checkout ref | commitHash - filePath
наприклад.
git checkout HEAD~5 -- foo.bar or git checkout 048ee28 -- foo.bar
Багато відповідей тут вимагають використовувати 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
(конфліктом).
Використовуйте git log
для отримання хеш-ключа для конкретної версії, а потім використовуйте git checkout <hashkey>
Примітка. Не забудьте ввести хеш перед останнім. Останній хеш вказує поточну позицію (HEAD) і нічого не змінює.
Очевидно, комусь потрібно написати зрозумілу книгу на git або git, щоб її краще пояснити в документації. Зіткнувшись з цією ж проблемою, я здогадався, що
cd <working copy> git revert master
відміняє останню вчинення, яке, як видається, робить.
Ян
Якщо ви робите неправильний файл в ваших останніх коммітов, дотримуйтесь інструкцій:
- дерево з відкритим вихідним кодом, змініть цей Комміт
Ви можете зробити це в 4 етапи:
- скасувати весь Комміт з файлом, який ви хочете спеціально скасувати - це створить новий Комміт у вашій гілці
- soft reset that commit - видаляє Комміт і переміщує зміни в робочу область
- відібрати файли вручну, щоб повернути і зафіксувати їх
- кинути всі інші файли у вашій робочій області
Що потрібно набрати в своєму терміналі:
-
git revert <commit_hash>
-
git reset HEAD~1
-
git add <file_i_want_to_revert>
git commit -m 'reverting file'
-
git checkout.
хай щастить
git revert <hash>
Поверне задану фіксацію. Схоже, ви думаєте, що git revert
впливає тільки на останній вчинення.
Це не вирішить вашу проблему, якщо ви хочете скасувати зміна в певному файлі і що commit змінився більше, ніж цей файл.
Ось мій шлях.
a) У Android Studio відкрийте файл.
b) git → Показати історію, знайти попередню фіксацію, до якої я хочу повернутися. Отримайте commit_id (тобто Commit hash).
c) git checkout commit_id file_path
Якщо ви використовуєте Git Extensions і хочете повернутися до батьківського фіксації для файлу, ви можете вибрати фіксацію, що містить зміни, які хочете повернути, потім вибрати вкладку "Diff" в деталях клацніть правою кнопкою миші файл, який ви хочете повернути, потім Reset файл на " .... ", потім" A "(батьківський)
Це дуже простий крок. Вийміть файл з ідентифікатором фіксації, який ми хочемо, тут один ідентифікатор фіксації раніше, а потім просто виконайте команду git commitmend, і все готово.
# git checkout <previous commit_id> <file_name> # git commit --amend
Це дуже зручно. Якщо ми хочемо вивести будь-якої файл з будь-яким ідентифікатором попередньої фіксації в верхній частині фіксації, ми можемо легко це зробити.
- 1
- 2
Інші питання по мітках git version-control або Задайте питання