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

Git:保留当前代码状态和最后四次提交,git,gitlab,Git,Gitlab,请注意:此问题与as不同,我们不希望将最后的X次提交合并为一次提交,而是希望将初始提交合并为一次提交,并以自动方式保留最后的四次提交/代码状态(无需手动拾取提交) 我们使用git来备份/记录对文件数据存储的更改,使用的是内部托管的GitLab服务器,该服务器的存储库包含一些非常大的文件 我们希望整合以前的冗余提交,这些提交不再需要减少回购的大小,但保留当前代码状态和最后四次提交作为备份,以防我们需要将数据存储恢复到以前的提交 建议在自动化脚本中使用哪些命令来更改以下git历史记录: 0 a

请注意:此问题与as不同,我们不希望将最后的X次提交合并为一次提交,而是希望将初始提交合并为一次提交,并以自动方式保留最后的四次提交/代码状态(无需手动拾取提交)

我们使用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)

也许是这样的

首先,挤压较旧的提交:

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
注意:为了避免在冲突时停止,您可能需要指定合并策略,例如:

-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)
当前代码状态和合并代码状态之间应该没有区别

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

git branch -D current_code_state
git tag -d new_base
根据sergej的答案()我编写了一个自动化脚本,它似乎可以按预期工作:

#!/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

已在本地测试repo上成功运行。即将在我们的大规模repo副本上进行测试,以查看是否按预期工作!

为什么您认为可以在不更改代码状态的情况下删除前4个提交?这很可能是不可能的。@TimBiegeleisen我们需要将以前的所有提交合并为一个提交,但保留最后4个提交。。git不可能做到这一点吗?@TimBiegeleisen问题与标记为重复的问题不同,因为我们希望将初始提交合并为单个提交,并将最后四次提交保持为自动提交,而建议的重复问题的答案解释了如何压缩最后一次提交,而不是初始提交,并且需要手动完成用户输入。
git签出aabbgg&&git重置-软aabbcc^&&git提交-m“初始提交->第四次备份(合并)”&&git标记new_base&&git checkout-b consolidated master&&git rebase-到new_base aabbgg上
@Steve我前面提到的重复链接或Serge的软重置方法基本上是压缩提交的两种方法。但是,这两种方法通常都需要手动干预。^字符是必需的吗?运行以下命令时出现问题命令:
git reset--soft aabbcc^
但是可以通过省略^成功运行。已经根据您的答案几乎完成了自动脚本的编写-将尽快发布。非常感谢
^
意味着“它的父级”。但是,如果
aabbcc
是第一次提交,它没有父级。尽管您可以让git这样做(您的脚本看起来是可行的),您应该注意,您所做的相当于使用源代码管理系统作为备份系统。SCM不是作为备份系统设计的(反之亦然),这就是为什么这样比较痛苦的原因。一个设计良好的备份系统将使保留N个备份(对于任何合适的N个备份)变得非常干净和简单。在我长期搁置的文章的第一章中,我有一些关于备份与SCM的更多说明。@torek同意-不幸的是,这是客户的一项要求,因为他们的开发工作流程-其中包括许多依赖于应用程序代码的大数据文件,并且必须与应用程序代码的版本控制同步。有因此,使用独立的备份系统将环境备份到Veeam快照/磁带机;)