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

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

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

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

вопрос задан 28.03.2009
hasen
79797 репутация

12 ответов


  • 1839 рейтинг

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

    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
    
    ответ дан Brian Campbell, с репутацией 222829, 28.03.2009
  • 118 рейтинг
    git checkout  
    

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

    git checkout 088ecd favicon.ico
    
    ответ дан neoneye, с репутацией 29516, 28.03.2009
  • 103 рейтинг

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

    git checkout filename
    

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

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

    ответ дан nimrodm, с репутацией 16992, 28.03.2009
  • 52 рейтинг

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

    Использование

    git reset HEAD 
    

    Тогда

    git checkout 
    

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

    git checkout 
    
    ответ дан thanikkal, с репутацией 1903, 3.07.2012
  • 15 рейтинг

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

    git checkout branchname^ filename
    

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

    ответ дан sykora, с репутацией 56916, 28.03.2009
  • 7 рейтинг

    Я всегда путаюсь с этим, поэтому вот контрольный пример с напоминанием; скажем, у нас есть этот сценарий 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 ..." to update what will be committed)
      (use "git checkout -- ..." 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 ..." to update what will be committed)
      (use "git checkout -- ..." 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 ..." 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 ..." to update what will be committed)
      (use "git checkout -- ..." 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 полностью перезаписывает изменения.

    ответ дан sdaau, с репутацией 18890, 9.02.2016
  • 5 рейтинг

    Я восстанавливаю свои файлы, используя идентификатор SHA, что я делаю, git checkout

    ответ дан Beto, с репутацией 463, 22.05.2012
  • 4 рейтинг

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

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

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

    enter image description here

    ответ дан Shivanandam Sirmarigari, с репутацией 743, 10.04.2018
  • 2 рейтинг

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

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

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

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

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

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

    git checkout -- name1/name2/*
    

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

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

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

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

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

    ответ дан Nirmal, с репутацией 700, 23.01.2017
  • 2 рейтинг

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

    git diff --stat HEAD^...HEAD | \
    fgrep filename_snippet_to_revert | cut -d' ' -f2 | xargs git checkout HEAD^ --
    git commit -a --amend
    
    ответ дан Jesse Glick, с репутацией 15422, 30.04.2014
  • 1 рейтинг

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

    git checkout -p filename
    

    enter image description here

    ответ дан Ramesh Bhupathi, с репутацией 164, 19.08.2017
  • 0 рейтинг

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

    ответ дан Gina, с репутацией 1, 26.04.2017