从git仓库提取子目录到另一个仓库并保留dir结构? [英] Extracting subdirectory from a git repo into another repo and keeping dir structure?

查看:295
本文介绍了从git仓库提取子目录到另一个仓库并保留dir结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

你可以使用git的filter-branch和subtree filter。



以下是步骤:克隆一个工作副本。
$ b


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

      git clone --no-hardlinks< original repository> <工作副本> 


  2. 使用子树fileter。

      cd<工作副本> 

    git filter-branch --subdirectory-filter<要拆分的子目录路径> --prune-empty --tag-name-filter cat - --all

    #重置当前工作目录
    git reset --hard

  3. 我们完成了我们的任务,最好做一些清理工作,因为很多旧对象变得无法访问。


    1. 删除旧的远程

        git remote rm来源


    2. 移除旧的reflog

      <$为了释放空间,清理不需要的reflog
      refbak = $(git for-each-ref --format =%(refname)refs / original /)
      if [-n$ refbak];然后
      echo -n $ refbak | xargs -n 1 git update-ref -d
      fi
      git reflog expire --expire = now --all


    3. 重新编译和压缩回购

       #修剪松散对象
      git

    4. >

      这将使回购结构从

       回购/ 
      | - sub1 /
      | - sub11
      | - sub12
      | - sub2

       回购/ 
      | - sub11
      | - sub12

      但是,您似乎希望它变成

       回购/ 
      | - sub1 /
      | - sub11
      | - sub12

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

       #replace< subdir path>与实际的子目录路径,对于这种情况下,它应该是sub1
      git filter-branch --index-filter'git ls-files -s | seds-\t-&< subdir path> / - | GIT_INDEX_FILE = $ GIT_INDEX_FILE.new git update-index --index-info&& mv $ GIT_INDEX_FILE.new $ GIT_INDEX_FILE'HEAD


      There are several subtrees in my repo (e.g. ./sub1/, ./sub2/, ..) which I would like to extract into separate repos, keeping commit history and the same dir structure, i.e. a new repo for sub1 should have ./sub1/ subtree from the main repo. How can I do this?

      解决方案

      You can use git's filter-branch with subtree filter.

      Here are the steps:

      1. Clone a working copy. This operation will alter local repo, so we must have a working copy first. You can either do a git clone as below or just copy it.

        git clone --no-hardlinks <original repository> <working copy>
        

      2. Use subtree 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. We have accomplished our task, it is better to do some cleaning work, because lots of old objects became unreachable.

        1. Delete old remote

          git remote rm origin
          

        2. Remove old 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. Repack and compress the repo

          # prune loose objects
          git gc --aggressive --prune=now
          

      This will make the repos structure change from

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

      to

      repo/
          |-- sub11
          |-- sub12
      

      But, it seems you want it to became

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

      Then, there is one more step need to be done, rewrite the git commit history with index-filter.

      # 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
      

      这篇关于从git仓库提取子目录到另一个仓库并保留dir结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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