我在学校的实验室机器上有一个git存储库,遇到了我一直试图解决的问题。
由于我们使用的CUDA SDK的安排,我在同一目录中有两个远程服务器,但我不希望将来自一个远程源的所有提交都推送到另一个远程“ proj1”。我在下面会更清楚:
最初,此目录具有一个带有单个远程目录的git存储库,例如,以下提交历史记录:
A-B-C-D-E <-(origin/master)
然后,我添加了第二个远程对象,并创建了一个本地分支,我可以从该分支推送并从中获取:
A-B-C-D-E-G <-(origin/master) (master)
'
'-F-H-I <-(proj1/newbranch) (newbranch)
现在,当我将更改从“ newbranch”推送到远程“ proj1 / newbranch”时,我不想用它推送commit AE,我只想从F向前推送。
我知道孤立的分支正是我在这里寻找的东西,但是我们的实验室正在运行git 1.7.x,它尚不具备该功能,并且让管理员对其进行更新花费的时间太长了(我们不会有权自行执行此操作)。
我还读到我可以使用rebase对提交进行重新排序,以便F是最早的提交,然后可以将单个提交推送到“ proj1”。但是,这样做是否也不会改变/弄乱我在master分支上的历史呢?(AE已在原点/主节点上)
所以我想知道我是否缺少git的某些功能来完成我想要的?还有其他方法可以删除“ newbranch”的提交历史记录,或者至少可以将其中断吗?也许我正在做的是不好的做法,但是就像我说的那样,我需要在此目录中拥有CUDA SDK的所有文件,而我不想弄乱它。
[[tl; dr ...如果您可以将“ origin”项目设置为“ proj1”项目的子目录,并使用Git子模块,那么您将过上幸福与和平的生活。如果您不能或不愿意,那么您注定要花费10%的时间用于“ proj1”开发,而90%的时间则要与Git战斗到流血死亡。
好的,我几乎可以肯定的是,您认为您需要采取的方法不仅是错误的做法,而且是行不通的,因此,作为Git的资深用户,我负有道义的责任,告诉您应该怎么做而不是帮助您做您认为应该做的事。也许会有其他人带来我从未想到的神奇解决方案,但我不会屏住呼吸。
我认为您需要接受以下事实:它们是两个单独的项目,并且它们需要有两个单独的工作目录(带有单独的“ .git”子目录)。当然,这带来了两个紧迫的问题。首先,如果您需要将这些文件大量混合在同一目录中,则这似乎不可行;我尝试在下面解决这个问题。其次,如果目录是完全分开的,则它们的历史记录也将完全分开跟踪,因此,当您提交特定版本的“ proj1”时,您将没有记录使用哪个版本的“ origin”来运行它。
如果您确实想跟踪用于每次提交“ proj1”的“ origin”的版本,那么Git子模块(请参阅参考资料git help submodule
)是可行的方法。为此,“ origin”必须保留在“ proj1”树的自己的子目录中。您可以根据需要组织其余的“ proj1”。同样,如果您需要混合文件,请参见下文。当在一个项目(“ proj1”)上进行开发,而第二个项目(“ origin”)仅在使用Git进行开发时,Git子模块可以很好地保持最新状态并记住哪个版本的“ origin”用于运行哪个版本的“ proj1”。(子模块允许在需要时对第二个项目进行更改,但要使所有工作正常进行都是很麻烦的,
顺便说一句,Git子树(不是孤立分支)是最接近您认为想要做的事情的东西,但是它们确实可以要求将“子”项目放置在其自己的专用子目录中,并且确实要求将子项目的整个历史记录都包含在主项目中;它们仅允许子项目被独立拆分和推入或拉出。从理论上讲,您可以使用它们进行设置,将“起源”作为主要项目,并将“ proj1”保留在单独的子目录中作为“子树”。您将像往常一样在存储库上工作,而“ git subtree”将提供一种机制来拆分“ proj1”子树中正在完成的工作并将其分别提交。太好了吧?遗憾的是,子树仅在Git 1.7.10及更高版本中可用作贡献模块(默认情况下未安装)。但是,您可以尝试使用“ git help子树”进行检查。
但是,任何这些解决方案都需要将一个项目隔离在其自己的子目录中。
如果绝对必须将文件混合在一个目录中,那么您将痛苦不堪:最直接的方法仍然是使用上述机制维护两个单独的Git工作目录(或Git子树)(即,完全独立)或使用子模块或子树来建立另一个子目录),然后构建一个符号链接树。符号链接树可以:
是一个单独的“ build”目录,在该目录中您实际运行项目,所有文件的符号链接均指向实际的“ proj1”和“ origin”工作目录中的每个目录。
是一组实际上已添加到“ proj1”工作目录并签入到存储库中的符号链接。它们都可以指向作为子模块管理的子目录中“原始”的副本。
唯一的替代符号链接树,我能想到的是很多更痛苦。从技术上讲,您可以设置一个“ proj1”工作目录,其中“ .gitignore”包含所有“原始”文件。然后,您可以愉快地运行“ git”来仅管理“ proj1”文件,而忽略任何“原始”内容。当您想使用“ origin”(例如,使用“ git pull”进行更新)时,可以使用“ --git-dir”和/或“ --work-tree”参数运行Git以匹配您的具有不同“ .git”目录的工作树(配置为使用其他“ .gitignore-origin”文件等)。我从来没有尝试过,这听起来很可怕,但是您可能会使其工作。
现在,关于您的Git存储库的当前状态,您遇到了问题。您的“ newbranch”现在已经与“ origin”项目的历史紧密地交织在一起,没有简单的方法可以将其分开。如果要重建历史记录,则需要使用一些过滤分支的黑魔法,或者需要手动进行(例如,对于从头到尾的每次提交,请在当前树中将其检出,复制“ proj1文件添加到新的Git工作目录中,而忽略所有“原始”文件,然后重新提交)。
关于孤儿分支,他们不会在这里为您提供帮助。孤分支只是普通的旧分支,碰巧没有与同一存储库中的其他分支共享任何历史记录。看起来像是在追求什么,但是一旦经历了全部设置的痛苦,您就会发现有些困扰。当您“ git checkout newproj”在“ proj1”上工作时,Git将检出您所有的“ newproj”文件并删除所有CUDA API文件!而且,当您“ git checkout master”获得对CUDA API文件的访问权限时,Git会全部检查它们并删除所有“ newproj”文件!您如何一次获取所有文件?显然,您设置了两个单独的工作目录,并在其中一个中检出了“ newproj”,在另一个中检出了“ master”,然后使用上述方法之一将它们合并。与将它们视为完全独立的项目相比,它没有任何优势。您不能有一个孤立的分支,以某种方式“保留” CUDA API文件,而不将其签入分支。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句