Git: 在不丢失历史记录的情况下从存储库中获取一个子文件夹到一个新的子文件夹
Git: Get a subfolder from a repository to a new one without losing history
我有一个包含多个分支的应用程序的 git
存储库。源代码树由几个目录组成。例如:
main_folder
|--> .git
|--> dir0
|--> dir1
|--> dir2
不幸的是,从开发之初我就没有使用 git-submodules
也没有 git-subtree
。现在我想移动其中一个目录,例如 dir0
到一个新的存储库作为一个新的独立应用程序,当然如果可能的话,我想保留相应目录的历史和分支。
所以我有两个问题:
- 第一个也是显而易见的是我如何做到这一点?
- 同样对于旧存储库,最佳做法是什么?只需删除文件夹并提交更改,还是其他?
- 是的,绝对有可能!
然而,在新存储库中拥有与 dir0 相关的历史是不可能的(或者不容易)。然而,历史将存在于主项目中。
你能做什么!
一种。删除 dir1 并提交。
b.为 dir1 创建一个新的存储库。
C。将它作为子模块添加到主项目中,它将作为 sub-module.
供您使用
- 是的!
Edit-1
Giving your usecase I would suggest sub-module is the way to do it! You can use git log --pretty="%H" dir-1 | xargs -n 1 git format-patch -1
to create patches of commits that make changes to your "stand-alone application" in dir-1.
Now create a new repository with an initial repository with an empty-commit. You can clone something like it using git clone git://github.com/mudassirazvi/EMPTY_COMMIT
, then apply the patches one by one in order. (You can see the order by giving gitk dir1
or git log --oneline dir1
.
Now that your repo is ready with history, add it as a sub-module
PS: This is straight-forward if your commits don't multiple dirs in same commit. If any of the commits do so then use git rebase -i
to edit those commits to make all commits of "dir1" stand alone.
尝试git subtree split
。这样可以拆分一个子文件夹,保留历史。
请参阅有关如何使用它的手册页。
我结束了使用 git filter-branch
方法,Github 也提到了。
程序如下
将存储库克隆到新目录
cd
到新目录
假设我们要创建一个仅包含 dir0
分支 master
的新存储库,相应的 git
命令应该是:
git filter-branch --prune-empty --subdirectory-filter dir0 master
这将删除 除dir0
之外的所有其他文件和目录。此外,它将删除与 'dir0' 无关的提交,这非常方便。
在原始存储库中,只需删除目录 dir0
并提交。
使用git splits
它基本上使用与您相同的 git filter-branch
方法,但界面更简单。
- 安装
git splits
. I created it as a git extension, based on jkeating's solution。
- 将目录拆分为本地分支
#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 分支,就到此为止(你已经完成了)。
如果你想将新分支推送到一个独立的 repo
在某处创建一个空的 repo。我们假设我们已经在 GitHub 上创建了一个名为 new_repo
的空存储库,其路径为:git@github.com:simpliwp/new_repo.git
推送到新的仓库。
#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
将新创建的远程仓库克隆到新的本地目录
#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
存储库。源代码树由几个目录组成。例如:
main_folder
|--> .git
|--> dir0
|--> dir1
|--> dir2
不幸的是,从开发之初我就没有使用 git-submodules
也没有 git-subtree
。现在我想移动其中一个目录,例如 dir0
到一个新的存储库作为一个新的独立应用程序,当然如果可能的话,我想保留相应目录的历史和分支。
所以我有两个问题:
- 第一个也是显而易见的是我如何做到这一点?
- 同样对于旧存储库,最佳做法是什么?只需删除文件夹并提交更改,还是其他?
- 是的,绝对有可能!
然而,在新存储库中拥有与 dir0 相关的历史是不可能的(或者不容易)。然而,历史将存在于主项目中。
你能做什么!
一种。删除 dir1 并提交。
b.为 dir1 创建一个新的存储库。
C。将它作为子模块添加到主项目中,它将作为 sub-module.
- 是的!
Edit-1
Giving your usecase I would suggest sub-module is the way to do it! You can usegit log --pretty="%H" dir-1 | xargs -n 1 git format-patch -1
to create patches of commits that make changes to your "stand-alone application" in dir-1.
Now create a new repository with an initial repository with an empty-commit. You can clone something like it usinggit clone git://github.com/mudassirazvi/EMPTY_COMMIT
, then apply the patches one by one in order. (You can see the order by givinggitk dir1
orgit log --oneline dir1
.
Now that your repo is ready with history, add it as a sub-module
PS: This is straight-forward if your commits don't multiple dirs in same commit. If any of the commits do so then usegit rebase -i
to edit those commits to make all commits of "dir1" stand alone.
尝试git subtree split
。这样可以拆分一个子文件夹,保留历史。
请参阅有关如何使用它的手册页。
我结束了使用 git filter-branch
方法,Github 也提到了。
程序如下
将存储库克隆到新目录
cd
到新目录假设我们要创建一个仅包含
dir0
分支master
的新存储库,相应的git
命令应该是:git filter-branch --prune-empty --subdirectory-filter dir0 master
这将删除 除
dir0
之外的所有其他文件和目录。此外,它将删除与 'dir0' 无关的提交,这非常方便。在原始存储库中,只需删除目录
dir0
并提交。
使用git splits
它基本上使用与您相同的 git filter-branch
方法,但界面更简单。
- 安装
git splits
. I created it as a git extension, based on jkeating's solution。 - 将目录拆分为本地分支
#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 分支,就到此为止(你已经完成了)。
如果你想将新分支推送到一个独立的 repo
在某处创建一个空的 repo。我们假设我们已经在 GitHub 上创建了一个名为
new_repo
的空存储库,其路径为:git@github.com:simpliwp/new_repo.git
推送到新的仓库。
#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
将新创建的远程仓库克隆到新的本地目录
#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