首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >git将目录移动到另一个存储库,同时保留历史记录。

git将目录移动到另一个存储库,同时保留历史记录。
EN

Stack Overflow用户
提问于 2017-01-23 17:19:10
回答 9查看 48.7K关注 0票数 57

首先,很抱歉问了这个问题。已经有很多关于它的话题了。但我对他们运气不太好。我对git不太熟悉,没有多大帮助。

我正在将一个文件夹从一个git移动到另一个git(已经存在)。例如:

代码语言:javascript
复制
repo-1
---- dir1
---- dir2
---- dir3
---- dir-to-move
---- dir5

repo-2
---- dir1
---- dir2
---- dir3

最后,我希望复仇者看起来像

代码语言:javascript
复制
repo-1
---- dir1
---- dir2
---- dir3
---- dir-to-move
---- dir5

repo-2
---- dir1
---- dir2
---- dir3
---- dir-to-move

也就是说,在一段时间内,两次回购中都会存在“双动”。但最终,我将把最新的修改迁移到回购-2,并从回购-1中删除dir- to -move。

我最初的研究让我相信我需要使用过滤分支。例如:

git am

从那时起,我就知道子树取代了这种方法。不过,它并没有达到我的预期。我以为我能做些像

在回购-1工作空间

代码语言:javascript
复制
git subtree split -P dir-to-move -b split

将分裂的分支过滤为只移动的分支,这是历史。然后在repo-2工作区中。

代码语言:javascript
复制
git remote add repo-1 repo-1-url.git
git subtree add --prefix dir-to-move split

这确实会把代码移到另一边。它也包括了历史

例如:

代码语言:javascript
复制
cd repo-2
git log

从回购-1提交的显示

代码语言:javascript
复制
cd repo-2
git log dir-to-move

只显示“从提交到移动.”

例如,历史记录包括在内,但在选中特定文件/目录时不显示。

我怎么才能做好这件事?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2017-01-23 19:38:28

我在git subtree上帮不了你,但是用filter-branch是可能的。

首先,您需要创建一个包含源分支和目标分支的公共存储库。这可以通过在“原产地”之外添加一个新的“远程”并从新的远程获取来实现。

在源分支上使用filter-branchrm -rfdir-to-move之外的所有目录。在此之后,您将拥有一个提交历史记录,可以干净地重定向或合并到目标分支中。我认为最简单的方法是从源分支cherry-pick所有非空提交。这些提交的列表可以通过运行git rev-list --reverse source-branch -- dir-to-move获得。

当然,如果dir-to-move的历史是非线性的(已经包含合并提交),那么它将不会被樱桃选择保留,因此可以使用git merge

示例创建公共回购:

代码语言:javascript
复制
cd repo-2
git remote add source ../repo-1
git fetch source

示例过滤分支

代码语言:javascript
复制
cd repo-2
git checkout -b source-master source/master
CMD="rm -rf dir1 dir2 dir3 dir5"
git filter-branch --tree-filter "$CMD"

将樱桃摘入目的地母版

代码语言:javascript
复制
cd repo-2
git checkout master
git cherry-pick `git rev-list --reverse source-master -- dir-to-move`
票数 30
EN

Stack Overflow用户

发布于 2018-04-29 19:06:21

FWIW,经过多次迭代后,以下内容对我起了作用。

将两个repos克隆到一个临时工作区。

代码语言:javascript
复制
git clone <repourl>/repo-1.git 
git clone <repourl>/repo-2.git
cd repo-1
git remote rm origin # delete link to original repository to avoid any accidental remote changes
git filter-branch --subdirectory-filter dir-to-move -- --all  # dir-to-move is being moved to another repo.  This command goes through history and files, removing anything that is not in the folder.  The content of this folder will be moved to root of the repo as a result. 
# This folder has to be moved to another folder in the target repo.  So, move everything to another folder.
git filter-branch -f --index-filter \
'git ls-files -s | /usr/local/bin/sed -e "s/\t\"*/&dir-to-move\//" |
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
        git update-index --index-info &&
 mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
# Above command will go through history and rewrite the history by adding dir-to-move/ to each files.  As a result, all files will be moved to a subfolder /dir-to-move.  Make sure to use gnu-sed as OSX sed doesn't handle some extensions correctly.  For eg. \t

现在切换到目标回购并从源获取所有内容。

代码语言:javascript
复制
git clone repo-2
git remote add master ../repo-1/
git pull master master --allow-unrelated-histories
git push  # push everything to remote 

以上步骤假设主分支同时用于源和目标。但是,标记和分支被忽略了。

票数 24
EN

Stack Overflow用户

发布于 2021-07-26 20:33:39

使用git subtree确实可以做到这一点。

在repo-1中创建一个子树:

代码语言:javascript
复制
git subtree split -P dir-to-move -b <split>

split分支现在将只包含dir-to-move目录。现在,您需要在回购-2中将分支从回购-1拉到分支。

万一回购-2碰巧是一个新的存储库(例如,就在git init之后),事情就像签出一个没有历史记录的分支和从回购-1中提取一样容易。

代码语言:javascript
复制
cd repo-2
git checkout <branch>
git pull <path-to-repo-1.git> <split>

但是,如果回购-2是已经提交的现有回购(如本问题中的情况),则需要从回购-2中的孤儿分支合并:

代码语言:javascript
复制
cd repo-2
git checkout --orphan <temp>                    # Create a branch with no history
git pull <path-to-repo-1.git> <split>           # Pull the commits from the subtree
git checkout <branch>                           # Go back to the original branch
git merge --allow-unrelated-histories <temp>    # Merge the unrelated commits back
git branch -d <temp>                            # Delete the temporary branch
票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41811986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档