git履歴からコミットを削除する方法、それ以外の場合はマージを含めてグラフをまったく同じに保つ方法は?

3
Daniel Stephens 2020-04-11 15:39.

私が持っているもの:

---A----B-----C-----D--------*-----E-------> (master)
                     \      /
                      1----2 (foo)

必要なもの:

---A---------------D--------*-----E-------> (master)
                    \      /
                     1----2 (foo)

少し前に、gitリポジトリから削除したい2つのコミットを行いました。さまざまなリベースの「チュートリアル」を試しましたが、すべてが奇妙なgit履歴で終わっていたため、レポの例を作成しましたが、期待した結果ではありませんでした。誰かが私が欠けているものを理解するのを手伝ってくれますか?

私には2つのブランチがmasterありfooます。削除したい単一のファイルでコミットBを作成し、このファイルを変更した場所でCをコミットしました。他のコミットに沿って、私はこのファイルに二度と触れませんでした。

コミットID:

A: f0e0796
B: 5ccb371
C: a46df1c
D: 8eb025b
E: b763a46
1: f5b0116
2: 175e01f

だから私はBCを使用rebase -i f0e0796して削除します、正しいですか?結果を正しく解釈すると、2番目のブランチがリストされますが、これが私のリポジトリに表示されます。 5ccb371 a46df1cgitkgit branches

---A-----1----2---E------> (master)

ここで何が起こったのか誰か教えてもらえますか?

編集:これは、最初のグラフからリポジトリを再作成する方法です。

git init foo
cd foo

touch A
git add A
git commit -m "add A"

touch B
git add B
git commit -m "add B"

echo "modify" > B
git add B
git commit -m "modify B"

touch C
git add C
git commit -m "add C"

git checkout -b foo

touch 1
git add 1
git commit -m "add 1"

touch 2
git add 2
git commit -m "add 2"

git switch master
git merge foo --no-ff

touch E
git add E
git commit -m "add E"

5 answers

2
Smeet Thakkar 2020-04-13 01:50.

私が提案していることはあなたにきれいで直線的な歴史を与えるでしょうが、それがリベースが本質的に行うことになっていることです。ただし、これにより、コミット履歴からBとB 'を削除する方法が得られることを期待しています。ここに説明があります:

Repo recreation output:
---A----B-----B'-----C--------D-------> (master)
                      \      /
                       1----2 (foo)

git log --graph --all --oneline --decorate #initial view the git commit graph
* dfa0f63 (HEAD -> master) add E
*   843612e Merge branch 'foo'
|\  
| * 3fd261f (foo) add 2
| * ed338bb add 1
|/  
* bf79650 add C
* ff94039 modify B
* 583110a add B
* cd8f6cd add A

git rebase -i HEAD~5 #here you drop 583110a/add B and ff94039/modify B from
foo branch.

git log --graph --all --oneline --decorate
$ git rebase -i HEAD~5 * 701d9e7 (HEAD -> master) add E * 5a4be4f add 2 * 75b43d5 add 1 * 151742d add C | * 3fd261f (foo) add 2 | * ed338bb add 1 | * bf79650 add C | * ff94039 modify B | * 583110a add B |/ * cd8f6cd add A $ git rebase -i master foo #drop 583110a/add B and ff94039/modify B again

$ git log --graph --all --oneline --decorate #view the git commit graph

* 701d9e7 (HEAD -> foo, master) add E
* 5a4be4f add 2
* 75b43d5 add 1
* 151742d add C
* cd8f6cd add A

最後に、ファイナルアウトはあなたが期待した順序ではないかもしれませんA--C--1 --- 2 --- E。ただし、インタラクティブモード内で順序を再配置することはできます。git rebase -i HEAD〜nを試してください。

注:コミット/公開履歴の変更は避けるのが最善です。私は初心者でgitを探索していますが、上記の解決策が続くことを願っています。そうは言っても、オンラインで利用できる他のより簡単なソリューションがたくさんあることは確かです。この記事は、今後の参考のために非常に役立ちました。

3
Inigo 2020-04-24 22:31.

