Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重新基址或合并Git分支,但保留已删除的文件_Git_Github - Fatal编程技术网

重新基址或合并Git分支,但保留已删除的文件

重新基址或合并Git分支,但保留已删除的文件,git,github,Git,Github,我从master为一个子项目创建了我的_分支(见下图)。我不得不从我的_分支中删除很多文件,因为它们与子项目无关,但在master中仍然需要这些文件。有一段时间,这种发展发生在master和my_分支机构 现在子项目已经完成,我想重新设置或合并从我的_分支到master的更改。但我想保留在我的_分支中删除但仍存在于master中的所有文件。最简单的方法是什么 我意识到我应该创建一个单独的存储库并重构项目。但鉴于目前的情况,我能做些什么,最好不要手动 不幸的是,我不能假设所有被删除的文件都是单独提

我从master为一个子项目创建了我的_分支(见下图)。我不得不从我的_分支中删除很多文件,因为它们与子项目无关,但在master中仍然需要这些文件。有一段时间,这种发展发生在master和my_分支机构

现在子项目已经完成,我想重新设置或合并从我的_分支到master的更改。但我想保留在我的_分支中删除但仍存在于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

分支,执行合并并传递
--no commit
标志:

git merge my_分支--无提交

现在,您可以取消删除合并要删除的文件:

git复位头

git签出--

命令
git status
将向您显示它要删除的文件,如果您愿意,您可以使用脚本解析此输出,有选择地重置/签出所有已删除的文件

然后继续提交最终结果:


git commit

更新-我之前对如何在重基期间处理
编辑
提交的解释不够清楚,不准确。澄清


一种可行的方法(如Ben所建议的)是编辑合并。存在一个潜在的不利因素,即此合并将违反某些命令所做的假设(例如,
rebase
,即使给出了
--preserve merges
)。这可能会导致此类命令在报告成功时悄悄产生损坏的结果

还有一种选择,尽管它更复杂。它还涉及重写分支的历史记录,但您提到可能会重新设置分支的基础,因此我认为这不是问题

这里的想法是放弃从历史记录中删除的文件,以便文件始终存在,处于创建分支时的状态。(老实说,这可能是一开始就应该做的。)

这方面的最佳程序取决于很多事情。有些更普遍可行(但更复杂),而另一些更容易执行(但只有在某些事情是真实的情况下才有效)

听起来这些文件不是一次全部删除的,而是在发生其他更改的同一提交中删除的

有可能一个交互式的重基会起作用。当然,您可以使用
过滤器分支
。两者的某种组合也可能是一种选择

如果
my_branch
像您描述的那样是线性的-在分支上没有合并提交-那么您可能可以通过交互式重新基址来获得

git rebase --interactive master my_branch
在弹出的待办事项列表中,为
edit
(而不是默认的
pick
)标记可能包含不需要的删除的任何提交。随着重基进程的进行,它将在尝试提交每个修补程序后暂停。要查找不需要的删除,可以执行以下操作

git diff --diff-filter D --no-renames --name-only HEAD^
git rebase --interactive `git merge-base my_branch master` my_branch
(更简单的命令会起作用;这会尝试只获取已删除文件名的列表,以便您可以检查要反转的文件名。特别是,您可能想要或不想要
--不重命名
;这是为了避免意外触发重命名检测,这可能会阻止显示删除,但如果确实重命名了大量文件这将导致htem显示为删除。)

撤消特定的删除

git checkout HEAD^ -- path/and/filename
当你有相反的删除

git add .
git commit --amend
上面的rebase命令还将在
master
的顶端完成工作的重定基址。如果您不想这样做,例如,如果您想将工作合并到
master
中,您可以执行以下操作

git diff --diff-filter D --no-renames --name-only HEAD^
git rebase --interactive `git merge-base my_branch master` my_branch
如果这看起来太过手动,或者存在使其无法工作的复杂性,那么您可能更喜欢
过滤器分支
——但请注意,如果历史记录很大,这可能会很慢

在这种情况下,您需要的是一个重新添加已删除文件的
树过滤器

git checkout `git merge-base master my_branch`
cp all/the/files/that/were/deleted some/path/where/I/can/find/them/later
然后


在这里,我想了想-取消跟踪您在my_分支中删除的master中的所有文件,然后提交master.Merge(或rebase)您的my_分支进入master。然后再次跟踪所有文件?虽然这看起来很简单,应该可以工作,但我不推荐这样做。原因是,如果遇到您的合并,进一步的回退可能会造成严重破坏。如果合并成功(但会产生不想要的结果)使用默认策略,那么使用<代码>——没有提交< /代码>来编辑合并是有点危险的。如果你知道你无论如何也不能通过这个回购中的合并来重置-例如,如果你已经有所谓的“邪恶合并”了,那就没事了。如果没有,我会考虑一个不同的方法(我会把它作为一个单独的答案)。谢谢Ben和Mark:我使用了你的两个建议的元素,但Mark的建议更有用。谢谢,Mark,这很有教育意义。我能够使用你的方法进行合并(谢天谢地,我不需要全部)。我也使用了Ben的部分答案。这也适用于目录吗?编辑:对于那些使用zsh的人,请改用这个:
git checkout HEAD~--your/directory
它也适用于检查当前HEAD中以前删除的文件,非常感谢@Mark Adelsberger