将子目录(已重命名!)分离到新的存储库中 [英] Detach subdirectory (that was renamed!) into a new repo

查看:47
本文介绍了将子目录(已重命名!)分离到新的存储库中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个存储库,我想将其目录之一分离到新的存储库中. 是入门的理想之地,但有一个警告,不过:我要分离的目录在某个时候已重命名.而且,如果我使用该目录的新名称遵循该帖子中的解决方案,那么似乎我在重命名之前失去了历史记录.有什么想法可以使其在这种情况下起作用?

I have a repository and I would like to detach one of its directories into a new repo. This is a perfect place to get started, there is one caveat, however: the directory that I want to detach was renamed at some point. And if I follow the solution from that post with the new name of the directory then it seems I'm loosing the history before the re-name. Any ideas of a tweak to make it work in this situation?

推荐答案

git filter-branch可以对提交范围进行操作;所以我们可以做的是分别过滤之前"和之后",然后使用嫁接将它们固定在一起:

git filter-branch can operate on ranges of commits; so what we can do is filter the 'before' and 'after' separately, and use grafts to tack them together:

git branch rename $COMMIT_ID_OF_RENAME 
git branch pre-rename rename~
## First filter all commits up to rename, but not rename itself
git filter-branch --subdirectory-filter $OLDNAME pre-rename
## Add a graft, so our rename rev comes after the processed pre-rename revs
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
## The first filter-branch left a refs backup directory. Move it away so the
## next filter-branch doesn't complain
mv .git/refs/original .git/refs/original0
## Now filter the rest
git filter-branch --subdirectory-filter $NEWNAME master ^pre-rename
## The graft is now baked into the branch, so we don't need it anymore
rm .git/info/grafts

如果您需要过滤多个分支或标签,则这稍微复杂一些;重命名之前的分支可以包含在第一个过滤器分支中,而重命名之后的分支必须包含在第二个过滤器分支中的^rename之前.

This is marginally more complex if you need to filter multiple branches or tags; branches before the rename can be included into the first filter-branch, while ones after must be included before the ^rename in the second filter-branch.

另一种选择是添加索引过滤器(或树过滤器),而不是检查旧目录和新目录,并保留存在的目录.

Another option would be to add an index filter (or tree filter) instead that checks for both directories, old and new, and keeps whichever is present.

由于您尚未提供测试存储库,因此以下是此情况的快速完整性检查脚本:

Since you haven't provided a test repository, here's a quick sanity-check script for this scenario:

#!/bin/bash

set -u
set -e
set -x

rm -rf .git x y foo

git init
mkdir x
echo initial > x/foo
git add x/foo
git commit -m 'test commit 1'

echo tc2 >> x/foo
git commit -a -m 'test commit 2'

mv x y
git rm x/foo
git add y/foo
git commit -a -m 'test rename'

git branch rename HEAD

echo post rename >> y/foo
git commit -a -m 'test post rename'

git branch pre-rename rename~

git filter-branch --subdirectory-filter x pre-rename
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts

mv .git/refs/original .git/refs/original0

git filter-branch --subdirectory-filter y master ^pre-rename

rm .git/info/grafts

git log -u

如果此过程不适合您,则您尚未描述的存储库历史记录可能还有其他奇怪之处,例如隐藏在历史记录中的另一个重命名.

If this procedure does not work for you, then there is likely to be something else odd about your repository history that you haven't described, such as another rename hiding in the history.

这篇关于将子目录(已重命名!)分离到新的存储库中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