git rebaseデフォルトでは、コミット履歴の単一の系統にのみリベースします。これは、より一般的にはそれが人々が望んでいるものだからです。特に指定しない場合は、チェックアウトしたブランチに対して実行されます(この場合はmaster)。そのためmasterfooコミットがマージされるのではなく移植され、fooそれ自体は変更されず、接続されなくなった、リベースされたブランチになりました。

gitバージョン2.18以降を使用している--rebase-merges場合は、オプション*を使用して、デフォルトのように線形化するのではなく、マージ履歴を再作成するようにgitに指示できます。リベースされた履歴には、同じ分岐とマージがあります。以下では、を使用して目的を達成するための手順を説明します--rebase-merges

これらの手順は、質問に表示されている正確なリポジトリを前提としています。

  1. git checkout master
  2. git rebase -i --rebase-merges f0e0796
  3. インタラクティブリベースtodoファイル内:
    • あなたがドロップしたかった2つのコミットを削除(またはそれらをコメントアウト、または変更pickしますdropd
    • 行の直後の新しい行にlabel foo、次を追加します。
    exec git branch -f foo head
    
    (説明については以下を参照してください)
  4. todoファイルを保存して閉じると、gitはコミットをリベースし、グラフが希望どおりに表示されます。


todoファイルを説明しました

git rebase手動で実行できる一連の手順を自動化するだけです。この一連の手順は、todoファイルに示されています。git rebase --interactive実行する前にシーケンスを変更できます。

手動で行う方法(優れた学習経験)などの説明を注釈として付けます。将来多くのリベースを行う場合は、これを感じることが重要です。これにより、マージの競合が発生した場合、またはリベースにポイントで一時停止して手動で変更できるように指示した場合に、良好な関係が得られます。

label onto                  // labels "rebase onto" commit (f0e0796)
                            // this is what you would do in your head
                            // if doing this manually
# Branch foo
reset onto                  // git reset --hard <onto>
drop 5ccb371 add B          // skip this commit
drop a46df1c modify B       // skip this commit
pick 8eb025b add C          // git cherry-pick 8eb025b
label branch-point          // label this commit so we can reset back to it later
pick f5b0116 add 1          // git cherry-pick f5b0116
pick 175e01f add 2          // git cherry-pick 175e01f
label foo                   // label this commit so we can merge it later
                            //   This is just a rebase internal label. 
                            //   It does not affect the `foo` branch ref.
exec git branch -f foo head // point the `foo` branch ref to this commit 

reset branch-point # add C  // git reset --hard <branch-point>
merge -C b763a46 foo # Merge branch 'foo'  // git merge --no-ff foo
                                           // use comment from b763a46

exec git branch -f foo head 説明

上で述べたように、gitrebaseは1つのブランチでのみ動作します。このexecコマンドが行うことはfoo、現在を指すようにrefを変更することheadです。todoファイルのシーケンスでわかるように、todoファイルでfoo便利にラベル付けさlabel fooれているブランチの最後のコミット(「add2」)をコミットした直後にこれを行うように指示しています。

foorefが不要になった場合(たとえば、機能ブランチであり、これが最後のマージである場合)、この行をtodoファイルに追加することをスキップできます。

この行の追加をスキップしてfoo、リベースが完了した後に必要なコミットを個別に再ポイントすることもできます。

git branch -f foo <hash of the rebased commit that should be the new head of `foo`>

ご不明な点がございましたらお知らせください。


*古いバージョンのgitを使用している場合は、現在非推奨の--preserve-mergesオプションを使用できますが、リベースのインタラクティブモードとは互換性がありません。

2
jthill 2020-04-25 03:10.

だから私はBCを使用rebase -i f0e0796して削除します、正しいですか?結果を正しく解釈すると、2番目のブランチがリストされますが、これが私のリポジトリに表示されます。 5ccb371 a46df1cgitkgit branches

...A---1---2---E    master

ここで何が起こったのか誰か教えてもらえますか?

それがそのために構築されたものです。単一のチップから単一のベースまでマージのない線形履歴を生成し、新しいベースへのマージバックが必要な可能性のあるすべてのパーツを保持します。

リベースのドキュメントはこれについてより明確になる可能性があります:「(によって決定されるgit log --cherry-mark …)クリーンなチェリーピックであるコミットは常にドロップされます。」は空のコミットを処理する方法のオプションの脇としてのみ言及され、「デフォルトではリベースマージコミットをtodoリストから削除し、リベースされたコミットを単一の線形ブランチに配置するだけです。」は、別のオプションの説明でさらに詳しく説明されています。しかし、それが目的です。面倒な識別と、すでに適用されている修正の排除と、他の方法では単純なチェリーピックからのノイズマージを自動化することです。


git rebaseは、問題を探している機能ですか?

あんまり。--rebase-mergesオプションは、強化している、とイニゴの答えはあなたの特定のケースに適していますが、そのドキュメント内の警告を参照してください:それは本当の制限や注意点があります。Inigoの回答が指摘しているように、「これらの手順は、質問に表示されている正確なリポジトリを前提としています」、「git rebase手動で実行できる一連の手順を自動化するだけです」。この答えの理由は、1回限りの作業の場合、通常はそれを行う方がよいためです。

Rebaseは、マージ元のブランチがあるか、開発中に同期を維持しているワークフローを自動化するために構築されました。少なくとも最後のマージバック(およびその前の数回)では、履歴をクリーンアップする必要があります。

それは他の多くの用途(特にパッチを運ぶ)に便利ですが、繰り返しますが、それは万能薬ではありません。たくさんのハンマーが必要です。それらの多くはピンチで提供するために伸ばすことができ、私は「何でもうまくいく」の大ファンですが、それはすでに彼らのツールに非常に精通している人々にとっては最高だと思います。

必要なのは、単一のクリーンな線形履歴を生成することではなく、別の何かが必要です。

使い慣れたツールを使用してそれを行う一般的な方法は簡単です。デモスクリプトから始めます。

git checkout :/A; git cherry-pick :/D :/1 :/2; git branch -f foo
git checkout foo^{/D}; git merge foo; git cherry-pick :/E; git branch -f master

これで完了です。

はい、あなたは可能性があり得るgit rebase -irあなたのためにこれを設定するには、私は生産ピックリストを見たとき、右の手順で編集することは上記のシーケンスよりも簡単か簡単には思えませんでした。あなたが望む正確な結果を理解しgit rebase -ir、あなたのためにそれを行う方法を理解することがあります、そしてそれをするだけです。

git rebase -r --onto :/A :/C master
git branch -f foo :/2

Inigoが「質問に表示する正確なリポジトリ」と言っているように、これはおそらく私が使用する「機能するものは何でも」の回答です。メッセージ検索構文については、git help revisionsドキュメントを参照してください。

1
Mark Adelsberger 2020-04-12 01:29.

コミット履歴を並べ替えるには、いくつかの方法があります。

rebaseリポジトリ全体の履歴を変更する場合の問題は、一度に1つのブランチしか移動しないことです。さらに、マージの処理に問題があるため、現在存在する最新の履歴を保持しながらD、単純にリベースしてEオンにすることはできませんAEマージであるため)。

