1. ホーム
  2. git

[解決済み] リベースの後、ブランチにプッシュできない

2022-06-01 10:14:57

質問

gitを使用しており、masterブランチとdeveloperブランチがあります。新しい機能を追加して、コミットをmasterにリベースし、masterをCIサーバーにプッシュする必要があります。

問題は、リベース中に競合が発生した場合、リベースが完了した後、リモートブランチをプルするまで、(Github 上の)リモート開発者ブランチにプッシュできないことです。そのため、コミットが重複してしまいます。コンフリクトがない場合は、期待通りに動作します。

質問: リベースと競合の解決後、重複コミットを作成せずにローカルとリモートの開発者ブランチを同期させるにはどうすればよいでしょうか。

セットアップです。

// master branch is the main branch
git checkout master
git checkout -b myNewFeature

// I will work on this at work and at home
git push origin myNewFeature

// work work work on myNewFeature
// master branch has been updated and will conflict with myNewFeature
git pull --rebase origin master

// we have conflicts
// solve conflict
git rebase --continue

//repeat until rebase is complete
git push origin myNewFeature

//ERROR
error: failed to push some refs to '[email protected]:ariklevy/dropLocker.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

// do what git says and pull
git pull origin myNewFeature

git push origin myNewFeature

// Now I have duplicate commits on the remote branch myNewFeature

編集

ということは、ワークフローが壊れるような気がするのですが。

開発者1がmyNewFeatureで作業中 開発者2が hisNewFeature を開発中 どちらも master をメインブランチとして使用

開発者2は myNewFeature を hisNewFeature にマージしています。

開発者1がリベースし、衝突を解決した後、myNewFeatureをリモートブランチに強制プッシュします。

数日後、developer2 が myNewFeature を hisNewFeature に再びマージしました。

これによって他の開発者は開発者1を憎むようになるのでしょうか?

どのように解決するのですか?

まず、あなたと一緒に作業している人たちは、トピック/develブランチを共有開発用とするか、自分だけのものとするかを合意する必要があります。他の開発者は、いつでもリベースされるから私の開発ブランチでマージしないように知っています。通常、ワークフローは次のようになります。

o-----o-----o-----o-----o-----o       master
 \
   o-----o-----o                      devel0
                \
                  o-----o-----o       devel1

それから、リモートの最新情報を得るために、次のようにします。

 git fetch origin
 git checkout master
 git merge --ff origin/master

私がこれを行う理由は2つあります。まず、develブランチから切り替えることなく、リモートでの変更を確認することができるからです。もうひとつは、まだ保存されていない、あるいはコミットされていない変更を上書きしてしまわないようにするための安全機構です。また、master ブランチに fast-forward でマージできない場合、誰かがリモート master をリベースしたか (これには厳しい非難が必要です)、私が誤って master にコミットしてしまい、自分側をクリーンアップする必要があることを意味します。

そして、リモートに変更があり、私が最新に早送りしたときにリベースします。

git checkout devel0
git rebase master
git push -f origin devel0

他の開発者は、彼らのdevelブランチを私の最新版からリベースする必要があることを知ることができます。

git fetch <remote>
git checkout devel1
git rebase <remote>/devel0

この結果、履歴がよりきれいになります。

o-----o                                 master
       \
         o-----o-----o                  devel0
                      \
                        o-----o-----o   devel1

ドンマイ は気まぐれにコミットを前後にマージします。重複したコミットを作成し、履歴を追うことができなくなるだけでなく、特定の変更からの回帰を見つけることはほぼ不可能になります (そもそもバージョン管理を使用しているのはそのためですよね?)。あなたが抱えている問題は、まさにこれを行った結果なのです。

また、他の開発者があなたのdevelブランチにコミットしている可能性があるようです。これを確認できますか?

マージするのは、あなたのトピックブランチが master .

余談ですが 複数の開発者が同じリポジトリにコミットしている場合、開発者のdevelブランチを区別するために名前付きブランチを持つことを全員で検討すべきです。たとえば

git branch 'my-name/devel-branch'

つまり、すべての開発者のトピックブランチは、自分自身のネストされたセットの中に存在するのです。