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

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

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

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

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

オーケーグッド770HPランボルギーニセンテナリオは十分に正気ではない

オーケーグッド770HPランボルギーニセンテナリオは十分に正気ではない

ランボルギーニの創設者であるフェルッチオランボルギーニが100歳になるのは毎日ではありません(そうです、彼は死んでいて、まだ死んでいると思います。

彼らが買った1台の車からAppleの車の計画について私たちが推測できること

彼らが買った1台の車からAppleの車の計画について私たちが推測できること

Appleが自動車分野に参入するという噂はかなり前から渦巻いており、AppleウォッチャーがSixtyEight Researchという会社がAppleの自動車研究開発のシェル会社である可能性が高いと判断したとき、その渦巻きは本当に渦巻いた。また、会社が購入した車は1台だけであることが知られており、その車はAppleが何を考えているかについての手がかりでいっぱいになる可能性があることも伝えています。

天文学者は太陽系の9番目の惑星の新しい証拠を見つけます

天文学者は太陽系の9番目の惑星の新しい証拠を見つけます

太陽系の外側にある架空の大きな物体である惑星Xの探索は、何十年にもわたって人間を魅了してきました。その検索の最新の章は、地球の10倍の大きさで、公転周期が15であるほど遠くにある惑星を指しています。

キャムニュートン、ゴッドダム

キャムニュートン、ゴッドダム

カムニュートンは昨日、簡単な265ヤードと3回のタッチダウンでファルコンズを引き裂き、別の素晴らしいゲームをしました。その日のハイライトは、上のタッチダウンスローでした。これは、視聴するたびにばかげているだけです。

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。

コンセプト ドリフト: AI にとって世界の変化は速すぎる

コンセプト ドリフト: AI にとって世界の変化は速すぎる

私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

犯罪擁護派のオークランドが暴力犯罪者のロミオ・ロレンゾ・パーハムを釈放

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

メリック・ガーランドはアメリカに失敗しましたか?

バイデン大統領の任期の半分以上です。メリック・ガーランドは何を待っていますか?

メリック・ガーランドはアメリカに失敗しましたか?

人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。

Language