从Catchall(脏)创建适当的Git存储库

问题描述 投票:1回答:1

让我们将my-dirty-repository称为现有的Git存储库,其中包含许多与之无关的脚本。它是一个需要正确清理的catchall存储库。

作为一个Minimal, Complete, and Verifiable example,让我们说这个存储库只包含:

script1.sh
script2.sh

通过各种提交,在几个分支中独立更新它们。

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

让我们称之为my-clean-repository1my-clean-repository2,第一个只有script1的历史,第二个只有script2的历史。

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

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

git git-clone shallow-clone
1个回答
0
投票

编辑:我在GitHub上创建了专用工具cloneToCleanGitRepositories来满足这个需求。

它是以下旧版的完整版本。


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

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

最终,对于他们中的大多数人来说还不够,我再次尝试使用Git filtering system的另一个解决方案。

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

#!/bin/bash
##
## Author: Bertrand Benoit <mailto:[email protected]>
## 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存储库的根目录中的EACH文件创建一个新的干净git存储库。在每一个中,历史都是干净的,只与保留的脚本有关。

此外,它会断开/删除远程以确保避免将更改推回到源存储库。

通过这种方式,很容易从一个大脏的Git Repository“迁移”到各种干净的: - )

© www.soinside.com 2019 - 2024. All rights reserved.