これらすべてを回避することはできますが、方法は複雑でエラーが発生しやすくなります。フルレポの書き換え用に設計されたツールがあります。filter-repo(を置き換えるツールfilter-branch)を見たいと思うかもしれませんが、履歴から特定のファイルをスクラブしようとしているようです。これは、(1)BFG Repo Cleanerに適しているか、(2)実際には十分に簡単なタスクですfilter-branch

(BFGを調べたい場合は、 https://rtyley.github.io/bfg-repo-cleaner/; 調べたい場合はfilter-repo、https://github.com/newren/git-filter-repo)

filter-branchこの目的で使用するには

git filter-branch --index-filter 'git rm --cached --ignore-unmatch path/to/file' --prune-empty -- --all

ただし、ファイルをリポジトリに含めないようにする必要があることを示しました(次のコミットからファイルを削除するという誰かの提案に対するカウンターとして)。したがって、gitはそれほど簡単に情報をあきらめないことを理解する必要があります。これらの手法のいずれかを使用した後でも、リポジトリからファイルを抽出できます。

これは一種の大きなトピックであり、SOに関するさまざまな質問/回答で何度も議論されているので、実際に質問する必要があるものを検索することをお勧めします。ソースの下にあるはずのないファイルを完全に削除する方法です。コントロール。

いくつかの注意:

1-パスワードがあり、それらが共有リモートにプッシュされた場合、それらのパスワードは危険にさらされます。それについてあなたができることは何もありません。パスワードを変更します。

2-各リポジトリ(リモートおよびすべてのクローン)は、意図的にスクラブするか、破棄して交換する必要があります。(協力したくない人に強制することはできないという事実は、(1)の理由の1つです。)

3-修復を行ったローカルリポジトリで、reflog(filter-branchおよびのようなツールを使用した場合に作成された可能性のあるバックアップref)を削除してから実行する必要がありgcます。または、ブランチの新しいバージョンのみをフェッチする新しいリポジトリに再クローンを作成する方が簡単な場合があります。

4-リモコンのホスト方法によっては、リモコンをクリーンアップできない場合もあります。場合によっては、リモートを削除してから最初から再作成するのが最善の方法です。

1
Mad Physicist 2020-04-11 22:51.

最初に理解することは、コミットは不変のオブジェクトであるということです。提案どおりに履歴を書き換えると、完全に異なる一連のコミットが発生します。親は、特に変更できない各コミットの不変ハッシュの一部です。提案したことを行うと、履歴は次のようになります。

     D'-----E'-----> (master)
    /
---A----B-----C-----D--------E-------> (abandoned)
                     \      /
                      1----2 (foo)

これを実現するには、にリベースD..EAてにリセットmasterするだけE'です。次に、にリベース1..fooすることができます(ただし、実際にそうする必要はありません)D'

はるかに簡単で、私の意見では正しい方法は、新しいコミットでファイルを削除することです。

---A----B-----C-----D--------E-----F-----> (master)
                     \      /
                      1----2 (foo)

これFがの結果ですgit rm that_file。gitの目的は履歴を維持することです。見た目が良くないという理由だけで剪定することは生産的ではありません(繰り返しますが、私の意見です)。前者のオプションをお勧めするのは、問題のファイルにパスワードなどの機密情報が含まれている場合のみです。

一方、ファイルのスクラブが必要な場合は、より極端な対策を講じる必要があります。例:Git履歴からファイルを削除する方法は?

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ジョー・バロウロー対ウェイド事件の転覆に対応するNFLは、言葉を言わないことで、腹立たしいが予測可能なPRの結果でした。

別の日、別のヒンジのないLIV記者会見

別の日、別のヒンジのないLIV記者会見

(lから)パット・ペレス、ブルックス・ケプカ、パトリック・リードサウジアラビアのLIVゴルフリーグのさらに別の信じられないほどの記者会見で、スポーツのファンはブルックス・ケプカからでたらめな吐き気と質問回避の驚異的なマスタークラスを受けました。パトリックリード、ブライソンデシャンボー、パットペレス、最近のPGAツアーの脱北者。

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

レッドダガーとマーベルさんがチームを組んでいます。

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

暗号業界最大の沈没船の1つであるスリーアローズキャピタルは、ついにその悲惨さから解放されています。火曜日に、不良債権ヘッジファンドは、債権者からの返済を要求する訴訟の高まりに応えて、バージンアイランド裁判所によって清算を命じられました彼らが3ACに行ったローン。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Suffragettes Indicam #3: Junho

Suffragettes Indicam #3: Junho

Mais um mês se findando — e metade do ano de 2022 já passou. Sabe o que isso significa? Não, não é hora de verificar se você está cumprindo com suas resoluções de Ano Novo.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

メインネットガイド— Arbitrum Odyssey Week 2

メインネットガイド— Arbitrum Odyssey Week 2

最新のアップデートを受け取るために私たちに従ってください。ニュースレター:https://www。

Language