Git - 如何在回滚时从将来的提交中获取新文件

时间:2015-11-13 17:20:02

标签: git git-checkout

我有一个git分支,它有一个正常的Git提交历史记录;在整个开发周期中都有添加/修改/删除。

我想回滚到之前的提交,但保留一个来自当前提交的文件,这不在我回滚的提交中(或者将其翻转到头上,从未来的提交中检出文件)在当前提交中不存在。)

E.g:

--------A--------B--------- ...
                 + myFile.txt;

 $ git checkout #A

我想结帐提交#A,但保留在提交myFile.txt中添加的#B

4 个答案:

答案 0 :(得分:5)

您可以使用git checkout执行此操作,它将路径作为可选参数:

git checkout <commit> <path>

假设您当前处于使用散列B的提交中,并且您希望重置除了goodFile.txt以及来自提交A的状态的所有文件。

git checkout A结帐您希望从

获取大部分文件的提交

git checkout B goodFile.txt现在从提交B中签出特定的好文件

git commit goodFile.txt提交它。

你现在有一个新的提交,其中A作为它的父母,其中包含来自A的所有文件和来自B的goodFile.txt

答案 1 :(得分:0)

将文件myFile.txt从git repo中复制出来,然后结帐A.将文件复制回repo中。

答案 2 :(得分:0)

请注意您当前的提交SHA。您可以使用git show在该SHA上获取文件的状态,并在回滚后重现该文件。

git show abcd1234:path/to/file > path/to/file

在任何时候查看任何commit-ish中的任何文件都很方便,并且在回滚的情况下工作,因为Git不会垃圾收集提交一段时间,即使它不再在你的任何分支上。至少在你的reflog失效之前,我相信Git默认会保留30天。

答案 3 :(得分:0)

虽然有很多方法可以在回滚时获得您想要维护的单个文件,但可以很容易地想象出更复杂的场景会很快变得难以处理。

这里的主要问题是A是否是您要创建的新分支(作为B的修改版本)。如果是,那么你不必担心“重写历史”(因为一切都将是新的),并且有一个非常愉快的选择来管理这个和更复杂的场景:git rebase。

以下是您创建 new 分支A的工作流程,该分支基于B,但有修改:

git checkout B          # Go to the tip of branch B.
git checkout -b A       # Create & checkout a new branch here named A.
git rebase -i           # Launch interactive rebase

此时,您将进入一个编辑器,其中包含来自B分支的所有提交的列表(尽管我们现在在A中,是B中更改的副本)。帮助文本非常好,但简短的总结是你现在可以重新排序提交(通过重新排序它们相应的行),删除提交(通过删除它们相应的行),一起压缩提交(将'pick'改为'squash'),编辑提交消息,等等。

根据您的情况,只需删除所有要丢弃的提交的行,然后保留要保留的提交。如果您对修改后的提交序列感到满意,保存并退出该文件,Git将会磨掉,您将留下一个新的分支A,它是原始分支B的修改形式。

Git rebase -i是一个非常习惯的超级大国,但请注意,你永远不应该改变任何其他人见过的现有分支(或者已被推向上游)。在你有空的时候阅读'git rebase',因为它是你工具箱中绝对需要的Git技能。