有什么方法可以在一个文件上浏览不同的提交。 比如我修改了一个文件5次,在我已经提交并推送到版本库后,我想回到第2次修改。
在我的理解中,唯一的办法是保留许多分支,我的理解对吗? 如果我是对的,几天后我就会有几百个分支,所以我可能真的没有理解。
谁能解释一下这个问题?
让我们先定性地描述一下我们想做的事情(这一点在Ben Straub的回答中已经说了很多)。我们做了一些提交,其中五个改变了某个文件,我们想把这个文件恢复到之前的一个版本。首先,git并不为单个文件保留版本号。它只是跟踪内容--一个提交基本上是工作树的快照,还有一些元数据(比如提交信息)。因此,我们必须知道哪个提交有我们想要的文件的版本。一旦我们知道了,我们就需要做一个新的提交,将文件还原到那个状态。(我们不能随便修改历史,因为我们已经推送了这些内容,而编辑历史会扰乱其他人的工作。)
所以让我们从找到正确的提交开始。你可以很容易地看到对指定文件进行了修改的提交。
git log path/to/file
如果你的提交信息不够好,而你又需要看到每次提交时对文件做了什么,可以使用-p/--patch
选项。
git log -p path/to/file
或者,如果你喜欢gitk的图形视图
gitk path/to/file
你也可以在启动gitk后通过视图菜单进行操作;视图的选项之一是包含的路径列表。
无论哪种方式,你都能找到带有你想要的文件版本的提交的SHA1(哈希值)。现在,你所要做的就是这个。
# get the version of the file from the given commit
git checkout <commit> path/to/file
# and commit this modification
git commit
(签出命令首先将文件读入索引,然后复制到工作树中,所以不需要使用git add
将其添加到索引中以准备提交)。)
如果你的文件可能没有简单的历史记录(比如重命名和复制),请参阅VonC的精彩评论。git
可以被指示更仔细地搜索这些东西,但要牺牲速度。如果你确信历史记录很简单,你就不需要麻烦了。
Git并不以文件版本来考虑问题。git中的版本是整个树的一个快照。
鉴于此,你真正想要的是一棵树,它拥有大多数文件的最新内容,但有一个文件的内容与5次提交前相同。这将采取在旧的提交之上增加一个新的提交的形式,最新版本的树就会有你想要的内容。
我不知道是否有一个单行程序可以将一个文件恢复到5次提交前的内容,但这个简单的解决方案应该可以:签出master~5
,将文件复制到其他地方,签出master
,将文件复制回来,然后提交。