web-dev-qa-db-ja.com

古いコミットを潰す最善の方法

最近、開発者が去り、数か月前のリポジトリに「更新済み」のような大量のコミットを残しました。理想的には、それらを1つのコミットに押しつぶしたいのですが、これは最近のコミットに対してのみ行っています。

次のコミットのようにするにはどうすればよいですか(2か月前からのコミットはこれらが数百あることを意味すると仮定します)?

.... 2か月前から

aabbcc updated
aabbdd updated
aabbee updated
aabbff updated

派手なものは必要ありません。単純な解決策です。これらのコミットは(今日の私を除いて)公に共有されていないので、他の人のコミット履歴を混乱させる問題はありません。

15
timpone

Gitスカッシュを実行するには、次の手順に従います。

// X is the number of commits you wish to squash
git rebase -i HEAD~X

コミットをスカッシュしたら-スカッシュにsを選択します=すべてのコミットを1つのコミットに結合します。

enter image description here


必要な場合に備えて、-rootフラグもあります

試してください:git rebase -i --root

-root

Rebase all commits reachable from <branch>, instead of limiting them with
an <upstream>.

This allows you to rebase the root commit(s) on a branch.  
When used with --onto, it will skip changes already contained in `<newbase>`   
(instead of `<upstream>`) whereas without --onto it will operate on every 
change. When used together with both --onto and --preserve-merges, all root 
commits will be rewritten to have `<newbase>` as parent instead.`
5
CodeWizard

コミットの年齢は関係ありません。コミットを押しつぶすことは、コミットを押しつぶすことです。

rebasing が好ましくない場合、または押しつぶしたい文字通り何千ものコミットがあり、それを気にすることができない場合は、最初のコミットハッシュにソフトリセットして再-すべてをコミットする:

$ git reset aabbff 
$ git commit -m "This commit now contains everything from the tip until aabbff"

その場合、リベース->スカッシュと同じように、コミットは1つだけになります。

3
Robbie Averill

これはすでに古代の質問であることを私は知っていますが、私はこれに対する解決策が必要でした。

簡単に言うと、私のローカルgitリポジトリ(NFS上、アップストリームなし)は特定のファイルのバックアップとして機能し、最大50のコミットが必要でした。ファイルが多く、バックアップが頻繁に行われるため、履歴を自動的に圧縮するものが必要だったため、ファイルのバックアップと履歴の圧縮の両方を行うスクリプトを作成しました。

#!/bin/bash

# Max number of commits preserved
MAX_COMMITS=50

# First commit (HEAD~<number>) to be squashed
FIRST_SQUASH=$(echo "${MAX_COMMITS}-1"|bc)

# Number of commits until squash
SQUASH_LIMIT=60

# Date and time for commit message
DATE=$(date +'%F %R')

# Number of current commits
CURRENT_COMMITS=$(git log --oneline|wc -l)

if [ "${CURRENT_COMMITS}" -gt "${SQUASH_LIMIT}" ]; then

    # Checkout a new branch 'temp' with the first commit to be squashed
    git checkout -b temp HEAD~${FIRST_SQUASH}

    # Reset (soft) to the very first commit in history
    git reset $(git rev-list --max-parents=0 --abbrev-commit HEAD)

    # Add and commit (--amend) all the files
    git add -A
    git commit --amend -m "Automatic squash on ${DATE}"

    # Cherry pick all the non-squashed commits from 'master'
    git cherry-pick master~${FIRST_SQUASH}..master

    # Delete the 'master' branch and rename the 'temp' to 'master'
    git branch -D master
    git branch -m master

fi

したがって、スクリプトが基本的に行うことは(バックアップ部分を削除した):

  1. 60を超えるコミットがある場合、50から60+までのすべてのコミットを1つのコミットに押しつぶします。
  2. コミットに基づいて新しいブランチを作成してチェックアウトします
  3. Cherryは、マスター(#1から#49)からブランチへの残りのコミットを選択します
  4. マスターブランチを削除します
  5. 新しいブランチの名前をmasterに変更します。
0
jxcr0w