我有一个包含在一个git存储库中的分支中开发的实用程序库的目录,但事实证明它们确实属于不同项目中的不同目录。我已经多次阅读并尝试过Greg Bayer Moving Files from one Git Repository to Another, Preserving History,但我无法保留历史。我试图在非主分支下完成这一切,以便更安全,因为项目还没有准备好合并回主人。
这是我到目前为止所做的事情:
准备从“Repo1”存储库的分支“SomeBranch”移动“DirectoryName”目录:
cd ~/Desktop
git clone git@github.com:username/Repo1.git
cd Repo1
git checkout -b SomeBranch origin/SomeBranch
git remote rm origin
git filter-branch --subdirectory-filter DirectoryName
mkdir DirectoryName
git mv *.php *.txt DirectoryName
git add DirectoryName
git commit -m "Stripped everything down to just DirectoryName."
将“DirectoryName”目录合并到“Repo2”存储库的“SomeBranch”分支中:
cd ~/Desktop
git clone git@github.com:username/Repo2.git
cd Repo2
git checkout -b SomeBranch origin/SomeBranch
git remote rm origin
git remote add Repo1 ../Repo1/
git pull Repo1 SomeBranch
git remote rm Repo1
当我这样做时,我可以成功地将所有内容都删除到Repo1中的“DirectoryName”(我也可以将其拉到Repo2),但历史记录丢失了。如果我执行git log -- DirectoryName
或git log -- DirectoryName/SomeFile.php
,我只会看到“将所有内容删除到只有DirectoryName”。承诺)。所以,我的git filter-branch
命令显然有问题,但我对它的了解还不够熟悉。
任何建议都会受到高度赞赏,因为我们正在对代码库进行一些根本性的更改,因此我需要相对频繁地执行此操作一段时间(因为我们希望保留历史记录)。 / p>
更新:正如我所提到的git log -- DirectoryName
(或git log -- DirectoryName/SomeFile.php
;无论是在Repo1还是Repo2中)都没有显示任何其他提交“将所有内容删除到只有DirectoryName。 “提交,但如果我git log
,我会看到正确的提交历史记录。我只是错误地使用git log
还是有一些腐败导致提交无法正确显示?
另一个更新: git log -- DirectoryName
在原始未经修改的Repo1中显示正确的提交,但不显示git filter-branch
之后的正确提交(我已经尝试了git filter-branch --subdirectory-filter DirectoryName -- --all
但是那个“主”分支也是如此,并且似乎没有必要......同样的结果)。也就是说,在运行git filter-branch
之后,提交历史就在那里,我可以用git log master..
看到它,它似乎不再与目录或文件有关。有什么想法吗?
答案 0 :(得分:2)
听起来好像你所做的一切都很好,这只是对导致问题的git log
的误解。
git只是在每次提交时存储树的状态,而不是记录在一次提交中将树从状态转移到下一次提交的更改。但是,如果您使用git log
查找特定文件或目录的历史记录,则可以告诉它在文件的历史记录用完时尝试查找重命名。你可以用:
git log --follow -- DirectoryName
或者,如果这不起作用,请仅针对单个文件进行尝试,例如
git log --follow -- DirectoryName/whatever.txt
答案 1 :(得分:0)
我是这样做的:
为触及子目录中文件的所有提交创建补丁:
$ c=1; git log --format=%h -- subdir/*|tac|while read commit; do
git format-patch --stdout -1 $commit > $(printf '%04d' $c).patch
c=$((c+1))
done
请注意,如果有单个提交触及subdir和subdir之外的两个文件,那么补丁也会在另一个文件中包含diff,因此您必须修剪这些文件,或者执行过滤分支以删除完成以下第二步后的那些文件:
使用git am在其他repo中的分支上应用补丁:
$ git am *.patch