web-dev-qa-db-ja.com

名前が変更されたファイルを使用したGitリベース

多くのファイルの名前を変更するブランチがあり、元のファイルが変更されたmasterにリベースしようとしています(できれば、手動での競合解決の悪夢に陥ることはありません)。

状況

  1. JavaScriptプロジェクトをTypeScriptのローカルTypeScriptブランチに移植しています。すべての.jsファイルが.tsファイルになり、一部の構文がアップグレードされました。

  2. その間、元の.jsファイルへの変更がmasterブランチで行われました。

  3. rebaseTypeScriptブランチをmasterにブランチしたい-しかし、変更がファイルとして正しくマージされない名前の変更は検出されませんでした。つまり、gitが削除されたと見なしている.jsファイルに変更が加えられると、競合が発生します(ただし、実際には.tsファイルに名前が変更されています)。

私が知っていると思うこと

Gitグラフ:

o-[TypeScript] .js files become .ts
|
| o-[master] changes to the .js files
| |
| o
|/
o-[root] common ancestor

したがって、rootブランチに立っている間:

  • このコマンドを実行して、すべての名前変更を表示できます:git diff --name-status --find-renames=10% TypeScript

  • git merge コマンドに同じ種類の--find-renames機能があることを理解していますが、うまく機能しません。

    • Update:git merge -X find-renames=10% mybranchは、予想される構文のようです。
  • git rebasemightサポートfind-renames機能を理解していますが、それがどのように使用されるかはまだわかりません。

ソリューションのアイデア?

  1. (いいえ)おそらくrootから、名前の変更を検出しながらTypeScriptにマージできます(このように:git merge -X find-renames=10% TypeScript)。その場合、ルートはTypeScriptと同じですが、名前の変更(一括削除/追加ではなく)を除きます。

    • そこから、git rebase masterだけでいいのにと思います。名前の変更が行われているため、操作はスムーズに行われ、編集内容が正しいファイルに保存されます。
      • 更新:私はこれを試しましたが、その後のリベースは以前よりうまくいきませんでした。
  2. (うん)おそらく、リベース自体はfind-renamesオプションで実行する必要があると思います。これについて調査しています...

    • git rebase -X find-renames=10% master-いいえ
    • git rebase -X --find-renames=10% master-いいえ
    • git rebase --find-renames=10% master-いいえ
    • git rebase -X recursive --find-renames=10% master-いいえ
    • git rebase --merge -X find-renames=10% master-いいえ
    • git rebase --strategy-option="rename-threshold=10" master-それがチケットです!うまくいく!
  3. (いいえ)おそらく問題を別の方法で見る必要がありますか?多分私はmasterから始めて、次にTypeScriptの名前を変更して検出する何らかのスカッシュマージを実行する必要があります(どのようなリベースよりも)。

    • TypeScriptブランチの履歴は必要ありません。レビューのために1つのファットコミットにまとめられます。
    • 更新:この戦略を試すとGitが機能しなくなったようです。rootブランチに立っているときは、 git merge -X find-renames=10 TypeScriptを実行すると、TypeScript ..に早送りされます(私が望んでいたものではないため、追加/削除ではなく名前が変更された新しいコミットを望んでいました。)
      • masterブランチに立っているときにを実行すると、まったく同じコマンド、gitはこれを教えてくれます:fatal: Unknown option for merge-recursive: -Xfind-renames=10...
      • さて、これは私が実際に引用したものを入力しなかったので(スペースを含めました)、私に違っているように見える唯一のことは、オプションが「不明」の場合、現在立っているブランチです。 "では、なぜ別のブランチにいるときにworkするのですか?
      • とにかく、それは気味が悪いので、このアプローチは行き止まりになりそうです。
19
ChaseMoskal

次のように名前変更を検出しながら、ブランチをリベースできます。

git rebase --strategy-option="rename-threshold=10" master

編集:Git 2.8.0以降、「rename- threshold」は「find-renames」のために廃止されました。

現時点ではGit 2.7.4を使用しているため、上記のコマンドが私の場合に機能することを実際に確認することしかできませんでした。上記の場合、「find-renames」という用語を使用する必要があるかもしれません。新しいバージョンのGitではコマンドが機能しない...

この例では、

  • 現在のブランチmasterに基づいています
  • 10%の名前変更しきい値が指定されている
  • masterを元のファイルに変更すると、新しい(名前が変更された)ファイルに配置されます(git rebase masterだけを実行するのではなく)。
  • git diffgit log、およびgit mergeコマンドにある同様の名前変更検出機能と比較して、構文がどのように異なるかに注意してください

git rebase のドキュメントは、特にこの名前変更検出の側面についてあまり明確ではありません。別のコマンドをどこかで読んだところ、「rename-threshold」という用語は廃止されましたが、このコンテキストではfind-renamesは同義語として機能していないようです-したがって、この同じコマンドを実行するより良い方法を誰かが知っている場合は、そのように述べてください:)

22
ChaseMoskal