Git:保留当前代码状态和​​最后四个提交

时间:2018-07-24 11:22:31

标签: git gitlab

请注意:此问题与Squash my last X commits together using Git不同,因为我们不希望将 last X个提交一起压缩到一个提交中-而是希望将 initial 提交合并到单个提交中,并以自动方式保留最后四个提交 /代码状态(无需手动选择)提交)。

我们正在使用git通过内部托管的GitLab服务器将更改备份/记录对文件数据存储的更改,该服务器的存储库包含一些非常大的文件。

我们想合并先前不需要的冗余提交,以减少存储库的大小,但是保留当前代码状态和​​最后四个提交备份,以防我们需要将数据存储还原到先前的提交。

自动脚本中建议使用哪些命令,该命令会更改以下git历史记录:

0    aabbcc Initial commit
1    aabbdd First backup
2    aabbee Second backup
3    aabbff Third backup
4    aabbgg Fourth backup
5    aabbhh Fifth backup
6    aabbii Sixth backup
7    aabbjj Seventh backup (current code state)

要成为以下而不丢失当前代码状态

4    aabbgg Initial commit -> Fourth backup (consolidated)
5    aabbhh Fifth backup
6    aabbii Sixth backup
7    aabbjj Seventh backup (current code state)

2 个答案:

答案 0 :(得分:2)

也许是这样。

首先,压缩较早的提交:

git checkout aabbgg         # checkout the commit that you want to squash the older commits into
git reset --soft aabbcc^    # squash the commits...
git commit -m "Initial commit -> Fourth backup (consolidated)"
git tag new_base            # tag it, we will use the tag later

下一步,将较新的提交重新建立到新的基础上:

git checkout -b consolidated current_code_state
git rebase --onto new_base aabbgg

注意:为避免rebase在冲突中停止,您可能需要指定合并策略,例如:

-s recursive -X ours -X no-renames

结果:

x - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 (current_code_state)
 \
  4' (new_base) - 5' - 6' - 7' (consolidated)

current_code_stateconsolidated之间应该没有区别。

最后,如果一切顺利,请删除原始分支和先前创建的标签。

git branch -D current_code_state
git tag -d new_base

答案 1 :(得分:1)

基于sergej的回答(Git: Preserving current code state and last four commits),我编写了一个自动脚本,该脚本似乎可以按需工作:

#!/bin/bash

function gitConsolidation() {

    # Default settings
    numCommitsToKeep=4
    branchName="master"
    path="/home/steve/test/testgit"

    # Set working directory
    cd $path

    # Get git repo name
    gitRepoName=$(basename `git rev-parse --show-toplevel`)

    # Print default message
    echo -e "** Prepairing to consolidate current Git Repo: $gitRepoName **"
    echo -e "Branch: $branchName"
    echo -e "Path: $path"
    echo -e "Total past commits to keep: $numCommitsToKeep\n"

    # Get required branch
    git checkout $branchName

    # Get size before consolidation
    echo -e "Repo size before consolidation: $(du -hs)" 

    # Print current log list
    echo -e "\n* Git commits prior to consolidation *"  
    git log --pretty="%H - %s"

    # Get initial commit hash
    initialCommitHash=$(git rev-list --max-parents=0 HEAD)
    echo -e "\n* Found initial commit hash: $initialCommitHash *"

    # Get hash for commit to be consolidated with intiial commit
    consCommitHash=$(git log --format=%H | head -$numCommitsToKeep | tail     -1)
    echo -e "* Found hash for commit to consolidate with initial commit: $consCommitHash *"

    # Get hash for latest commit
    latestCommitHash=$(git log --format=%H | head -1)
    echo -e "* Found hash for latest commit $latestCommitHash *\n"

    # Begin consolidation
    echo -e "* BEGIN: Git repo consolidation *"

    # Checkout commit to consolidate with initial commit
    git checkout $consCommitHash

    # Soft reset initial commit
    git reset --soft $initialCommitHash

    # Commit changes
    git commit -m "Consolidated commit $initialCommitHash -> $consCommitHash"

    # Set tag
    git tag new_base

    # Checkout
    git checkout -b consolidated $latestCommitHash

    # Rebase
    git rebase --onto new_base $consCommitHash

    # Get size after consolidation
    echo -e "Repo size after consolidation: $(du -hs)"

    # Print current log list
    echo -e "\n * Git commits after consolidation *"    
    git log --pretty="%H - %s"

    echo -e "\n* END: Git repo consolidation *"
}

# Call function
gitConsolidation

已成功在本地测试存储库上运行。即将对我们的大型存储库副本进行测试,以查看是否可以正常运行!