分叉git repo到原始的端口功能没有拉入整个分叉回购

时间:2013-09-23 17:01:36

标签: git

我只是在学习git而且我有一点难题......

我不拥有两个项目:

  • Delila

背景

  • Delila曾在古老的遥远的过去与Julio分道扬..
  • Julio继续快速发展。
  • 我有一个Delila的功能,我想把它放到Julio中。
  • 对于Julio的所有者来说,这个功能毫无意义,因为它不够通用(这就是为什么Delila的原始作者从不打算提供拉取请求)。
  • Delila显然不希望Julio的所有新东西提供一个庞大的拉动请求,从Julio到Delila的所有新东西都不合理。

头发计划

现在,我想从Delila拿一个文件并把它放到Julio中,因为Julio包含了我需要的一堆善良,而Delila包含了我真正可以做的奇妙功能。

所以,实际上,我可以这样做:

  1. 将Julio分给我实际拥有的新项目(我将其称为Benito)
  2. git clone Delila获取旧代码
  3. git clone Benito获取新代码的分支
  4. 将我需要的文件从包含Delila的目录复制到Benito
  5. 稍微调整它以使其与周围的新东西一起使用,然后将它添加到Benito中
  6. git commit Benito,git推它,去做一个当之无愧的一杯茶
  7. 除了茶味道酸。我对其他人的工作表示赞赏(如果你查看文件的历史,你只看到我),我已经失去了,有用的历史信息(为什么哦为什么哦为什么那个疯狂的懒人那样做?)

    那么在这种情况下做什么是正确的呢?


    更新

    感谢@djechlin我一直在玩这个,但我仍然无法使它工作。在这里,我通过在本地创建两个存储库Julio和Delila来模拟这种情况。所以,这是起始情况:

    ~/playing/Julio (master)
    $ git log
    commit f72960c18392d843d40adfd1c7ab943162005879
    Author: xxxxx
    Date:   Tue Sep 24 08:46:50 2013 +0200
    
        A change after Delila left the building
    
    commit eca80d52acefcb02baae48e717bd8c2d98685c5e
    Author: xxxxx
    Date:   Tue Sep 24 08:31:15 2013 +0200
    
        initial commit from Julio
    

    Delila

    ~/playing/Delila (master)
    $ git log
    commit 0e7c530246bc782dbf30fb4ac425e031d3626bbe
    Author: xxxxx
    Date:   Tue Sep 24 08:39:06 2013 +0200
    
        Added changes for Delila
    
    commit eca80d52acefcb02baae48e717bd8c2d98685c5e
    Author: xxxxx
    Date:   Tue Sep 24 08:31:15 2013 +0200
    
        initial commit from Julio
    

    你可以看到Delila已经从Julio分叉并且发生了一些变化。具体来说,Delila 提交的添加的更改是我想要维护的。

    现在,从〜/开始我这样做,根据答案:

     ~/playing
    $ mkdir me
    
     ~/playing
    $ cd me
    
     ~/playing/me
    $ git clone ../Delila
    Cloning into 'Delila'...
    done.
    
     ~/playing/me
    $ cd Delila
    
     ~/playing/me/Delila (master)
    $ git remote rm origin
    
     ~/playing/me/Delila (master)
    $ git filter-branch --subdirectory-filter someFolder -- --all
    Rewrite 0e7c530246bc782dbf30fb4ac425e031d3626bbe (2/2)
    Ref 'refs/heads/master' was rewritten
    
     ~/playing/me/Delila (master)
    $ mkdir someFolder
    
     ~/playing/me/Delila (master)
    $ mv * someFolder
    mv: cannot move `someFolder' to `someFolder/someFolder'
    

    现在,我想要整个文件夹,所以我这样做:

     ~/playing/me/Delila (master)
    $ git rm theNewFeature
    rm 'theNewFeature'
    
     ~/playing/me/Delila (master)
    $ git rm anotherFileFromJulio
    rm 'anotherFileFromJulio'
    

    这是错误的做法吗?

    回到答案:

     ~/playing/me/Delila (master)
    $ git add .
    
     ~/playing/me/Delila (master)
    $ git commit -m "filtered Delila"
    [master b7fde89] filtered Delila
     2 files changed, 0 insertions(+), 0 deletions(-)
     rename anotherFileFromJulio => someFolder/anotherFileFromJulio (100%)
     rename theNewFeature => someFolder/theNewFeature (100%)
    

    现在我想“分叉”胡里奥,所以我这样做:

     ~/playing/me
    $ git clone ../Julio
    Cloning into 'Julio'...
    done.
    
     ~/playing/me
    $ cd Julio
    
     ~/playing/me/Julio (master)
    $ git remote rm origin
    

    好的,回到答案的步骤......

     ~/playing/me/Julio (master)
    $ git remote add repo-A-branch ../Delila
    
     ~/playing/me/Julio (master)
    $ git pull repo-A-branch master
    remote: Counting objects: 8, done.
    remote: Compressing objects: 100% (4/4), done.
    remote: Total 8 (delta 0), reused 0 (delta 0)
    Unpacking objects: 100% (8/8), done.
    From ../Delila
     * branch            master     -> FETCH_HEAD
    Merge made by the 'recursive' strategy.
     someFolder/theNewFeature | 1 +
     1 file changed, 1 insertion(+)
     create mode 100644 someFolder/theNewFeature
    
     ~/playing/me/Julio (master)
    $ git remote rm repo-A-branch
    

    那应该是它,所以让我们看一下我们移植的特殊功能的日志......

     ~/playing/me/Julio/someFolder (master)
    $ git log theNewFeature
    commit b7fde8940d761f7babe13d8b6cdfa12fe1685390
    Author: xxxxx
    Date:   Tue Sep 24 09:01:43 2013 +0200
    
        filtered Delila
    

    叹息那么我做错了什么?历史何去何从?

