【问题标题】:How to import an existing directory to an orphan branch如何将现有目录导入孤立分支
【发布时间】:2013-10-20 06:36:28
【问题描述】:

tl;博士

我想要的是一种整洁的方式,可以将代码从我的 Web 服务器推送到远程存储库中的孤立分支,之后无需在 Web 服务器上留下任何 Git 存储库,也无需先将整个远程存储库克隆到 Web 服务器上。我还需要在 Web 服务器上保留当前未版本化的文件。

编辑: 澄清一下,我不是在寻求一种方法来设置部署或任何类似的东西,我已经有了它的工作。我只需要一种方法将现有代码从非版本化目录整齐地推送到远程存储库中的新孤立分支,而不会弄乱网络服务器上的文件,也不会留下任何 .git 文件。

背景资料

我最近进入了使用 Git 对我的所有网站进行版本控制的趋势。它似乎比 FTP 容易得多,并且允许在具有完整历史和修订的团队中工作。我正在完成将所有内容导入 Git 存储库的过程,但遇到了一些问题。

我有一个项目,它将有多个(孤立)分支,代表代码的不同部署目标。出于这个问题的目的,这就是我的设置:

我有 3 台服务器。两个是 Web 服务器,一个是混合 Web-Git 服务器。

其中一个 Web 服务器是一个小型 VM,用作 Cloudflare 的 CDN 后端。它运行一个 nginx 服务器,只需向 Cloudflare 提供一次或两次更改或新文件以进行缓存(它很小,因为 Cloudflare 只请求一次文件,这意味着它不处理大量请求)。

我的第二个 Web 服务器托管实际网站并包含应用程序的整个服务器后端。

出于说明目的,两个 Web 服务器都是独立的机器。第三台机器只是 Git 服务器,托管着一堆 Atlassian 应用程序。

我还有一个以前的 SVN 存储库,其中包含与项目相关的服务器的 C# 源代码。

问题

我已将现有的 SVN 存储库导入 Git 存储库的“主”。我现在想创建 2 个孤立分支,一个用于 CDN 文件,一个用于网站文件。

经过一些研究,我遇到了这样的事情:git checkout --orphan <branchname>。这就是我的问题所在。我想创建一个分支来推送 CDN 等代码,然后从当前的 Web 服务器推送代码,而无需克隆整个存储库。因为git checkout 需要一个现有的 git repo 在工作目录中,所以我不知道该怎么做。我尝试git init-ing 我的文件所在的目录,在本地创建一个新分支,提交它们,然后使用git push git@mydomain.com:me/the_repo +local_branch:cdn_branch 将它们推送到远程分支,但这不起作用,并在我的 Web 服务器中留下了一个 Git 存储库 WWW文件夹。

【问题讨论】:

  • 我感到困惑的是为什么选择使用孤儿分支。从我在 Git 发布周期流程中看到的情况来看,一个人标记了一个分支,然后发布了该标记。如果您有多个需要特殊处理的目录,那么您将拥有多个 Git 存储库。此外,将源代码放在源代码控制中也没有什么坏处,因为您总是可以返回到旧版本。标签对您来说不是一个可行的选择吗?
  • @Makoto 如果你指的是我要求在你说:“在源代码管理中拥有源代码没有害处”之后不要留下 Git 存储库,我的意思是我有一种单独的方式来 VHosting 我的 repos,这样 repo 实际上不在我的 /var/www 文件夹中。我所有的代码目前都在那里,所以我需要一种方法来进行“路过”推送,而不会留下回购。
  • @Makoto 我们选择孤儿分支的原因是它可以让我们更轻松地跟踪项目。将来我们可能会为每个部分采用单独的 repo 的方式,但现在它使我们的 Git 主机更整洁地使用分支。此外,我当前的部署脚本基于分支工作,因此使用孤儿比重写我的脚本更容易。
  • 我不知道...这听起来很不合常规。通常,代码将存储在一个独立于它需要部署的位置的地方,并且您将有一个部署脚本将其放在 /var/www 中。我绝对是 Git 的常规用户,所以在这种情况下我无法为您提供太多帮助。
  • @Makoto 这正是我所拥有的。对不起,如果我不够清楚。我在我的 Web 服务器上运行了一个脚本,该脚本通过 POST 请求通过 git 服务器上的提交后挂钩调用。这个脚本然后执行一个 Bash 脚本,它计算出它需要做什么,然后从任何地方运行一个git fetch。我只需要一种方法来整齐地首先对源代码进行版本控制。查看我的编辑。

标签: git version-control


【解决方案1】:

经过一些实验,我得出了以下解决方案:

  1. 首先进入你想要推送到孤儿分支的目录

    例如:cd /var/www

  2. 初始化一个空的 Git 存储库

    例如:git init .

  3. 添加当前目录下的所有文件

    例如:git add .

  4. 提交他们

    例如:git commit -m "Importing existing code to branch blah"

  5. 将分支推送到远程仓库

    例如:git push <URL> master:<BRANCH NAME>

  6. 清理时间

    例如:rm -fr .git

我不需要将整个 Git 存储库克隆到我的网络服务器上!让我有一段时间的原因是孤立分支只有在您向其提交文件后才会创建。多次尝试git checkout --orphan BRANCH 并让我感到困惑,因为当我输入git branch 时分支没有显示。

【讨论】:

  • 对于它的价值,您甚至不需要在第 4 步中使用 --orphan,普通的 git checkout -b 也可以。存储库中没有任何内容,因此新分支头没有指向先前的提交,这就是为什么 git branch 在您提交之前无法显示它(它不会显示 [缺少] master任何一个)。此外,如果您打算从添加的遥控器中带回代码返回,请在步骤 7 中使用git push -u 将遥控器标记为新分支的“上游”。
  • 哦,评论上一条评论,我不知何故完全错过了第 8 步。用jthill's version 简化。
【解决方案2】:

合并两个存储库的一种方法是简单地将对象从一个.git/objects 目录复制到另一个目录。

repoA/.git/objects/* 复制到repoB/.git/objects/ 后,repoA 的对象(文件的提交和修订,而不是分支和简单标签)应按原样出现在 repoB 中。

从 repoA 导入的提交不会被 repoB 的任何分支指向,因此它们会暂时悬空提交。之后,您可以在 repoB 中创建一个指向这些导入提交的分支。

一个可能的风险是可能存在冲突的 SHA1 哈希(仅提及这种可能性,这不应该经常发生)。

======

不太确定我是否理解您想要做什么。也许你想用 git submodule 管理部分内容?

【讨论】:

    【解决方案3】:

    听起来您想提交到一台服务器并发布到另外两台服务器,而不需要发布服务器上的所有文件、历史记录等 - 我建议为复制的标签设置提交后过滤器发布文件到其他两台服务器。

    【讨论】:

      【解决方案4】:

      你可以跳过很多:

      cd /var/www
      git init
      git add .
      git commit -m"Importing existing code to branch blah"
      git push u://r/l master:blah
      rm -rf .git
      

      【讨论】:

      • 这个工作原理是一样的,所以我会把这个改成正确的:)
      • 嘿。不,你已经有了,把你的清理干净并放回去:-)
      • 完成! (遗憾的是,我必须等待 18 小时才能将我的标记为答案)
      猜你喜欢
      • 2014-03-17
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      相关资源
      最近更新 更多