linux - 如何将发布文件转换为 git repo

标签 linux git shell

我有一个发布文件列表:

MyProject-0.9.zip
MyProject-1.0.zip
MyProject-1.3.tar.gz
MyProject-2.0.tar.gz

每个都包含一个与存档同名的文件夹(不带文件扩展名),其中包含源代码和 makefile 等,如下所示:

MyProject-0.9.zip
- MyProject-0.9/
- MyProject-0.9/src/
- MyProject-0.9/src/mySrc.c
- MyProject-0.9/Makefile
- MyProject-0.9/LICENSE

我想将它们转换成一个 git 存储库,每个存档一个提交。

最佳答案

这是一个使用 bash 的解决方案。

  • 使用发布文件修改日期作为提交的作者日期
  • 为每个提交添加一个发布/版本 git 标签
  • 支持不同的存档格式
  • 允许在提交前轻松清理存档内容

脚本:

#!/bin/bash
# author:      hoijui <hoijui.quaero@gmail.com>
# copyright:   Copyright (c) 2017 hoijui
# license      GNU General Public License version 3
# description: Creates a git repository from a list of release archives.
# example:     Before using the script, we should have this directory structure:
#              * conv_dir/createGitRepoFromReleaseArchives # this script
#              * conv_dir/MyProject-1.0.0.zip              # 1. release archive
#              * conv_dir/MyProject-1.0.1.zip              # 2. release archive
#              * conv_dir/MyProject-2.0.0.tar.gz           # 3. release archive
#              * conv_dir/MyProject-2.1.0.tar.gz           # 4. release archive
#              while each of the archives should contain a dir with the same name
#              as the archive (without the file extension), for example:
#              MyProject-1.0.0.zip:
#              * MyProject-1.0.0/LICENSE
#              * MyProject-1.0.0/Makefile
#              * MyProject-1.0.0/src/mySrc.c
#              We then simply run the script:
#              > createGitRepoFromReleaseArchives
#              after which we should end up with a dir "repo" containing the git repository.

ORIG_DIR=`pwd`

ARCHIVE_SUFFIX_REGEX="\.\(tar\|tar\.gz\|tgz\|zip\|tar\.bz2\|tbz2\)"
ZIP_SUFFIX_REGEX=".*\.zip$"

ARCHIVES="${1:-}"
REPO_DIR="${2:-repo}"
EXTRACT_DIR="/tmp/$(basename ${0})_extract_${RANDOM}"

if [ -z "${ARCHIVES}" ]
then
    # if ARCHIVES is not set
    # gather common archive files from the current directory
    ARCHIVES="$(find . -regex ".*${ARCHIVE_SUFFIX_REGEX}" | sort --version-sort)"
fi

# Possibly remove files fond in the release archives
# that we do not want in the git repo.
# This gets called for each archive,
# with PWD set to the extracted archives main dir.
function cleanRepoDir() {
    echo "cleaning repo dir ..."
    #rm version.txt
    # ... more commands
}

PROJECT_NAME="$(basename "${ARCHIVES%% *}" | sed -e 's/-.*//')"

mkdir "${EXTRACT_DIR}"

echo ""
echo "project name: '${PROJECT_NAME}'"
echo "extract dir: '${EXTRACT_DIR}'"
echo "repo dir:    '${REPO_DIR}'"
echo -e "version archives:\n${ARCHIVES}"
echo ""

read -p "Do you want to continue creating a git repo with the above info! [Y/n]" -n 1 -r
echo
if [[ ${REPLY} =~ ^[Nn]$ ]]
then
    # handle exits from shell(-script) or function
    # but do not exit interactive shell
    [[ "$0" = "${BASH_SOURCE}" ]] && exit 1 || return 1
fi

# setup the resulting repo
if [ -e "${REPO_DIR}" ]
then
    >&2 echo "Error: Repo already exists!"
    exit 1
fi
mkdir "${REPO_DIR}"
cd "${REPO_DIR}"
git init
#git config --local user.name "My Name"
#git config --local user.email mail@mail.com
cd ..

for archive in ${ARCHIVES}
do
    echo

    # get the absolute path to the current archive
    archive="$(realpath "${archive}")"

    # remove extracted contents of the last archive
    cd "${EXTRACT_DIR}"
    rm -Rf ./*

    # extract contents of the current archive
    if [[ "${archive}" =~ ${ZIP_SUFFIX_REGEX} ]]
    then
        echo "Extracting (unzip): '${archive}'"
        unzip -q "${archive}"
    else
        echo "Extracting (tar): '${archive}'"
        tar -xf "${archive}"
    fi
    # and create the absolute path to the contained directory
    # (which should be "${PROJECT_NAME}-${version}")
    version_dir="${EXTRACT_DIR}/$(basename "${archive}" | sed -e "s/${ARCHIVE_SUFFIX_REGEX}$//")"
    #version_dir="${EXTRACT_DIR}/$(basename "${archive}" | sed -r -e 's/\.zip$//')"
    #version_dir="${EXTRACT_DIR}/$(basename "${archive}" | sed -r -e 's/\.(zip|zap)$//')"
    # remove directory and project name from extracted archive path
    # to get the bare version string
    version="$(basename "${version_dir}" | sed -e 's/^[^-]*-//')"

    # remove all content from the previous commit from git
    # for the next comit
    cd "${ORIG_DIR}"
    cd "${REPO_DIR}"
    git rm -rfq . 2> /dev/null
    # also remove empty directories
    rm -Rf ./*

    # move current versions content to the git repo
    mv "${version_dir}"/* ./
    cleanRepoDir
    # and add all of it for the next commit
    git add .

    # extract last modification date of the release archive file,
    # which is to be used as commit date
    date="$(date -r "${archive}" +'%Y-%m-%dT%H:%M:%S')"

    # commit the current archives content
    git commit -m "${PROJECT_NAME} release version ${version}" --date "${date}" --quiet
    # and tag it as a release
    git tag -m "${PROJECT_NAME} release version ${version}" "v${version}"

    cd ..
done

# Compress the git history
cd "${REPO_DIR}"
git gc --aggressive
echo "Git history size: $(du -s --si .git)"

cd "${ORIG_DIR}"

关于linux - 如何将发布文件转换为 git repo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46268631/

相关文章:

java - 从 Java 执行 shell 命令

python - 如何让 Tornado 在 ssh 连接断开时不停止?

c++ - Botan::DSA_PrivateKey 到 DSA_PublicKey 怎么样?

linux - 在 .gitconfig 中 stash GitHub token

node.js - 制作用于单元测试的 git 存储库

git-svn 克隆 : unable to connect to a repository

git - 组合多个 Github 存储库并同时跟踪它们的最佳方法是什么?

linux - 2 个 AWS EC2 实例之间的 rsync : cannot locate . pem 文件

windows - 如何使用纯 c 或 linux-shell 或 dos-commands 创建超大文件?

bash - ": > file"对比 "> file"