我有一个Git分支,其中包含正常的Git提交历史记录;在开发周期中进行了添加/修改/删除。
我想回滚到以前的提交,但保留当前提交中未包含的文件(或者换个角度,从未来的提交中检出当前提交中不存在的文件)。
例如:
--------A--------B--------- ...
+ myFile.txt;
$ git checkout #A
我想要检出提交记录 #A,但是保留在提交记录 #B
中添加的 myFile.txt
文件。
我有一个Git分支,其中包含正常的Git提交历史记录;在开发周期中进行了添加/修改/删除。
我想回滚到以前的提交,但保留当前提交中未包含的文件(或者换个角度,从未来的提交中检出当前提交中不存在的文件)。
例如:
--------A--------B--------- ...
+ myFile.txt;
$ git checkout #A
我想要检出提交记录 #A,但是保留在提交记录 #B
中添加的 myFile.txt
文件。
git add goodFile.txt
。 - jorangit checkout goodFile.txt
似乎会自动将检出的文件暂存。 - whaleberg将myFile.txt文件从git仓库中拷贝到其他目录,然后切换到分支A。将该文件再次拷贝回仓库。
git show
获取该 SHA 的文件状态,并在回滚后重新生成它。git show abcd1234:path/to/file > path/to/file
这个功能非常方便,可以随时查看任何提交版本中的任何文件,并且在回滚的情况下也可以使用,因为 Git 不会立即清除该提交,即使它不再存在于任何分支上。您至少可以在其从 reflog 中删除之前使用该功能,我相信 Git 默认会保留 30 天。
虽然有方法可以获取您想要维护的单个文件,同时回滚,但很容易想象到更复杂的情况,这些情况很快就会变得难以控制。
主要问题在于A是否是您将创建的新分支(作为B的修改版本)。如果是,则无需担心“重写历史记录”(因为一切都是新的),并且有一个非常愉快的选项来管理此类更复杂的情况:git rebase。
以下是一个工作流程,您可以在其中创建一个新分支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是一种非常易养成的超能力,但请注意,您永远不应该对任何其他人看过(或已被推送到上游)的现有分支进行rebase。在有时间时,请阅读有关“git rebase”的内容,因为这是您绝对需要掌握的Git技能之一。