it-swarm.com.ru

Сброс или возврат определенного файла к определенной ревизии с помощью Git?

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

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

3806
Hates_

Предполагая, что хеш коммита, который вы хотите, равен c5f567:

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

Страница git checkout дает больше информации.

Если вы хотите вернуться к фиксации до c5f567, добавьте ~1 (работает с любым числом):

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

Как примечание, мне всегда было неудобно с этой командой, потому что она используется как для обычных вещей (переключение между ветвями), так и для необычных, разрушительных вещей (отбрасывая изменения в рабочем каталоге).

5187
Greg Hewgill

Вы можете быстро просмотреть изменения, внесенные в файл, используя команду diff:

git diff <commit hash> <filename>

Затем, чтобы вернуть определенный файл в этот коммит, используйте команду сброса:

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>
545
Chris Lloyd

Вы можете использовать любую ссылку на коммит git, включая SHA-1, если это наиболее удобно. Дело в том, что команда выглядит так:

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

323
foxxtrot
git checkout -- foo

Это сбросит foo в HEAD. Вы также можете:

git checkout HEAD^ foo

за одну ревизию назад и т. д.

258
Greg Hewgill

И чтобы вернуться к последней подтвержденной версии, которая наиболее часто необходима, вы можете использовать эту более простую команду.

git checkout HEAD file/to/restore
114
CDR

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

git checkout [commit-ref] [filename]

Это поместит эту старую версию в ваш рабочий каталог, и оттуда вы можете зафиксировать ее, если хотите.

103
bbrown

Если вы знаете, сколько коммитов нужно вернуть, вы можете использовать:

git checkout master~5 image.png

Предполагается, что вы находитесь в ветви master, и вам нужна версия 5 коммитов назад.

88
Ron DeVera

Я думаю, что я нашел это от http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

Иногда вы просто хотите вернуться назад и забыть о каждом изменении после определенного момента, потому что все они не правы. 

Начните с:

$ git log

который показывает вам список последних коммитов и их хэш SHA1. 

Далее введите:

$ git reset --hard SHA1_HASH

чтобы восстановить состояние данного коммита и удалить все новые коммиты из записи навсегда.

78
jdee

Это сработало для меня:

git checkout <commit hash> file

Затем внесите изменения:

git commit -a
61
v2k

Вы должны быть осторожны, когда говорите «откат». Если раньше у вас была одна версия файла в коммите $ A, а затем позже было сделано два изменения в двух отдельных коммитах $ B и $ C (так что вы видите третью итерацию файла), и если вы скажете " Я хочу откатиться к первому ", вы действительно это имеете в виду? 

Если вы хотите избавиться от изменений как второй, так и третьей итерации, это очень просто:

$ git checkout $A file

и тогда вы фиксируете результат. Команда спрашивает: «Я хочу извлечь файл из состояния, записанного коммитом $ A».

С другой стороны, вы имели в виду избавление от изменений, внесенных второй итерацией (т. Е. Commit $ B), сохраняя то, что commit $ C сделал с файлом, вы захотите вернуть $ B

$ git revert $B

Обратите внимание, что тот, кто создал коммит $ B, возможно, не был очень дисциплинированным и мог совершить совершенно несвязанное изменение в том же коммите, и этот возврат может коснуться файлов, отличных от file вы видите оскорбительные изменения, поэтому вы можете проверить результат тщательно после этого.

54
gitster

Забавно, но 'git checkout foo' не будет работать, если рабочая копия находится в каталоге с именем foo; однако и «git 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
Aaron Maenpaa

Вот как работает rebase:

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

Предположим, у вас есть

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

Первые две команды ... Commit git checkout мастер git rebase

... проверить ветку изменений, которые вы хотите применить к ветке 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. Без этого шага коммит перебазирования не добавляется в master. Окончательный результат:

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

master и <my branch> оба ссылаются на B'. Кроме того, с этого момента можно безопасно удалить ссылку <my branch>.

git branch -d <my branch>
32
cmcginty

git-aliases, awk и Shell-функции на помощь!

git prevision <N> <filename>

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

git prevision -1 x/y/z.c

Как работает Git Prevision?

Добавьте следующее к вашему 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 для идентификатора коммита для указанного файла.

По сути, все, что можно было бы сделать вручную в этой ситуации,
завернутый в один красивый, эффективный псевдоним git - git-prevision

21
TheCodeArtist

Первая головка сброса для целевого файла

git reset HEAD path_to_file

Вторая проверка этого файла

git checkout -- path_to_file
21
Gulshan Maurya

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

git checkout HEAD^1 path/to/file

или же

git checkout HEAD~1 path/to/file

Затем просто подготовьте и зафиксируйте «новую» версию.

Вооружившись знанием, что в случае слияния у коммита может быть два родителя, вы должны знать, что HEAD ^ 1 является первым родителем, а HEAD ~ 1 - вторым родителем.

