Reverting a single file to a previous version in git

This question already has an answer here:

  • Reset or revert a specific file to a specific revision using Git? 28 answers

  • Let's start with a qualitative description of what we want to do (much of this is said in Ben Straub's answer). We've made some number of commits, five of which changed a given file, and we want to revert the file to one of the previous versions. First of all, git doesn't keep version numbers for individual files. It just tracks content - a commit is essentially a snapshot of the work tree, along with some metadata (eg commit message). So, we have to know which commit has the version of the file we want. Once we know that, we'll need to make a new commit reverting the file to that state. (We can't just muck around with history, because we've already pushed this content, and editing history messes with everyone else.)

    So let's start with finding the right commit. You can see the commits which have made modifications to given file(s) very easily:

    git log path/to/file
    

    If your commit messages aren't good enough, and you need to see what was done to the file in each commit, use the -p/--patch option:

    git log -p path/to/file
    

    Or, if you prefer the graphical view of gitk

    gitk path/to/file
    

    You can also do this once you've started gitk through the view menu; one of the options for a view is a list of paths to include.

    Either way, you'll be able to find the SHA1 (hash) of the commit with the version of the file you want. Now, all you have to do is this:

    # get the version of the file from the given commit
    git checkout <commit> path/to/file
    # and commit this modification
    git commit
    

    (The checkout command first reads the file into the index, then copies it into the work tree, so there's no need to use git add to add it to the index in preparation for committing.)

    If your file may not have a simple history (eg renames and copies), see VonC's excellent comment. git can be directed to search more carefully for such things, at the expense of speed. If you're confident the history's simple, you needn't bother.


    Git is very flexible. You shouldn't need hundreds of branches to do what you are asking. If you want to revert the state all the way back to the 2nd change (and it is indeed a change that was already committed and pushed), use git revert . Something like:

    git revert a4r9593432 
    

    where a4r9593432 is the starting characters of the hash of the commit you want to back out.

    If the commit contains changes to many files, but you just want to revert just one of the files, you can use git reset (the 2nd or 3rd form):

    git reset a4r9593432 -- path/to/file.txt
    # the reverted state is added to the staging area, ready for commit
    git diff --cached path/to/file.txt        # view the changes
    git commit
    git checkout HEAD path/to/file.txt        # make the working tree match HEAD           
    

    But this is pretty complex, and git reset is dangerous. Use git checkout <hash> <file path> instead, as Jefromi suggests.

    If you just want to view what the file looked like in commit x, you can use git show :

    git show a4r9593432:path/to/file.txt
    

    For all of the commands, there are many ways to refer to a commit other than via the commit hash (see Naming Commits in the Git User Manual).


    Say your 5 commits are A, B, C, D, E--A being the first and E the latest. You want to revert file.txt to the way it was after commit A. You don't need to learn or remember the different versions or options of the git-reset and git-checkout commands. Run:

    git show A:file.txt >file.txt
    
    # If you want to commit the older version:
    git add file.txt
    git commit
    

    The git-show command shows the contents of, or information about, any object in a Git repository. When given a commit reference like A (or master^ or HEAD~5 or ...), followed by a colon, followed by a file name, it will show the contents of that file as it was after that commit. Then it's just a matter of redirecting the output into the file.

    链接地址: http://www.djcxy.com/p/8970.html

    上一篇: Git重置功能分支中的单个文件与主文件中的相同

    下一篇: 在git中将单个文件恢复到以前的版本