Git-防止在合并时添加开发目录
我是一名程序员,更熟悉高级编程语言,如C#或Python,但我最近开始深入研究Git的复杂性。上下文:我正在开发一个游戏,我有一个Git-防止在合并时添加开发目录,git,git-merge,Git,Git Merge,我是一名程序员,更熟悉高级编程语言,如C#或Python,但我最近开始深入研究Git的复杂性。上下文:我正在开发一个游戏,我有一个development分支,它有一个特定的'development'目录,为了保持master干净,不会在合并中推送到master 我来到了一个几乎能胜任这项工作的地方;但是,这种方法虽然不会将更改提交到目录,仍然会在主节点分支上创建它,这意味着每次合并后,我仍然需要返回并手动删除文件 我正在设置一个别名git publish来自动执行此任务,为了完整起见,我将在这里
development
分支,它有一个特定的'development'
目录,为了保持master
干净,不会在合并中推送到master
我来到了一个几乎能胜任这项工作的地方;但是,这种方法虽然不会将更改提交到目录,仍然会在主节点
分支上创建它,这意味着每次合并后,我仍然需要返回并手动删除文件
我正在设置一个别名git publish
来自动执行此任务,为了完整起见,我将在这里发布此任务:
[alias]
publish = "!f(){ git checkout master \
&& git merge --no-commit --no-ff development \
&& git reset -- Assets/Development/ \
&& git commit \
&& git push; };f"
我想知道,有没有什么办法可以阻止
资产/开发/
在主机上创建?
旁注:摆弄.gitignore
不会有帮助,因为.gitignore
的本质不是真正的“要忽略的文件”,而是“用于抑制某些投诉的文件,和/或在某些情况下可以随意销毁的文件”。(这并不是说您不应该出于其他原因调整.gitignore
,只是这无助于解决此合并问题,因为您确实希望在开发分支中对这些文件进行版本控制。)
您现有的解决方案(以及可能改进的方法)
一个技巧基本上就是你现在正在做的:进行合并(使用--no commit
),然后去掉你不想要的东西
剥离步骤如下所示:
git reset -- Assets/Development/
这使用了--mixed
(默认,并在提供路径时强制您)形式的git reset
,它设置(或“reset”,实际上)索引以匹配指定路径的指定树。这里的路径是Assests/Development/
,即该子目录中的所有内容。指定的树没有指定,因此它默认为HEAD
,或者更确切地说,HEAD
的树是当前分支上的当前提交,这当然是master
,因为我们刚刚选中了它那就是:而且master
根本不包含Assets/Development/
,因此重新设置的索引现在不再包含该子树
简言之,由于Assets/Development/
不在HEAD
中,这会撤消git merge
对Assets/Development
中的所有内容所做的git add
操作。问题是,虽然这会从索引中删除条目,但会将它们留在工作树中
人们可能会尝试git reset--hard--Assets/Development/
,但git不会这么做:在提供路径时,不能指定重置模式。不过,这还剩下三个明显的选项:
- 添加
(就在rm-r资产/开发
之前或之后,甚至在git重置
步骤之后) 这将删除这些文件,这样,当它们从索引和工作树中消失后,您就可以提交并完成它们了提交
- 使用
(代替git-rm-rf资产/开发/
) 这将删除索引项并删除工作树文件(和目录),以便您可以提交和完成git重置
- 提交后使用
。这可能会超出您的需要git clean
git merge
时,git首先找到合并基
合并基数被定义为LowestCommonAncestor(LCA)在图中两个节点之间的提交图中。在本例中,这两个节点是您当前的提交,分支master
的提示,以及您提交给git merge
,在本例中,这是分支开发
的提示提交。LCA的定义需要一点图论,但不严格地说,这是两个提交历史记录上的“最近”提交
为了了解这是如何工作的,它有助于绘制提交图的一部分。这里我们将master
和development
作为两个分支提示,两个分支结构(提交链)最终连接在一起:
... <- o <- * <- o <- ... <- o <-- master
\
o <- o <- ... <- o <-- development
现在您继续在development
上开发,进行更多新的提交。让我们用o
替换*
,因为它不再是特例
...--o--o--o-...-o---o <-- master
\ /
o--o-...-o--o--o <-- development
现在标记为*
的节点可以从主节点(通过向下和向左跟随第二个父节点)和开发节点(通过向左跟随链)访问。它是最近的此类节点,因此是合并基础
Git现在将合并基*
与这两个提示区分开来。如果对master
的提示有任何更改,则应该很少(基本上只有从o
节点在先前的合并基和master
的新提示之间拾取的内容),以及自上次合并以来对开发
分支所做的任何更改
如果这些更改影响资产/开发
中的现有文件,则这些更改将导致合并冲突:
CONFLICT (modify/delete): Assets/Development/foo deleted in HEAD
and modified in development. Version development of
Assets/Development/foo left in tree.
Automatic merge failed; fix conflicts and then commit the result.
请注意,这些代码不需要--no commit
另一方面,如果这些更改在Assets/Development/
中添加了新文件,merge将很高兴地将它们添加到您即将进行的提交中,因此您确实需要--no commit
来避免添加任何此类文件
如果需要,您可以再次使用git rm-rf
抛出任何冲突和/或添加的文件。为什么不能将其放入.gitignore?为什么不能将文件夹放在包含存储库的目录之外,
...--o--o--o-...-o---o <-- master
\ /
o--o-...-*--o--o <-- development
CONFLICT (modify/delete): Assets/Development/foo deleted in HEAD
and modified in development. Version development of
Assets/Development/foo left in tree.
Automatic merge failed; fix conflicts and then commit the result.