git - 将一些子目录添加到本地仓库但不是远程?

时间:2011-09-14 22:51:06

标签: git

是否有(相对)简单的方法将树的某些部分添加到本地存储库但不是远程存储库?例如,假设我有类似

的内容
project_root/
-- src/ <- in local and remote
-- test/ <- in local and remote
-- my_dev_ideas/ <- currently untracked, want in local but not remote

我想添加my_dev_ideas/以便我可以在我的本地仓库中跟踪它,但在推送到远程时不包括它。我可以在分支中创建一个分支和my_dev_ideas/,但有几个挂断:

  • 当我尝试合并回(例如)master时,我不希望它创建my_dev_ideas/
  • 这是一个简化的例子 - 实际上它是一个相当大的项目,我有一些分散在整个树中的这样的目录。
  • IMO打破了“分支”的抽象概念。我仍然希望能够创建像add-feature这样的本地分支,这些分支在本地仍然包含这些目录。

我看过一些类似的问题但不是很好的答案。我真的不想使用子模块,因为涉及多个目录,因为我希望本地存储库历史记录能够反映这些目录中文件的更改。也就是说,除非有一种简单的方法可以做到这一点。

我希望以下内容对我有利。

  1. 目录不在回购站(本地或远程)。
  2. 我不一定需要挑选特定文件 - 只是目录树的一部分。
  3. 我理解为什么这可能非常复杂甚至不可能(假设我在同一次提交中更改src/foo.cppmy_dev_ideas/bananas.h ...)但我想看看是否有人有任何建议。

2 个答案:

答案 0 :(得分:0)

这听起来像是git submodules的工作,你可以单独跟踪它们。虽然这意味着你必须解决两个项目之间的联系问题,这可能会给你带来不同的麻烦。也许会有所帮助?

答案 1 :(得分:0)

(是的,我知道这已经超过一年了。但是我正在处理类似的事情,所以让我分享我的想法,希望它可以帮助某人)。

嗯,你可以做到。有几种方法,但它们都很复杂。但我认为这将证明是最简单的:

从存储库外部引入更改不是问题(假设没有人添加您在本地执行的相同文件)。像往常一样合并或改变。但是没有你的文件发布有点棘手。

首先,您需要找到最早的提交,其中添加了您不想发布的内容。让我们说那是1abcdef。我们真的想要那个提交的父级,所以让我们创建一个分支来引用它:

git branch before_publish 1abcdef^

注意行末尾的^。如果您正在使用Windows和cmd.exe,则必须使用第二个^字符引用它,即^^,因为cmd.exe使用^作为行继续符....

接下来,让我们创建并签出要发布的分支(假设我们已经检出了要发布的分支):

git checkout -b publish

现在是有趣的部分。我们想要摆脱这个有问题的文件的分支。

git filter-branch -f --index-filter 'git rm -r -f --quiet --cached --ignore-unmatch <your list of files and directories here>' before_publish..publish

好的,这会为您提供一个没有您不想发布的添加的分支。然后,您可以根据您的工作流程在您开始的主分支之上合并或重新定义这些更改,然后按照惯例推送它们。

请注意,这可能会使您的工作树中包含一些残余 - 空目录或包含已排除或未跟踪的文件的目录。但是他们离开了分店。

当然,最后一步是再次查看原来的工作分支。

下一次,您可以重复此过程 - 但您也可以合并自之后所做的更改。为方便起见,您可以将before_publish移至指向当前的发布主管,并添加一个分支以跟踪您上次在工作分支中合并的位置。

您无法直接使用'git merge' - 您必须使用:

git checkout publish
git branch -f before_publish
git cherry-pick last_published..my-main-branch
git filter-branch ... before_publish..publish
git checkout my-main-branch
git branch -f last_published

它有点复杂,但它可以避免您不必为其他文件的整个历史记录重复创建新提交。如果你做的事情很短暂,那可能不值得做。

你也可以这样做来撤消删除!而不是做'git rm',使用它的相反,git reset。您将使用它来存储丢失的文件和目录,它们仍然存在:

git filter-branch -f --index-filter 'git reset --quiet before_publish -- <paths to restore>' before_publish..publish

当然,如果你需要,你可以(并且应该)在一个'git filter-branch'操作中将两者结合起来。