代码之家  ›  专栏  ›  技术社区  ›  Bsquare ℬℬ

从catchall(脏的)库创建适当的git库

  •  1
  • Bsquare ℬℬ  · 技术社区  · 6 年前

    我们打电话来 my-dirty-repository 一个现有的Git存储库,包含许多不相关的脚本。它是一个需要 正确清洁 .

    作为一个 Minimal, Complete, and Verifiable example ,假设此存储库仅包含:

    script1.sh
    script2.sh
    

    在多个分支中使用不同的提交,这些提交独立地更新了它们。

    其目标是创建2个100%独立的Git存储库,只保留文件(引用)的历史记录。

    我们打电话给他们 my-clean-repository1 my-clean-repository2 第一个只有关于脚本1的历史,第二个只有关于脚本2的历史。

    我尝试了3种方法来满足我的需求,但没有成功:

    我很确定有一种方法可以正确地执行它。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Bsquare ℬℬ    6 年前

    编辑: 我创建了专用工具 cloneToCleanGitRepositories 在Github上回答这个需求。

    它是旧的后续版本的完整版本。


    @Mkasberg感谢您对交互式钢筋网的建议,这在一些简单的历史情况下非常有趣。

    我尝试过,它解决了我的一些脚本的问题,我想要一个干净、专用、独立的Git存储库。

    最后,对他们大多数人来说这还不够,我再次尝试了另一个解决方案 Git filtering system .

    最后,我写了这个小剧本:

    #!/bin/bash
    ##
    ## Author: Bertrand Benoit <mailto:contact@bertrand-benoit.net>
    ## Description: Create clean git repositories for each file in root of specified source Git repository, updating history consequently. 
    ## Version: 1.0
    
    [ $# -lt 2 ] && echo -e "Usage: $0 <source repository> <dest root directory>" >&2 && exit 1
    
    SOURCE_REPO="$1"
    [ ! -d "$SOURCE_REPO" ] && echo -e "Specified source Git repository '$SOURCE_REPO' does not exist." >&2 && exit 1
    DEST_ROOT_DIR="$2"
    [ ! -d "$DEST_ROOT_DIR" ] && echo -e "Specified destination root directory '$DEST_ROOT_DIR' does not exist." >&2 && exit 1
    
    sourceRepoName=$( basename "$SOURCE_REPO" )
    
    # For each file in root of the source git repository.
    for refToManage in $( find "$SOURCE_REPO" -maxdepth 1 -type f ); do
      echo -ne "Managing $refToManage ... "
    
      refFileName=$( basename "$refToManage" )
      newDestRepo="$DEST_ROOT_DIR/$refFileName"
    
      # Creates the repository if not existing.
      logFile="$newDestRepo/logFile.txt"
      echo -ne "creating new repository: $newDestRepo, Log file: $logFile ... "
      if [ ! -d "$newDestRepo" ]; then
        mkdir -p "$newDestRepo"
        cd "$newDestRepo"
        ! git clone -q "$SOURCE_REPO" && echo -e "Error while cloning source repository to $newDestRepo." >&2 && exit 2
      fi
      cd "$newDestRepo/$sourceRepoName"
    
      # Removes all other resources.
      FILTER='git ls-tree -r --name-only --full-tree "$GIT_COMMIT" | grep -v "'$refFileName'" | tr "\n" "\0" | xargs -0 git rm -f --cached -r --ignore-unmatch'
      ! git filter-branch -f --prune-empty --index-filter "$FILTER" -- --all >"$logFile" 2>&1 && echo -e "Error while cleaning new git repository." >&2 && exit 3
    
      # Cleans remote information to ensure there is no push to the source repository.
      ! git remote remove origin >>"$logFile" 2>&1 && echo -e "Error while removing remote." >&2 && exit 2
    
      echo "done"
    done
    

    用途:

    mkdir /tmp/cleanRepoDest
    createCleanGitRepo.sh ~/_gitRepo/Scripts /tmp/cleanRepoDest
    

    在目标目录中,它将为指定源Git存储库根目录中的每个文件创建一个新的干净Git存储库。 在每个脚本中,历史都是干净的,并且只与保留的脚本相关。

    此外,它还断开/删除远程存储,以确保避免将更改推回到源存储库时出现问题。

    这样,很容易从一个大的脏catchall-git存储库“迁移”到各种干净的存储库:—)

    推荐文章