簡単な解決策:マージ後に「work」ブランチを削除します
簡単な答え:マージを含め、gitを好きなように使用できます(簡単なワークフローについては以下を参照してください)。一時的な作業ブランチを削除するには、必ず各「gitmergework」の後に「gitbranch-dwork 」を続けてください。
背景
の説明:merge / dcommitの問題は、ブランチを「git svn dcommit」すると、そのブランチのマージ履歴が「フラット化」されることです。gitは、このブランチに入ったすべてのマージ操作を忘れます。ファイルの内容だけが保持されます。しかし、このコンテンツが(部分的に)特定の他のブランチからのものであるという事実は失われます。参照:git svn dcommitがローカルブランチのマージコミットの履歴を失うのはなぜですか?
(注:git-svnがそれについてできることはあまりありません:svnは単にはるかに強力なgitマージを理解していません。したがって、svnリポジトリ内では、このマージ情報を表すことはできません。)
しかし、これが全体の問題です。'masterブランチ'にマージされた後に'work'ブランチを削除すると、gitリポジトリは100%クリーンになり、svnリポジトリとまったく同じように見えます。
私のワークフロー:
もちろん、最初にリモートsvnリポジトリをローカルgitリポジトリに複製しました(これには時間がかかる場合があります)。
$> git svn clone <svn-repository-url> <local-directory>
その後、すべての作業は「ローカルディレクトリ」内で行われます。サーバーから更新を取得する必要があるときはいつでも(「svnupdate」など)、次のことを行います。
$> git checkout master
$> git svn rebase
私はすべての開発作業を、次のように作成された別のブランチ「作業」で行います。
$> git checkout -b work
もちろん、あなたはあなたの仕事のために好きなだけブランチを作成し、好きなだけそれらの間でマージしてリベースすることができます(それらが終わったらそれらを削除するだけです---以下で説明します)。私の通常の仕事では、私は非常に頻繁にコミットします:
$> git commit -am '-- finished a little piece of work'
次のステップ(git rebase -i)はオプションです--- svnにアーカイブする前に履歴をクリーンアップするだけです:他の人と共有したい安定したマイルストーンに到達したら、この「作業」の履歴を書き直しますコミットメッセージを分岐してクリーンアップします(他の開発者は、途中で行った小さな手順や間違いをすべて確認する必要はありません---結果だけです)。このために、私はします
$> git log
そして、svnリポジトリにある最後のコミットのsha-1ハッシュをコピーします(git-svn-idで示されます)。それから私は電話します
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
私の代わりに、最後のsvncommitのsha-1ハッシュを貼り付けるだけです。詳細については、「githelprebase」を使用してドキュメントを読むことをお勧めします。つまり、このコマンドは最初にコミットを表示するエディターを開きます----以前のコミットでスカッシュしたいすべてのコミットに対して「pick」を「squash」に変更するだけです。もちろん、最初の行は「ピック」のままにする必要があります。このようにして、多くの小さなコミットを1つ以上の意味のあるユニットに凝縮できます。エディターを保存して終了します。コミットログメッセージを書き直すように求める別のエディターが表示されます。
つまり、「コードハッキング」を終了した後、他のプログラマーにどのように提示したいか(または履歴を参照するときに数週間後にどのように作業を表示したいか)がわかるまで、「作業」ブランチをマッサージします。 。
変更をsvnリポジトリにプッシュするために、私は次のことを行います。
$> git checkout master
$> git svn rebase
これで、svnリポジトリでその間に発生したすべての変更で更新された古い「master」ブランチに戻ります(新しい変更は「work」ブランチに隠されています)。
新しい「作業」の変更と衝突する可能性のある変更がある場合は、新しい作業をプッシュする前に、ローカルでそれらを解決する必要があります(詳細は以下を参照してください)。次に、変更をsvnにプッシュできます。
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
注1:コマンド'git branch -d work'は非常に安全です。これにより、不要になったブランチのみを削除できます(現在のブランチに既にマージされているため)。作業を「master」ブランチとマージする前にこのコマンドを誤って実行すると、エラーメッセージが表示されます。
注2:マージとdcommitの間に「gitbranch -dwork」を使用してブランチを削除してください:dcommitの後にブランチを削除しようとすると、エラーメッセージが表示されます:「gitsvn dcommit」を実行すると、gitはそれを忘れますブランチは「マスター」とマージされました。安全チェックを行わない「gitbranch-Dwork」で削除する必要があります。
ここで、「master」ブランチを誤ってハッキングしないように、すぐに新しい「work」ブランチを作成します。
$> git checkout -b work
$> git branch # show my branches:
master
* work
'work'をsvnの変更と統合する:
'git svn rebase'が、'work'ブランチで作業しているときに他の人がsvnリポジトリを変更したことを明らかにしたときに私が行うことは次のとおりです。
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
より強力なソリューションが存在します
。提示されたワークフローは単純です。「update/hack / dcommit」の各ラウンド内でのみgitの機能を使用しますが、長期的なプロジェクト履歴はsvnリポジトリと同じように線形のままです。これは、レガシーsvnプロジェクトの小さな最初のステップでgitマージの使用を開始したい場合は問題ありません。
gitマージに慣れたら、他のワークフローを自由に調べてください。何をしているのかがわかっている場合は、gitマージとsvnマージを組み合わせることができます( svnマージを支援するためだけにgit-svn(または同様のもの)を使用しますか?)