用了以后, 树可以非常清晰, 某种程度上便于追踪, 但是 push --force
就多多了,
不用呢, 合并没有远程仓库被修改的麻烦, 可是追踪又不清晰...
怎样取舍? 团队里一般怎么取舍?
滿天的星座2017-04-25 09:04:57
git rebase
はコミット履歴の書き換えです。書き換えたいコミット履歴がリモート リポジトリに送信されていない場合、 つまり他のユーザーと共有される前の場合、コミット履歴はプライベートであるため、どのようにでも書き換えることができます。欲しい。 git rebase
是对commit history的改写。当你要改写的commit history还没有被提交到远程repo的时候,也就是说,还没有与他人共享之前,commit history是你私人所有的,那么想怎么改写都可以。
而一旦被提交到远程后,这时如果再改写history,那么势必和他人的history长的就不一样了。git push
的时候,git会比较commit history,如果不一致,commit动作会被拒绝,唯一的办法就是带上-f
参数,强制要求commit,这时git会以committer的history覆写远程repo,从而完成代码的提交。虽然代码提交上去了,但是这样可能会造成别人工作成果的丢失,所以使用-f
参数要慎重。
楼主遇到的问题,就是改写了公有的commit history造成的。要解决这个问题,就要从提交流程上做规范。
举个正确流程的栗子:
假设楼主的team中有两个developer:tom和jerry,他们共同使用一个远程repo,并各自clone到自己的机器上,为了简化描述,这里假设只有一个branch:master
。
这时tom机器的repo有两个branchmaster
, origin/master
而jerry的机器上也是有两个branchmaster
, origin/master
均如下图所示
tom和jerry分别各自开发自己的新feature,不断有新的commit提交到他们各自私有的commit history中,所以他们的master指针不断的向前推移,分别指向不同的commit。而又由于他们都没有git fetch
和git push
,所以他们的origin/master
都维持不变。
jerry的repo如下
tom的repo如下,注意T1
和上图的J1
,分别是两个不同的commit
这时Tom首先把他的commit提交的远程repo中,那么他本机origin/master
指针则会前进,和master
git Push
の場合、git はコミット履歴を比較します。矛盾している場合、コミット アクションは拒否されます。唯一の方法は、-f
パラメーターを使用してコミットを強制することです。この時点で、Git はリモート リポジトリをコミッターの履歴で上書きして、コードの送信を完了します。コードは送信されましたが、他の人の作業が失われる可能性があるため、-f
パラメータは注意して使用してください。 投稿者が遭遇した問題は、パブリック コミット履歴の書き換えによって引き起こされました。この問題を解決するには提出プロセスを標準化する必要があります。 正しいプロセスの例を挙げてください:
投稿者のチームにはトムとジェリーという 2 人の開発者がいると仮定します。彼らは共同でリモート リポジトリを使用し、それを自分のマシンにクローンします。 というブランチが 1 つだけあると仮定します。 >マスター コード>。
現時点では、トムマシンのリポジトリには 2 つのブランチがありますmaster
、origin/master
ジェリーのマシンには 2 つのブランチmaster
、origin/master
もあります
はすべて下の写真の通りです
git fetch
と git Push
がないため、origin/master
は変更されません。 #🎜🎜#
#🎜🎜#ジェリーのレポは以下の通りです#🎜🎜#
#🎜🎜##🎜🎜##🎜🎜##🎜🎜#
#🎜🎜#Tom のリポジトリは次のとおりです。上の図の T1
と J1
は 2 つの異なるコミットであることに注意してください#🎜🎜#
#🎜🎜##🎜🎜##🎜🎜##🎜🎜#
#🎜🎜#このとき、Tom は最初にコミットをリモート リポジトリに送信し、その後、ローカルの origin/master
ポインタが進み、master
ポインタと一致します。 #🎜🎜#をフォローします
#🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#
#🎜🎜#リモートリポジトリは以下の通りです#🎜🎜#
#🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜# ここで、Jerry はコミットをリモート リポジトリに送信して git Push
を実行したいと考えています。これは当然失敗したため、git fetch
を実行して実行しました。以下のように、リモート リポジトリ、つまり T1
がトムによってローカル リポジトリに送信されましたgit push
,毫无意外的失败了,所以他git fetch
了一下,把远程repo,也就是之前tom提交的T1
给拉到了他本机repo中,如下
commit history出现了分叉,要想把tom之前提交的内容包含到自己的工作中来,有一个方法就是git merge
,它会自动生成一个commit,既包含tom的提交,也包含jerry的提交,这样就把两个分叉的commit重新又合并在一起。但是这个自动生成的commit会有两个parent,review代码的时候必须要比较两次,很不方便。
jerry为了保证commit history的线性,决定采用另外一种方法,就是git rebase
。jerry的提交J1
这时还没有被提交到远程repo上去,也就是他完全私有的一个commit,所以使用git rebase
改写J1
的history完全没有问题,改写之后,如下
注意J1
被改写到T1
后面了,变成了J1`
git push
后,本机repo
而远程repo
异常的轻松,一条直线,没有-f
所以,在不用-f
的前提下,想维持树的整洁,方法就是:在git push
之前,先git fetch
,再git rebase
コミット履歴が分岐しました。Tom が以前に送信したコンテンツを自分の作品に含めたい場合、1 つの方法は
git merge
です。これは、Tom の送信も含むコミットを自動的に生成します。にはジェリーの送信が含まれているため、フォークされた 2 つのコミットが再びマージされます。ただし、この自動生成されたコミットには 2 つの親があるため、コードをレビューするときに 2 回比較する必要があり、非常に不便です。 git rebase
を使用することにしました。ジェリーのコミット J1
は現時点ではリモート リポジトリに送信されていません。これは彼の完全にプライベートなコミットであるため、git rebase
を使用して J1
を書き換えます。書き換えると履歴は全く問題ありません J1
は T1
の後に書き換えられ、J1`
になることに注意してください#🎜🎜#
#🎜🎜#git Push
後、ローカル リポジトリ#🎜🎜#
#🎜🎜# #🎜🎜#
#🎜🎜#そしてリモートリポジトリ#🎜🎜#
#🎜🎜# #🎜🎜#
#🎜🎜#非常にリラックスした直線、-f
はありません#🎜🎜#
#🎜🎜#したがって、-f
を使用せずにツリーをクリーンに保ちたい場合の方法は次のとおりです: git Push
コードの前に git fetch
>、git rebase
の順にクリックします。 #🎜🎜#
リーリー
#🎜🎜#ぜひ読んでください#🎜🎜#
#🎜🎜#
#🎜🎜#成功した git ブランチング モデル#🎜🎜#
#🎜🎜#Git ブランチブランチリベース#🎜🎜#
#🎜🎜#PHPz2017-04-25 09:04:57
ローカルブランチとリモートブランチのバインド(追跡)とリベース戦略:
リーリーこのようにして、コードを更新するとき (pull
)、サードパーティの合併によって引き起こされる競合などの他の状況がない限り、マージ コミットを生成する代わりにリベースが自動的に適用されます。介入。ほとんどの場合、チームの習慣が良好である限り、非常にきれいで美しい樹形を維持できます。 pull
)的时候就会自动应用 rebase 而不是产生 merge commit,除非有其他情况产生,比如三方合并造成了冲突需要人共去干预。大部分时候还是很聪明的,只要团队里的习惯都良好,那么可以保持一个非常干净漂亮的树形。
其实想让树形结构漂亮些清晰些是有很多办法的,但是首先要取决于团队用的是什么样的 Git Model,对症下药即可。在这里就无法一言以蔽之了。
另外,楼上说得对,慎用 push -f
実際、ツリー構造をより美しく明確にする方法はたくさんありますが、それはまずチームが使用する Git モデルの種類に依存し、適切な薬を処方するだけで済みます。ここで要約する方法はありません。
push -f
の使用には注意してください。 🎜🎜我想大声告诉你2017-04-25 09:04:57
これは git ワークフローの問題であるはずです。私たちのチームはコミット情報がクリーンであることを確認するためにリベースを使用していますが、push -f
などの操作は使用されません。 push -f
这样的操作。
关于git workflow就是一个见仁见智的问题了,下面几篇文章你可以看下,再找出一套适合自己团队的就可以了,不过最重要的是要保证团队的每个人都熟悉git,防止犯愚蠢的错误。
如果使用github来团队合作的话,用好pull request,它可以解决push -f
push -f
のような愚かな問題を解決できます。 🎜阿神2017-04-25 09:04:57
送信する前に、変更をサーバーの最新のコードにリベースする必要があります。このルールに従えば問題はありません。強制プッシュが必要な場合は、強制プッシュが必要になる前にサーバー コードをローカル ブランチにリベースすることを意味します。これは間違った使用法です。
PHP中文网2017-04-25 09:04:57
Pro Git のリベースに関する章を参照することをお勧めします http://git-scm.com/book/zh/Git-%E5%88%86%E6%94%AF-%E5%88%86% E6%94% AF%E7%9A%84%E8%A1%8D%E5%90%88
再生のリスク
さて、この素晴らしい派生は完璧ではありませんが、それを使用するには 1 つのルールに従う必要があります:ブランチ内の送信オブジェクトがパブリック ウェアハウスに公開された後は、ブランチをリベースしないでください。
この黄金律に従えば、何も問題は起こりません。そうしないと、人々はあなたを憎み、友人や家族はあなたを笑い、拒絶するでしょう。
私に関する限り。リベース後に push -f
を使用する必要がある場合、それはリベース操作が不適切であることを意味するに違いありません。コミット履歴を変更するつもりがない限り。
伊谢尔伦2017-04-25 09:04:57
上記の答えはすべて正しいです。個人的には、特定のブランチで作業しているのがあなただけでない限り、問題なくリベースできます。チーム内では何の問題もありません。特に git に詳しくないチームメイトは、あなたを撃ち殺そうとします。戸惑うのはごく普通のことです。 リベース後に Push -f を実行できる状況は 1 つだけです。つまり、被験者は私と同じように強迫性障害を抱えており、コンピューターのダウンタイムとシステムクラッシュ (血と涙の悲劇的な歴史) を恐れており、機能を完了した後です。 commit して、すぐにリモートにプッシュ 自分だけが所有するブランチ
上で、develop の新機能を取得するために、毎日自分のブランチにデベロップをリベースしてプッシュ操作を繰り返す これは個人的には無いと思います。結局のところ、影響を受けるのは自分自身だけです(これが正しいことはわかっています)。PHP中文网2017-04-25 09:04:57
個人的には、特定のブランチでチームとして作業しているときにリベースを使用するのは非常に不合理だと思います。そして間違いやすいのです。慎重に使用してくださいpush --force
習慣沉默2017-04-25 09:04:57
git rebase は通常、単独で開発する場合に送信レコードをクリーンに保つために使用されます。 github にアップロードしたら、git rebase を使用しないでください。使用しないと死ぬほど叱られます。