将有限的提交历史推送到远程git

时间:2016-11-27 23:07:07

标签: git github push git-commit git-fetch

我在学校的实验室机器上有一个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”时,我不想用它推送提交A-E,我只想从F向前推进。

我知道孤立的分支正是我在这里寻找的,但是我们的实验室正在运行git 1.7.x,它还没有这个功能,让管理员更新它只需要太长时间(我们当然没有权限自己做。)

我还读过我可以使用rebase对我的提交进行重新排序,以便F是最早的提交,然后我可以将单个提交推送到“proj1”。但是不会这样做会改变/搞乱我在主分支上的历史吗? (A-E已经在原点/主人身上)

所以我想知道我是否缺少git的一些功能来完成我想要的东西?有没有其他方法可以删除“newbranch”的提交历史记录,或至少将其分解?也许我正在做的是不好的做法,但就像我说的,我需要在这个目录中为CUDA SDK提供所有文件,我不想搞砸。

1 个答案:

答案 0 :(得分:2)

[[tl; dr ...如果你可以做你的&#34;起源&#34;项目&#34; proj1&#34;的子目录项目和使用Git子模块,你将过上幸福和平的生活。如果你不能或不能,你注定要花费10%的时间在&#34; proj1&#34;发展和你90%的时间与Git战斗到血腥死亡。]]

好的,我几乎是肯定的,你想法你需要接近这个的方式不仅仅是不好的做法,它是不可行的,所以我有一个作为Git用户的道德责任,告诉你应该做什么,而不是帮助你做你应该做的事情。也许其他人会带来一个我无法想到的神奇解决方案,但我不会屏住呼吸。

我认为你需要接受这样的事实,即这是两个独立的项目,他们需要有两个独立的工作目录(使用单独的&#34; .git&#34;子目录)。当然,这会带来两个直接的问题。首先,如果你需要在同一目录中大量混合这些文件,这似乎是不可行的;我试着在下面解决这个问题。其次,如果目录是完全独立的,那么它们的历史记录将被完全分开跟踪,因此当您提交特定版本的&#34; proj1&#34;时,您将无法记录哪个版本的&#34 ;来源&#34;用来运行它。

如果你想跟踪&#34;来源&#34;的版本用于&#34; proj1&#34;的每次提交,然后Git子模块(参见git help submodule)是要走的路。为了这个工作,&#34;起源&#34;必须保存在&#34; proj1&#34;的子目录中。树。你可以组织剩下的&#34; proj1&#34;但是你喜欢。同样,如果您需要混合文件,请参阅下文。 Git子模块在一个项目(&#34; proj1&#34;)上进行开发时效果很好,而第二个项目(&#34; origin&#34;)只是使用Git以方便保持最新状态约会并记住哪个版本的&#34;来源&#34;用于运行哪个版本的&#34; proj1&#34;。 (如果需要,子模块允许对第二个项目进行更改,但是让一切正常工作会很麻烦,所以如果子模块只是&#34;只读&#它会更好34。)

顺便说一下,Git子树(不是孤儿分支)是你做你想做的最接近的事情,但他们需要&#34; sub&#34; -project被安置在自己的专用子目录中,它们确实要求将子项目的整个历史记录包含在主项目中;他们只是允许子项目被拆分并独立推或拉。理论上,您可以将它们用于您的设置,处理&#34;起源&#34;作为主要项目并保持&#34; proj1&#34;在一个单独的子目录中作为&#34;子树&#34;。您可以正常使用存储库,&#34; git subtree&#34;将提供一种机制来分离在&#34; proj1&#34;子树并单独提交。太棒了吧?可悲的是,子树只能作为Git 1.7.10及更高版本的贡献模块(默认情况下不安装,我不这么认为)。但是,你可以试试&#34; git help subtree&#34;检查。

但是,这些解决方案中的任何一个都需要在自己的子目录中隔离一个项目。

如果绝对必须将文件混合在一个目录中,那么您将陷入痛苦的世界:最简单的方法是仍然来维护两个单独的Git工作目录(或Git子树)使用上面的机制(即,完全独立或使用子模块或子树的另一个子目录),然后构建符号链接树。符号链接树可以是:

  1. 是一个单独的&#34;构建&#34;实际运行项目的目录,所有文件的符号链接到每个真实的&#34; proj1&#34;和&#34;起源&#34;工作目录。

  2. 是一组实际添加到&#34; proj1&#34;的符号链接。工作目录并签入存储库。他们都可以指向&#34;起源&#34;的副本。在作为子模块管理的子目录中。

  3. 我能想到的符号链接树的唯一选择是更多痛苦。从技术上讲,你可以设置一个&#34; proj1&#34;工作目录&#34; .gitignore&#34;全部&#34;起源&#34;文件。然后,你可以愉快地运行&#34; git&#34;管理&#34; proj1&#34;仅限文件,忽略任何&#34;来源&#34;东西。当你想和&#34;起源&#34; (例如,要使用&#34; git pull&#34;)更新它,您可以使用&#34; - git-dir&#34;来运行Git。和/或&#34; - 工作树&#34;将您的工作树与不同的&#34; .git&#34;匹配的参数目录(配置为使用备用&#34; .gitignore-origin&#34;文件或其他东西)。我从来没有试过这个,听起来很可怕,但是你可能会让它发挥作用。

    现在,对于Git存储库的当前状态,您遇到了问题。你的&#34; newbranch&#34;现在与'&34;起源&#34;深深地交织在一起。项目的历史,没有简单的方法可以将它分开。如果你想重建历史,你需要使用一些过滤分支黑魔法,或者你需要手动完成(例如,从头到尾的每个提交,在当前树中检查它,复制&# 34; proj1&#34;文件到一个新的Git工作目录,遗漏任何&#34; origin&#34;文件,然后重新发送。

    关于孤儿分支,他们不会在这里帮助你。孤立分支只是普通的旧分支,碰巧与同一存储库中的其他分支没有共享历史记录。它可能看起来就像你追求的那样,但是一旦你经历了将它们全部放好的痛苦,你就会发现令人痛苦的事情。当你&#34; git checkout newproj&#34;为了研究&#34; proj1&#34;,Git会检查你所有的&#34; newproj&#34;文件并删除所有CUDA API文件!当你&#34; git checkout master&#34;为了能够访问CUDA API文件,Git将全部检查它们并删除你所有的&#34; newproj&#34;文件!你如何一次获得所有文件?显然,你设置了两个单独的工作目录并检查&#34; newproj&#34;在一个和#34;主人&#34;在另一个中,然后使用上述方法之一组合它们。与将这些视为完全独立的项目相比,它没有任何优势。你不可能有一个以某种方式保持&#34;的孤儿分支。 CUDA API文件没有将它们签入分支。

相关问题