2012-10-09 49 views

回答

5

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

步骤如下:

  1. 克隆的工作副本。这个操作会改变本地回购,所以我们必须先有一个工作副本。你可以像下面那样做一个git clone,或者直接拷贝它。

    git clone --no-hardlinks <original repository> <working copy> 
    
  2. 使用子树fileter。

    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. 删除旧引用日志

      # 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 
      

这将使从

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 
相关问题