13 Вопрос: Отменить рабочую копию изменений одного файла в Git?

вопрос создан в Thu, Jan 11, 2018 12:00 AM

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

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

Как мне это сделать?

    
1473
13 ответов                              13                         

Вы можете использовать

git checkout -- file

Вы можете сделать это без -- (как предлагает nimrodm), но если имя файла выглядит как ветвь или тег (или другой идентификатор ревизии), оно может запутаться, поэтому лучше использовать --.

Вы также можете проверить конкретную версию файла:

git checkout v1.2.3 -- file         # tag v1.2.3
git checkout stable -- file         # stable branch
git checkout origin/master -- file  # upstream master
git checkout HEAD -- file           # the version from the most recent commit
git checkout HEAD^ -- file          # the version before the most recent commit
    
2027
2014-05-30 02: 30: 59Z
  1. в чем разница между HEAD и HEAD ^?
    2009-03-28 22: 06: 02Z
  2. HEAD - это самый последний коммит в текущей ветви, а HEAD ^ - это коммит до этого в текущей ветви. Для описываемой ситуации вы можете использовать git checkout HEAD - filename.
    2009-03-28 22: 21: 32Z
  3. Вкратце "git checkout sha-reference - filename", где sha-reference является ссылкой на sha коммита в любой форме (ветке, теге, родитель и т. д.)
    2010-03-02 15: 46: 03Z
  4. ПРИМЕЧАНИЕ. Если файл уже подготовлен, сначала необходимо сбросить его. git reset HEAD <filename> ; git checkout -- <filename>
    2013-06-13 21: 56: 52Z
  5. @ gwho Да, вы можете выполнить HEAD^^ для 2 коммитов из самых последних или HEAD^^^ для 3 коммитов назад. Вы также можете использовать HEAD~2 или HEAD~3, что становится более удобным, если вы хотите получить больше коммитов назад, в то время как HEAD^2 означает «второй родитель этого коммита»; из-за коммитов слиянием коммит может иметь более одного предыдущего коммита, поэтому с HEAD^ число выбирает, какой из этих родителей, а с HEAD~ число всегда выбирает первого родителя, но это число коммитов возвращается. См. git help rev-parse для получения дополнительной информации.
    2014-05-13 15: 34: 54Z
git checkout <commit> <filename>

Я использовал это сегодня, потому что понял, что мой favicon был перезаписан несколько коммитов назад, когда я обновился до drupal 6.10, поэтому мне пришлось вернуть его. Вот что я сделал:

git checkout 088ecd favicon.ico
    
125
2009-03-28 10: 25: 25Z
  1. Как получить коммит (из ранее удаленного файла), кроме прокрутки с тоннами вывода «git log --stat»?
    2012-03-01 09: 40: 22Z
  2. IMO через командную строку довольно сложно сканировать журнал gits и найти нужный файл. С приложением с графическим интерфейсом намного проще, например, sourcetreeapp.com
    2012-03-02 06: 46: 50Z
  3. git log --oneline <filename> предоставит вам более компактный журнал и будет содержать только изменения в конкретном файле
    2014-02-05 11: 51: 38Z
  4. альтернативно, вы можете использовать git reflog <filename>
    2015-08-05 07: 08: 11Z

Просто используйте

git checkout filename

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

ВНИМАНИЕ: ваши изменения будут отменены - резервная копия не сохраняется.

    
123
2014-05-30 02: 32: 10Z
  1. что такое - для?
    2015-03-03 19: 52: 38Z
  2. @ duckx для устранения неоднозначности имен ветвей из имен файлов. если вы скажете git checkout x и x окажется именем ветви, а также именем файла, я не уверен, что такое поведение по умолчанию, но я думаю, что git будет предполагать, что вы хотите переключиться на ветку x Когда вы используете --, вы говорите, что ниже приведены имена файлов.
    2015-03-04 16: 15: 09Z
  3. спасибо за разъяснение. все предполагают, что вы знаете, что - значит, когда они показывают вам примеры. и это не то, что вы тоже можете легко погуглить.
    2015-03-04 18: 05: 31Z
  4. Похоже, что ответ был отредактирован для удаления из него --. Хотя все еще правильно, как указывает @hasen, если существует двусмысленность между именами файлов и веток, вы можете столкнуться с очень нежелательным поведением здесь!
    2015-03-14 18: 14: 21Z
  5. Мне нравится, как есть, без --, красиво и легко. Когда вы называете ветви, используя имена файлов, где-то должно быть плохое мышление ...
    2017-04-21 16: 00: 53Z

Если ваш файл уже подготовлен (происходит, когда вы делаете git add и т. д. после редактирования файла), чтобы отменить внесение изменений.

Использовать

git reset HEAD <file>

Тогда

git checkout <file>

Если это еще не постановка, просто используйте

git checkout <file>
    
64
2015-03-31 07: 08: 00Z
  1. Это было более полезным, чем принятый хаха. Легко забыть, какие изменения были организованы, а какие нет, поэтому сброс помог. Хотя я и раньше пробовал «git reset --hard», он не делал то, что делал «git reset HEAD». Интересно почему?
    2014-10-06 14: 21: 00Z

Если вы хотите просто отменить изменения предыдущего коммита в этом файле, попробуйте следующее:

git checkout branchname^ filename

Это извлечет файл таким, каким он был до последнего коммита. Если вы хотите вернуться еще на несколько коммитов, используйте нотацию branchname~n.

    
18
2014-05-30 02: 32: 42Z
  1. Это не приведет к удалению изменений из фиксации, оно просто применит diff к версии в HEAD.
    2013-02-27 18: 32: 17Z
  2. Несмотря на то, что истина, оригинальный постер просто хотел отменить изменения своей рабочей копии (я думаю), а не отменить изменения с последнего коммита. Оригинальный вопрос автора был немного неясен, поэтому я могу понять путаницу.
    2014-05-30 02: 34: 40Z
  3. возможно, не используется OP, но я искал, как перезаписать мою ветку основной копией - это прекрасно работает при замене branchname^
    2019-03-14 17: 18: 43Z

Я сделал через git bash:

(use "git checkout -- <file>..." to discard changes in working directory)

  1. Статус Git. [Итак, мы видели один файл, модифицированный.]
  2. git checkout - index.html [я изменился в файле index.html:
  3. git status [теперь эти изменения были удалены]

 введите описание изображения здесь

    
12
2018-04-12 13: 04: 25Z

Я всегда путаюсь с этим, поэтому вот контрольный пример с напоминанием; скажем, у нас есть этот скрипт bash для проверки git:

set -x
rm -rf test
mkdir test
cd test
git init
git config user.name test
git config user.email test@test.com
echo 1 > a.txt
echo 1 > b.txt
git add *
git commit -m "initial commit"
echo 2 >> b.txt
git add b.txt
git commit -m "second commit"
echo 3 >> b.txt

На этом этапе изменение не размещается в кэше, поэтому git status:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

Если с этого момента мы сделаем git checkout, результат будет таким:

$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean

Если вместо этого мы сделаем git reset, результат будет таким:

$ git reset HEAD -- b.txt
Unstaged changes after reset:
M   b.txt
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

Таким образом, в этом случае - если изменения не являются поэтапными, git reset не имеет значения, а git checkout перезаписывает изменения.

Теперь предположим, что последнее изменение из приведенного выше сценария является поэтапным /кэшированным, то есть мы также сделали git add b.txt в конце.

В этом случае git status на данный момент:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   b.txt

Если с этого момента мы сделаем git checkout, результат будет таким:

$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean

Если вместо этого мы сделаем git reset, результат будет таким:

$ git reset HEAD -- b.txt
Unstaged changes after reset:
M   b.txt
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

Таким образом, в этом случае - если изменения поэтапно, git reset будет в основном вносить поэтапные изменения в не поэтапные изменения - в то время как git checkout полностью перезаписывает изменения.

    
8
2016-02-09 08: 56: 33Z

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

  

если у вас есть один или несколько файлов, вы можете применить ту же команду (git checkout -- file) к   каждый из этих файлов, перечисляя каждый из их местоположения, разделенных   пробел как в:

git checkout -- name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext
  

обратите внимание на расстояние между name1 /name2 /fileOne.ext nameA /subFolder /fileTwo.ext

Для нескольких файлов в одной папке:

  

Если вам нужно отменить изменения для всех файлов в   в определенном каталоге используйте git checkout следующим образом:

git checkout -- name1/name2/*

Звездочка, указанная выше, выполняет процедуру удаления всех файлов в этом месте с именем name1 /name2.

  

И, аналогично, следующее может отменить изменения во всех файлах для   несколько папок:

git checkout -- name1/name2/* nameA/subFolder/*
  

снова обратите внимание на пробел между name1 /name2 /* nameA /subFolder /* в   выше. р>

Примечание: name1, name2, nameA, subFolder - все эти примеры имен папок указывают папку или пакет, где могут находиться рассматриваемые файлы.

    
7
2019-01-11 13: 44: 33Z

Я восстанавливаю свои файлы, используя идентификатор SHA. Что я делаю, это git checkout <sha hash id> <file name>

    
5
2012-05-22 20: 39: 17Z

Если вы еще не выдвинули или иным образом не поделились своим коммитом:

git diff --stat HEAD^...HEAD | \
fgrep filename_snippet_to_revert | cut -d' ' -f2 | xargs git checkout HEAD^ --
git commit -a --amend
    
2
2014-05-30 02: 28: 41Z

Для меня только этот работал

git checkout -p filename

 введите описание изображения здесь

    
2
2017-08-19 14: 28: 04Z

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

    
0
2017-04-26 19: 17: 07Z
  1. Добавление определенных используемых команд поможет оригинальному постеру и будущим посетителям.
    2017-04-26 20: 29: 40Z

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

 введите описание изображения здесь

    
0
2018-12-31 15: 55: 01Z
источник размещен Вот