我从master中创建了my_branch(参见下图)以获取子项目。我不得不从my_branch中删除很多文件,因为它们与子项目无关,但在master中仍然需要这些文件。有一段时间,开发工作正在master和my_branch中进行。
现在子项目已经完成,我想将my_branch中的更改重新绑定或合并到master。但我想保留my_branch中删除但仍存在于master中的所有文件。最简单的方法是什么?
我意识到我应该创建一个单独的存储库并重构项目。但考虑到手头的情况,我该怎么做,最好不要手动?
不幸的是,我无法假设所有已删除的文件都在单独的提交中。
* 172c3f3 (origin/my_branch, my_branch) comment
| * e4f6849 (origin/master, origin/HEAD, master) Merge branch asdf
| |\
| | * c796e73 aafg
| |/
| * 75720e5 Merge branch zxcv
| |\
| | * 7c694e9 changes
| |/
* | 61370ac some
* | 8afc0be development,
* | d14263b bugfixes,
* | 0d5a17f testing,
* | 588cf8f maybe some cleanup
* | 588cf8f here and there
* | e1f990b and a lot of files
* | 146212b removed
* | 09c6278 but they are still needed in master
|/
* 9a53a83 my_branch created here
答案 0 :(得分:1)
来自master
分支,进行合并并传递--no-commit
标记:
git merge my_branch --no-commit
现在您可以取消删除合并要删除的文件:
git reset HEAD <file>
git checkout -- <file>
命令git status
将显示要删除的文件,如果您愿意,可以使用脚本解析此输出以选择性地重置/检出所有已删除的文件
然后继续提交最终结果:
git commit
答案 1 :(得分:1)
更新 - 我以前关于如何在rebase期间处理edit
提交的解释不清楚是不准确的。澄清
一种可行的方法(如Ben所建议的)是编辑合并。存在潜在的缺点,因为这种合并将违反某些命令所做的假设(例如rebase
,即使给出--preserve-merges
也是如此。这可能导致此类命令在报告成功时静默生成损坏的结果。
有另一种选择,虽然它更复杂。它还涉及重写分支的历史,但你提到你可能会重新分支分支,所以我认为这不是问题。
这里的想法是丢弃历史记录中的文件删除,以便文件始终存在,处于创建分支时的状态。 (说实话,这应该是首先应该做的事情。)
最好的程序取决于很多事情。有些更普遍可行(但更多参与),而其他更容易执行(但只有在某些事情成立时才有效)。
听起来这些文件并非全部被删除,并且在发生其他更改的相同提交中被删除。
交互式rebase可能会起作用。当然你可以用filter-branch
来做。两者的某种组合也可能是一种选择。
如果my_branch
与您描述的一样线性 - 在分支上没有合并提交 - 那么您可能会使用交互式rebase。
git rebase --interactive master my_branch
在弹出的TODO列表中,标记任何可能包含edit
不需要的删除的提交(而不是默认的pick
)。随着rebase的进展,它会在暂时提交每个补丁之后暂停。要查找不需要的删除,您可以执行类似
git diff --diff-filter D --no-renames --name-only HEAD^
(更简单的命令将起作用;这会尝试仅获取已删除文件名的列表,以便您可以检查要反转的文件名。特别是,您可能想要也可能不想要--no-renames
;它可以意味着避免意外触发重命名检测,这可能会阻止删除显示,但如果你真的重命名了很多文件,这将导致htem显示为删除。)
撤消特定删除
git checkout HEAD^ -- path/and/filename
当你删除了删除
git add .
git commit --amend
上述rebase命令还将完成您的工作重新定位到master
的提示。如果您不想要那样 - 例如如果你想将工作合并到master
- 你可以做类似的事情
git rebase --interactive `git merge-base my_branch master` my_branch
如果这似乎是手动的,或者如果有复杂性使其无法工作,那么您可能更喜欢filter-branch
- 但要注意,如果历史很大,这可能会很慢。
在这种情况下,您需要的是tree-filter
重新添加已删除的文件。我将从合并基础
git checkout `git merge-base master my_branch`
cp all/the/files/that/were/deleted some/path/where/I/can/find/them/later
然后
git filter-branch --tree-filter 'cp some/path/where/I/can/find/them/later all/the/files/that/were/deleted' -- my_branch