是否有一种方法可以对一个文件进行不同的提交。 假设我修改了一个文件5次,在我已经提交并推送到存储库之后,我想回到修改2。

在我的理解中,唯一的方法就是保留许多分支,对吗? 如果我是对的,几天内我就会有几百家分行,所以我可能不太理解。

有人能解释一下吗?


Git不考虑文件版本。git中的版本是整个树的快照。

鉴于此,您真正想要的是一个包含大多数文件最新内容的树,但其中一个文件的内容与5次提交前相同。这将采取在旧提交之上的新提交的形式,并且树的最新版本将拥有您想要的内容。

我不知道是否有一行程序可以将单个文件恢复到5次提交前的内容,但是低保真解决方案应该可以工作:签出master~5,将文件复制到其他地方,签出master,将文件复制回来,然后提交。


你可以使用一个diff来撤销你想要的更改并提交。

例:如果你想撤销范围从..,执行以下操作

git diff to..from > foo.diff  # get a reverse diff
patch < foo.diff
git commit -a -m "Undid changes from..to".

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 (e.g. 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.)

所以让我们从找到正确的承诺开始。你可以很容易地看到对给定文件进行修改的提交:

git log path/to/file

如果你的提交消息不够好,你需要看到每次提交时对文件做了什么,使用-p/——patch选项:

git log -p path/to/file

或者,如果您更喜欢gitk的图形化视图

gitk path/to/file

你也可以这样做,一旦你开始通过视图菜单;视图的一个选项是要包含的路径列表。

无论哪种方式,您都能够找到提交的SHA1(哈希)与您想要的文件版本。现在,你要做的就是:

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

(checkout命令首先将文件读入索引,然后将其复制到工作树中,因此不需要使用git add将其添加到索引中以准备提交。)

如果您的文件可能没有简单的历史记录(例如重命名和复制),请参阅VonC的优秀评论。Git可以被指示更仔细地搜索这些东西,但以速度为代价。如果你确信历史很简单,你就不必费心了。


Git非常灵活。您不应该需要数百个分支来完成您的请求。如果你想将状态一直还原到第2个更改(这确实是一个已经提交和推送的更改),请使用git revert。喜欢的东西:

git revert a4r9593432 

其中a4r9593432是您想要退出的提交的散列的起始字符。

如果提交包含对许多文件的更改,但你只想恢复其中一个文件,你可以使用git reset(第二或第三种形式):

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           

但这是相当复杂的,并且git重置是危险的。使用git checkout <hash> <file path>代替,就像Jefromi建议的那样。

如果你只是想查看文件在提交x时的样子,你可以使用git show:

git show a4r9593432:path/to/file.txt

对于所有的命令,除了通过提交哈希之外,还有许多方法来引用提交(参见Git用户手册中的命名提交)。


从这里提取:http://git.661346.n2.nabble.com/Revert-a-single-commit-in-a-single-file-td6064050.html

 git revert <commit> 
 git reset 
 git add <path> 
 git commit ... 
 git reset --hard # making sure you didn't have uncommited changes earlier 

这对我来说很有效。