Любой из них будет работать, если в дереве есть только один родитель.

20
ModernIncantations

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

eg revertfoo/bar foo/baz

20
Aristotle Pagaltzis

Заметьте, однако, что 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 помещает файл в индекс, но not не получает Commit.)

Git checkout ./foo означает возврат пути ./foo из index ; добавление HEAD указывает Git перед тем, как сделать так, чтобы Git вернул этот путь в индексе к его ревизии HEAD.

19
Damien Diederen

Здесь много предложений, большинство из которых соответствуют 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 это относительный путь)

И тем более странно

git archive $revision $file | tar -x0 > $file
14
Peter V. Mørch

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

У меня есть коммит abc1 и после него я сделал несколько (или одну модификацию) файла file.txt.

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

1 .git checkout file.txt: это удалит локальные изменения, если они вам не нужны

2 .git checkout abc1 file.txt: это переведет ваш файл в вашу wanted версию

3 .git commit -m "Restored file.txt to version abc1": это совершит ваше возвращение.

  1. git Push: это будет толкать все в удаленном хранилище 

Между шагами 2 и 3, конечно, вы можете сделать git status, чтобы понять, что происходит. Обычно вы должны видеть, что file.txt уже добавлен, и поэтому нет необходимости в git add.

11
kalmanIsAGameChanger

Чтобы перейти к предыдущей версии файла коммита, получите номер коммита, скажем, eb917a1 Then 

git checkout eb917a1 YourFileName

Если вам просто нужно вернуться к последней зафиксированной версии

git reset HEAD YourFileName
git checkout YourFileName

Это просто приведет вас к последнему подтвержденному состоянию файла.

11
shah1988

git checkout ref | commitHash - filePath

например 

git checkout HEAD~5 -- foo.bar
or 
git checkout 048ee28 -- foo.bar
10
Amos Folarin

Используйте git log, чтобы получить ключ хеша для конкретной версии, а затем используйте git checkout <hashkey>

Примечание: не забудьте набрать хеш перед последним. Последний хеш указывает вашу текущую позицию (HEAD) и ничего не меняет.

8
mustafakyr

Многие ответы здесь утверждают, что используют 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
Vince

Очевидно, что кто-то должен либо написать вразумительную книгу по git, либо git нужно лучше объяснить в документации. Столкнувшись с этой же проблемой, я догадался, что 

cd <working copy>
git revert master

отменяет последний коммит, который, кажется, делает.

Ян

7
Ian Davis

если вы делаете неправильный файл в ваших последних коммитах, следуйте инструкциям:

  1. дерево с открытым исходным кодом, измените этот коммит

 open source tree

  1. измените строки и найдите ваш коммит, который неверный файл отправил как коммит

 enter image description here

  1. вы можете увидеть список ваших изменений в этом коммите  list of files in the source tree
  2. выберите его, а затем нажмите ... кнопки справа ... щелкните обратный файл
  3. затем вы можете увидеть его на вкладке статуса файла внизу слева затем нажмите untage:

 file status tab

  1. откройте код Visual Studio и вернитесь обратно, зафиксировав удаленные файлы
  2. после всех них вы можете увидеть результаты вашего последнего коммита в исходном дереве

 enter image description here

5
saber tabatabaee yazdi
git revert <hash>

Вернет данный коммит. Похоже, вы думаете, что git revert влияет только на самый последний коммит.

Это не решит вашу проблему, если вы хотите отменить изменение в определенном файле, и этот коммит изменился больше, чем этот файл.

4
Otto

Вы можете сделать это в 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 .

удачи

3
Nir M.

Это очень простой шаг. Извлеките файл с требуемым идентификатором фиксации, здесь один идентификатор фиксации ранее, а затем просто выполните команду git commit modify и все готово.

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

Это очень удобно. Если мы хотим вывести какой-либо файл с любым идентификатором предыдущей фиксации в верхней части фиксации, мы можем легко это сделать.

2
Abhishek Dwivedi
  1. Git вернуть файл к определенной фиксации

git checkout Last_Stable_commit_Number - fileName

2.Git вернуть файл в определенную ветку

git checkout branchName_Which_Has_stable_Commit fileName
1
ireshika piyumalie

Вот мой путь.

а) В Android Studio откройте файл.

б) git -> Показать историю, найти предыдущий коммит, к которому я хочу вернуться. Получите commit_id (то есть, передайте хеш).

в) git checkout commit_id file_path

1
Francis Bacon

Если вы используете Git Extensions и хотите вернуть только родительский коммит для файла, вы можете выбрать коммит, содержащий изменения, которые вы хотите отменить, а затем выберите вкладку «Разница» в области сведений, щелкните правой кнопкой мыши. файл, который вы хотите восстановить, затем «Сбросить файл (ы) в» ...., затем «A» (родитель)

1
Chris Halcrow