[解決済み】Gitでルートコミットの前にコミットを挿入する?
質問
以前にも質問したことがあるのですが 最初の2つのコミットをつぶす を git リポジトリで使用することができます。
この解決策はなかなか面白いもので、git の他の機能ほど頭を悩ませるものではありませんが、それでも、プロジェクトの開発中に何度もこの手順を繰り返す必要がある場合は、ちょっとした痛手となります。
だから、一回だけ痛い目にあって、あとはずっと標準の対話型リベースを使えるようにしたいんです。
そこで私がやりたいのは、最初のコミットという目的だけのために存在する、空の初期コミットです。コードも何もありません。ただ、リベースのベースとなるようにスペースを取っておくだけです。
そこで質問ですが、既存のリポジトリがある場合、最初のコミットの前に新しい空のコミットを挿入し、他の全員を前に移動させるにはどうすればいいのでしょうか?
どのように解決するのですか?
これを実現するには、2つのステップがあります。
- 空のコミットを新規に作成する
- この空のコミットから始まるように履歴を書き換える
新しい空のコミットを一時的なブランチに置くことにします。
newroot
便宜上
1. 新しい空のコミットを作成する
これにはいくつかの方法があります。
配管のみの使用
最もクリーンな方法は、Git の配管を使ってコミットを直接作成することです。これは、作業コピーやインデックス、どのブランチがチェックアウトされているかなどを触ることを避けるためです。
-
空のディレクトリのツリーオブジェクトを作成します。
tree=`git hash-object -wt tree --stdin < /dev/null`
-
コミットを巻き付ける。
commit=`git commit-tree -m 'root commit' $tree`
-
参照を作成します。
git branch newroot $commit
もちろん、シェルのことをよく理解していれば、この手順全体をワンライナーにアレンジすることもできます。
配管なし
通常のポーセリンコマンドの場合、空のコミットを作成するためには、チェックアウトせずに
newroot
ブランチを作成し、インデックスと作業コピーを繰り返し更新するという、意味不明なことをしています。しかし、この方が分かりやすいと思う人もいるでしょう。
git checkout --orphan newroot
git rm -rf .
git clean -fd
git commit --allow-empty -m 'root commit'
Git の非常に古いバージョンで
--orphan
に切り替えることができます。
checkout
の場合、最初の行をこれに置き換えてください。
git symbolic-ref HEAD refs/heads/newroot
2. この空のコミットから始まるように履歴を書き換える
リベースするか、履歴をきれいに書き直すか、2つの選択肢があります。
リベース
git rebase --onto newroot --root master
これはシンプルであるという長所があります。しかし、この方法ではブランチの最後のコミットごとにコミッター名と日付を更新してしまいます。
また、いくつかのエッジケース・ヒストリーでは、何も含まないコミットにリベースしているにもかかわらず、マージの競合が原因で失敗することさえあります。
履歴の書き換え
よりクリーンな方法は、ブランチを書き換えることです。とは異なり
git rebase
ブランチがどのコミットから始まっているかを調べる必要があります。
git replace <currentroot> --graft newroot
git filter-branch master
書き換えが行われるのは明らかに第2段階であり、説明が必要なのは第1段階である。何
git replace
は、置き換えたいオブジェクトへの参照を見つけたらいつでも、代わりにそのオブジェクトの置き換えを見るようにGitに伝えます。
を使用すると
--graft
スイッチでは、通常とは少し異なることを指示しています。置換オブジェクトはまだないけれども
<currentroot>
コミットオブジェクトをそれ自身の完全なコピーで
ただし
置換の親コミットには、リストアップしたもの (すなわち
newroot
コミット)。次に
git replace
が先に進んでこのコミットを作成し、そのコミットを元のコミットの代わりとすることを宣言します。
今、もしあなたが
git log
ブランチの始まりは
newroot
.
ただし、以下の点に注意してください。
git replace
は実際には履歴を変更しません。
- また、リポジトリから外に伝搬することもありません。単に、あるオブジェクトから別のオブジェクトへのローカルリダイレクトをリポジトリに追加するだけです。これが意味するのは、この置換の効果を他の誰も見ていないということです。
そのため
filter-branch
のステップが必要です。とは
git replace
を実行すると、ルートコミットの親コミットを調整した完全なコピーが作成されます。
git filter-branch
を実行し、それに続くすべてのコミットに対してこのプロセスを繰り返します。ここで実際に歴史が書き換えられ、それを共有できるようになります。
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] Git リポジトリを以前のコミットに戻すにはどうすればよいですか?
-
[解決済み] Git で、ステージされていない変更を破棄するにはどうしたらいいですか?
-
[解決済み] git rebase の取り消し
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み] Git で最新のコミットを新しいブランチに移動する
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】未マージファイルがあるため、Gitマージができない
-
[解決済み] GitHubに空のブランチを作成する
-
[解決済み] ブラウンアウトの一環として、パスワード認証が一時的に無効になっています。代わりに個人用アクセストークンを使用してください[重複]。
-
[解決済み] Git エラー : 'upstream' は git リポジトリでないようです。
-
[解決済み] 警告: リモート HEAD は存在しない参照元を参照しているため、チェックアウトできません。
-
[解決済み] Gitで最初の2つのコミットをつぶす?重複
-
[解決済み] Gitのルートコミットを編集しますか?
-
[解決済み】Git リポジトリの最初の2つのコミットを結合する?
-
[解決済み] 新しい(そして空の!)「ルート」ブランチを作成する方法は?
-
[解決済み] git の半秘密の空のツリーオブジェクトは信頼できますか?なぜシンボル名がないのですか?