2 个答案:

答案 0 :(得分:2)

这实际上完全在git的功能范围内。一般来说,这是你应该能够期待git做的事情。提交不仅仅是代码库快照,它们(大致 - 合并创建分支)链接的代码库快照列表具有完整的历史记录。 Git允许您重写历史记录,因此它类似于您认为应该发生的事情。特别是,您不想销毁文件的历史记录,但也想要导入它。

您的问题是您不想拉入所有分叉的回购。因此,只需使用filter-branch导入您需要的内容即可。这样可以一次完成您所需要的:保留这些文件,保留其历史记录,但会破坏与这些文件无关的所有历史记录。

我希望自己能够做到这一点,你需要1)变得轻松filter-branch或2)将你的相关文件隔离在一个目录中。

This is described in this post here

使用filter-branch销毁您关注的目录中的原始仓库中的所有内容而不是。是的,您希望首先克隆并离开原始仓库的副本。

git clone <git repository A url>
cd <git repository A directory>
git remote rm origin
git filter-branch --subdirectory-filter <directory 1> -- --all
mkdir <directory 1>
mv * <directory 1>
git add .
git commit

而且,简单地说,从仅包含您关注的事物的新回购中拉取并合并。请记住,git repos没有一些ID,说明它们是什么回购。这是一个vanilla操作 - 恰好是一个只包含新文件的repo B副本。

git clone <git repository B url>
cd <git repository B directory>
git remote add repo-A-branch <git repository A directory>
git pull repo-A-branch master
git remote rm repo-A-branch

答案 1 :(得分:0)

好的,所以我找到了一种方法,可以做到我所期望的。正如您从我的更新中看到的那样,我认为过滤后的历史记录没有得到维护。实际上,我只是需要传递 - 关注参数......

除了有争议之外,请不要贬低我,只是因为有人试图用git来完成工作并感到有些痛苦: 就个人而言,我觉得这是在我不知道的存储库中给出的不是最佳的,我总是需要添加额外的follow参数来获取文件的完整历史记录(所以我现在将创建一个别名,而不是仅使用{{ 1}})。此外,github默认不会在他们漂亮的网页用户界面git log进行--follow,我怀疑这是很多人寻找历史的地方。

我意识到github等可以改进,但是从最终用户 - 我只是希望git mv可以保留历史记录。在我git mv之后,我希望git log看到之前的所有内容。

但我只是一个用户,所以我知道什么。

无论如何,这就是我所做的,基于Git: Copy a file or directory from another repository preserving the history

git clone Delila
mkdir ~/mypatches
cd Delila/folderWithFile
export reposrc=fileToKeepHistory
git format-patch -o ~/mypatches $(git log $reposrc|grep ^commit|tail -1|awk '{print $2}')^..HEAD $reposrc

... Fork Julio ...

cd ~/
git clone JulioForked
cd Julio/folderWithFile    
git am ~/mypatches/*.patch

...Make my changes...

git commit -m "my changes"
git push origin master

它有效!现在我在github查看我想要保留其历史的讨厌文件,并且它的所有奇迹都在其中!

呼。