从git repo中提取子目录到另一个repo并保持dir结构?

时间:2012-10-09 13:58:40

标签: git git-filter-branch

我的仓库中有几个子树(例如./sub1/./sub2/,...),我想将其提取到单独的回购中,保留提交历史和相同的目录结构,即新的回购for sub1应该有来自主回购的./sub1/子树。我怎么能这样做?

1 个答案:

答案 0 :(得分:5)

你可以使用git的filter-branch和子树过滤器。

以下是步骤:

  1. 克隆工作副本。此操作将更改本地仓库,因此我们必须先拥有工作副本。您可以执行如下的git克隆,也可以只复制它。

    git clone --no-hardlinks <original repository> <working copy>
    
  2. 使用子树文件管理器。

    cd <working copy>
    
    git filter-branch --subdirectory-filter <subdir path to be splited> --prune-empty --tag-name-filter cat -- --all
    
    # reset current working directory
    git reset --hard
    
  3. 我们完成了我们的任务,最好做一些清洁工作,因为很多旧物体无法到达。

    1. 删除旧遥控器

      git remote rm origin
      
    2. 删除旧的reflog

      # clean unneeded reflog in order to free space
      refbak=$(git for-each-ref --format="%(refname)" refs/original/)
      if [ -n "$refbak" ];then
          echo -n $refbak | xargs -n 1 git update-ref -d
      fi
      git reflog expire --expire=now --all
      
    3. 重新包装并压缩回购

      # prune loose objects
      git gc --aggressive --prune=now
      
  4. 这将使repos结构从

    更改
    repo/
        |-- sub1/
            |-- sub11
            |-- sub12
        |-- sub2
    

    repo/
        |-- sub11
        |-- sub12
    

    但是,似乎你想要它成为

    repo/
        |-- sub1/
            |-- sub11
            |-- sub12
    

    然后,还有一个步骤需要完成,用index-filter重写git commit history。

    # replace <subdir path> with the actual subdir path, for this case, it should be "sub1"
    git filter-branch --index-filter 'git ls-files -s | sed "s-\t-&<subdir path>/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD