2012-05-25 13 views
17

私はgitブランチングモデルの周りを頭で覆そうとしていました。私はhttp://nvie.com/posts/a-successful-git-branching-model/をいくつかのアイデアを見て、私が本当に楽しみにしていたSubversionから来ているのは、単一の場所で変更を加え、それを必要とするすべてのブランチにマージすることでした。 Subversionでは、コードのコピーをたくさん作成することになりました。複数のブランチにホットフィックスをマージする

しかし、私はまだ完全にこれを取得しません。ここに私が持っている標準的なタイプのワークフローがあります。常に競合が発生します。

# create new version branch 
git checkout master 
git checkout -b v3 
vim pom.xml # change branch version to "3.1-SNAPSHOT" 
git commit -a 
git checkout master 
vim pom.xml # change master version to "4.0-SNAPSHOT" 
git commit -a 

したがって、マスターは4.0-SNAPSHOTにあり、分岐は3.1-SNAPSHOTにあります。

私はブランチに修正プログラムを作成し、それをトランクに移動したいと思います。

git checkout v3 
git checkout -b hotfix 
vim file.txt # make a bugfix change 
git commit -a 
git checkout v3 
git merge hotfix # this works fine 
git checkout master 
git merge hotfix # this has a conflict since both branches have changed the version 

私はなぜそれが起こっているのか理解しています。これを行うより良い方法はありますか?

私は私がテストしたチェリーピック、読ん作業を行います。

git checkout v3 
git cherry-pick a518b0b75eaf28868 
git checkout master 
git cherry-pick a518b0b75eaf28868 

しかし、それは、これを処理するための「正しい」方法のように見えるしていません。助言がありますか?場合

答えて

11

、あなたあなたのツリーが同じ履歴に基づいているかどうかに依存しています...たとえば、4.0は4.0のすべての変更の最新の3.X +すべてに基づいています...

個人的に、新しいバージョンの新しいブランチを開始することを決めたら、それをお勧めします。一定の時点で、ソフトウェアは異なる方向を取っているので、あなたの支店もそうでなければなりません。

これは、git cherry-pickを理想的な解決策として残します。どの支店でも最も意義のあるものを変更し、チェリーは古いバージョンに変更します。これは、古いブランチをチェックアウトした場合と同じで、手動でが同じ変更を適用し、新しいコミットを行った場合と同じです。それはそれを清潔に保ちます。

Gitにあなたがしたい場合は...等、私はバグ修正をバックポートするとき、あなたが望んでいない疑いがあるこれ、一緒に独自の方法で各支店履歴を統合しようとしている

+0

私は同意します(ただし、@ellothethの答えは状況によってはよりエレガントかもしれません)。 git自身の[分岐哲学](http://gitster.livejournal.com/42247.html)によれば、実際にはであり、このコミットはすべてのブランチに属する唯一のものです。ですから、チェリーピッキングはそれを「言う」ものです。 –

+0

ありがとう、私はそれが理にかなっていると思う。 Subversionから来て、時には私たちがトランクとブランチ(基本的に修正を2回行っています)に修正プログラムを適用するのがどれほど苦労していたのか、私は自分が望む場所に機能ブランチをマージできると思っていました。それが私が期待したようにうまくいかなかったとき、私はちょっとうんざりでした。 「チェリーピック」はセンスがあります。私は、すべての開発者が理解しやすいプロセスを考え出す必要があります。これはかなり明確にできると思います。 –

1

、あなたは枝の上に「4.0」を作業していると、「3.1」に修正を加える必要があり、あなたが「3.1」をコミットした後、あなたが「4.0」をリベースことがあります。

本当に
git checkout 4.0 # you are on the feature brnach 4.0 
git stash # save current work so you can check out other branch 
git checkout 3.1  
git commit -a -m "bug fix" # do editing and commit 
git checkout "4.0" 
git stash apply # get back your changes 
git rebase "3.1" # change 4.1 so it branches of the current head of "3.1" 
+3

これは可能ですが、タグに依存したり、押したり、効率的に4.0コードを共有する機能を削除しています。リベースは、個人的には素晴らしいですが、すでにプッシュしている場合はそれほど素晴らしいものではありません。 – gahooa

18

をマージするかリベースあなたが共通の祖先から修正プログラムを作成することができ、それについて超技術を取得:

git merge-base v3 master 
git checkout -b hotfix <whatever you got from merge-base> 
# make your fix 
git checkout v3 && git merge --no-ff hotfix 
git checkout master && git merge --no-ff hotfix 

     v3--------v3 (hotfixed) 
    /  /
ancestor----hotfix 
     \   \ 
     master----master (hotfixed) 

--no-ffフラグが代わりにv3またはmasterにラベルを引っ張る、修正プログラムの先端にhotfix分岐ラベルを保持します。

個人的には、それは残酷だと思います。私はgahooaと一緒に行くだろう:枝を互いに関連付ける方法に応じて、枝にホットフィックスをつけてマージするかチェリーを選ぶ。

+3

+1 'merge-base'、' --no-ff'と良いアドバイス。 'cherry-pick'は新しいコミットを作成します:同じdiff、ログメッセージ、タイムスタンプですが、異なるハッシュです。明確な歴史が重要なのであれば、私はマージベースが過度のものだとは思わない。チェリーピッキングは単純なケースでは機能しますが、次のようなことに注意してください:http://news.ycombinator.com/item?id=3947950 –

+0

あなたの回答からたくさんのことを学んでくれてありがとう! –

0

私はこの質問にも苦労しています。バージョン管理戦略を少し変更したいと思えばMavenが推奨する-SNAPSHOTのバージョンから出発した場合)、これはマスター(または開発ブランチが何であれ)上の固定バージョン(SNAPSHOTや0.0.0-SNAPSHOTなど)を使用することで解決できます。 MavenはSNAPSHOTバージョンのアーティファクトを別のものと扱うため、Mavenを使用している場合はSNAPSHOTの接尾辞が重要です。

実際には、バージョン番号を変更するというポリシーを設定したいと思います(リリースをビルドするもの)またはリリース目的のみ(たとえば、バージョン番号の変更)のブランチに、そして開発ブランチにマージするつもりはないブランチ上で実行することができます。

私は実際にこの戦略をまだ使用していませんが、それについて考えていて、試してみると思います。

関連する問題