【问题标题】:Git: Get a subfolder from a repository to a new one without losing historyGit:从存储库中获取一个子文件夹到一个新的而不丢失历史记录
【发布时间】:2015-02-18 12:15:45
【问题描述】:

我有一个具有多个分支的应用程序的git 存储库。源代码树由几个目录组成。例如:

main_folder
|--> .git
|--> dir0
|--> dir1
|--> dir2

很遗憾,从开发之初我就没有使用git-submodules,也没有使用git-subtree。现在我想将其中一个目录,例如dir0作为新的独立应用程序移动到一个新的存储库,当然如果可能的话,我想保留相应目录的历史记录和分支。

所以我有两个问题:

  1. 第一个也是显而易见的问题是我该如何做到这一点?
  2. 对于旧存储库,最佳做法是什么?只需删除文件夹并提交更改,还是其他?

【问题讨论】:

    标签: git git-submodules git-subtree


    【解决方案1】:

    试试git subtree split。这可以拆分一个子文件夹并保留历史记录。

    请参阅手册页了解如何使用它。

    【讨论】:

    • 我检查了您的解决方案,我可以说这与我的答案以及@Joelerr 的答案具有相同的结果。所以我等待一些可用的答案是否会得到一些赞成,以便接受最好的。
    【解决方案2】:

    使用git splits

    它基本上使用相同的git filter-branch 方法,但界面更简单。

    1. 安装git splits。我基于jkeating's solution 将它创建为一个 git 扩展。
    2. 将目录拆分为本地分支 #change into your repo's directory cd /path/to/repo #checkout the branch git checkout MyOldBranch #split directory or directories into new branch git splits -b MyNewBranch dir1 dir2 dir2...

    如果您只想将目录连同其历史记录复制到新的 MyNewBranch 分支,请在此处停止(您已完成)。


    如果您希望将新分支推送到独立存储库

    1. 在某处创建一个空仓库。我们假设我们在 GitHub 上创建了一个名为 new_repo 的空仓库,其路径为:git@github.com:simpliwp/new_repo.git

    2. 推送到新的仓库。 #add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_new_repo git@github.com:simpliwp/new_repo.git #push the branch to the new repo's master branch git push origin_new_repo new_repo:master

    3. 将新创建的远程仓库克隆到新的本地目录
      #change current directory out of the old repo cd /path/to/where/you/want/the/new/local/repo #clone the remote repo you just pushed to git clone git@github.com:simpliwp/new_repo.git

    【讨论】:

    • git split确实非常简单好用!
    【解决方案3】:

    我结束了使用git filter-branch 方法,Github 也提到过。

    过程如下。

    1. 将存储库克隆到新目录中

    2. cd 到新目录

    3. 假设我们要创建一个仅包含分支masterdir0 的新存储库,则对应的git 命令应该是:

      git filter-branch --prune-empty --subdirectory-filter dir0 master

    4. 这将删除dir0 之外的所有其他文件和目录。此外,它将删除与 'dir0' 无关的提交,这非常方便。

    5. 在原始存储库中,只需删除目录dir0 并提交即可。

    【讨论】:

      【解决方案4】:
      1. 是的,这绝对是可能的!
        但是,在新存储库中拥有与 dir0 相关的历史记录是不可能的(或不容易)。但是,历史将存在于主项目中。

      你能做什么!
      一种。删除 dir1 并提交。
      湾。为 dir1 创建一个新的存储库。
      C。将其作为子模块添加到主项目中,您可以使用 sub-module

      1. 是的!
      编辑-1
      给你的用例我建议子模块是这样做的!您可以使用 git log --pretty="%H" dir-1 | xargs -n 1 git format-patch -1 创建提交补丁,以更改 dir-1 中的“独立应用程序”。

      现在创建一个新的存储库,其中包含一个带有空提交的初始存储库。您可以使用git clone git://github.com/mudassirazvi/EMPTY_COMMIT 克隆类似的东西,然后按顺序一一应用补丁。 (您可以通过提供 gitk dir1git log --oneline dir1 来查看订单。
      现在您的仓库已准备好历史记录,请将其添加为子模块

      PS:如果您的提交在同一提交中没有多个目录,这是直截了当的。如果有任何提交这样做,则使用git rebase -i 编辑这些提交以使“dir1”的所有提交独立。

      【讨论】:

      • 嗯,历史对我来说很重要。我希望以某种方式将它放在新的存储库中。另外,我希望新的 repo 独立于旧的 repo,所以我不认为 submodule 方法是最好的。
      • 当你说独立时,这是否意味着两者都没有任何依赖关系。如果是这样,为什么还要有一个子模块?
      • 是的,它们是完全独立的。想象一下,子目录将作为主项目的插件。所以我想继续开发它作为一个新的独立项目。我提到了git-submode,因为我知道如果我从开发之初就使用它们,现在会更容易实现我想要的。这不是必需的。
      猜你喜欢
      • 2019-07-23
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 2015-05-10
      • 1970-01-01
      • 2017-09-15
      相关资源
      最近更新 更多