看了Git官网的这一段介绍更加迷惑了
用 Git 的话,就算你在飞机或者火车上,都可以非常愉快地频繁提交更新, 等到了有网络的时候再上传到远程仓库。同样,在回家的路上,不用连接VPN 你也可以继续工作。换作其他版本控制系统,这么做几乎不可能,抑或非常麻烦。
链接地址》》》
有一个商城项目正在上线,团队中有A、B、C三个程序员,使用git来进行版本控制。总共开发天数是10天,从第1天到第5天,A、B、C都是一起开发,一起提交,一个版本。但是到了第6天开始,C就不提交到远程了,一直都是在自己修改制作。整个项目很多文件,C会把项目中的文件GlobalFunction.php改动很多次,修改了很多函数,也加入了很多自己的函数。随着开发的继续,C还会不断的陆续修改GlobalFunction.php文件。而一直都提交到远程的A和B,也需要经常修改GlobalFunction.php文件,但是A和B会保持同步到Git远程。
到了最后第10天,C可以联网了,然后C提交到远程。可C电脑里面的GlobalFunction.php 跟 Git远程上的 GlobalFunction.php 已经完全不一样了,而且远程的这个文件还经历过了二十多个版本。而C自己电脑里面的也经历过了几十个不同版本。
根据git介绍中的那一段的描述,这样的情况下,Git是可以自动合并?如何自动合并?
C已经在GlobalFunction.php中加入了很多函数且期间也经历过了很多次的版本。
看到很多介绍Git的文章重点都放在了不需要push到远程,不需要联网就可以使用,真的觉得实在是难以理解。我在sf问也有很多人也在说不用push,/q/1010000000605934#c-1020000000606050-1050000000609657,更让人迷惑。不用push,假如1年或者10年了从来都不push到远程,那么还算是协同工作了吗,git会那么神奇10年之后再联网push过去还可以自动合并
シナリオを極端に推し進めるのは、議論の仕方としては良くありません。
まず第一に、送信の目的は何でしょうか? コードを他の人に同期するだけである場合、Git には実際には何の特徴もありません。これが欠点です。
個人的には、送信の目的はコードを一時的に保存すること (その後の Shenma のロールバックを容易にするためのバージョン管理)、2 つ目はコードのステージ ノードとして機能すること (この機能は完了し、送信すること)、そして3 つ目は、サーバーと同期することです。
Git のオフライン送信は、上記の目的の 1 つまたは 2 つを非常にうまく達成できます。また、オフラインで送信されるため、サーバーと同期する前に送信レコードを簡単に変更できます。これは何に使用されますか?たとえば、メソッドを書いて動作するのでリファクタリングしたいが、リファクタリング後に正しく動作するかどうかわからないため、リファクタリングが中断した場合にロールバックできるように、最初にバージョンを送信します。リファクタリングが完了したら、再度提出します。この時点では、同じ機能の 2 つの送信があり、他の人には 1 つの送信「XX 機能が完了しました」だけを表示したい場合があるため、2 つの送信を簡単にマージできます。最終的なマージの後、コード リポジトリは非常にきれいになります。これらの提出は、実際に提出する必要があるため、「Test XXX」や「Try XXX」を表示せずに直接リリース ノートに書き込むことができます。同じ結果に基づいて、1 回作成したコードを複数回送信することもできます。たとえば、3 つの関数を作成した場合、それを 3 回送信し、最後に SVN でサーバーに同期することを選択できます。ネットワークがありません) コードは 1 回のみ送信でき、その後「3 つの関数 A、B、および C を完了する」と記述できます。これは他の人がコードを閲覧するのに不便であり、A、B、をロールバックするのにも役立ちません。とCをそれぞれ。
つまり、git のオフライン送信は柔軟性をもたらします。オフラインでの提出ではサーバーが必要ないというわけではありません。共同作業は Air が自動的に完了します。冒頭で「場面を極端に押し出すのは間違った議論方法だ」と言ったのはこのことだ。 svn と比較すると、git はコラボレーション方法が多く、より柔軟ですが、それでも共同作業やコードのマージが必要になるという問題は避けられません。
コードをマージするプロセスでは、SVN と同様に競合も発生するため、条件が許せば適時にコードをサーバーと同期することを習慣にしてください。ただし、git はコンテンツベースの追跡バージョンであり、svn は基本的なファイル追跡バージョンであるため、git merge は svn よりも信頼性が高くなります。つまり、同じ状況下では、git は svn よりも競合が発生する可能性がはるかに低くなります。
最後に、git のオフライン送信機能と、git ブランチが特に使いやすいという事実により、ローカルのマルチブランチ管理機能を実装することもできます。つまり、関数で作業しているときに、ローカルにブランチしてからローカルに送信し、完了したらマージしてサーバーにプッシュします。他の人にとってはこのブランチは存在しませんが、いつでも動作ステータスを切り替えることができます (新しい機能を作成したり、正しいバグに切り替えてください)。 SVN はブランチをカットすることもできますが、そのブランチはローカルにしか存在できません。ブランチのコラボレーションが採用されている場合、多くのブランチが存在し、そのうちのいくつかは他のブランチを気にする必要がありません。さらに厄介なのは、新しい機能の作成途中で、戻ってバグを修正する必要がある場合、私の個人的な意見では、未完成のコードを svn サーバーに送信することしかできないことです (未完成のコードをリポジトリ サーバーに送信する)。これは非常に悪い動作ですが、git の場合、ブランチがオフラインであるため、サブミットした後、バグを修正するためにスイッチを戻し、その後再びスイッチを戻し、関数が完了した後、サブミットレコードをマージすると、すべてが正常になります。完璧。
双方が異なるファイル、または同じファイルの異なる部分を変更した場合、git はそれらを自動的にマージできます。
同じファイルの同じ部分が変更された場合、Git は自動的にマージできなくなります。この状況は Git によって両方の最新バージョンがリストされ、マージを実行した人がリストされます (C)。例では))、手動で編集します。
実際の開発では、2 人がこのファイルに関数を追加するだけであれば、主に同じ行を変更したときに競合が発生します。
補足への回答:
多くの紹介では、git がオフラインでコミットできることを強調していますが、これは svn と比較することを目的としています。 svn では、サーバーのみが完全なリポジトリを持ち、クライアントのコード履歴は完全ではありません。 git の各クライアントは完全なリポジトリであり、プッシュおよびプル操作は実際には複数の完全なリポジトリ間の同期です。
利点は、サーバーがハングアップしたり失われたりする心配がないことです。これは、Linus が Git を開発する出発点でもあります (Linux は、複数人での分散コラボレーションのためのオープンソース プロジェクトです)。欠点は、権限管理が比較的不十分であり、誰もが完全なリポジトリを持っているため、コード (履歴内のすべての変更) が誤って漏洩する可能性があることです。
最後に、うまく答えられる質問があります;
まず、質問の仮説について話しましょう:
C 6日目からリモートでのやり取りをやめて一人でプレイするようになりました。これは、ネットワークが利用可能であることを意味します。分散とは、数日経ってもリモートと同期しないことを意味するものではありません。
このファイルはGlobalFunction.php
という名前なので、Python のコード >setup と同様に、このファイルにはほとんど変更が必要ありません (または同じ行にほとんど変更がありません)。 .py では、新しいバージョンがリリースされたときにのみversion
変数を変更することがあります。GIT のブランチ概念についての私の個人的な理解は、1 つ以上のブランチに基づいてより迅速な共同開発を可能にするというものです。たとえば、ウェアハウス
foo
にはmaster
というブランチがあります。次に A 、B と C が共同開発を実行するとき、この共通ブランチmaster
に基づいてローカルにブランチします。たとえば、A のローカル ブランチはa-dev
と呼ばれます。 B はb-dev
と呼ばれ、C はc-dev
と呼ばれます。これはどのようにして生まれたのでしょうか?GlobalFunction.php
,那么这个文件就是修改极少的(或者说修改相同的一行是很少的),类似于Python下的setup.py
,有时只是到了新版本发布的时候你才会修改一下version
变量吧;GIT 的分支概念个人理解是可以更快速的基于某个或某些分支进行协作开发,比如一个仓库
foo
有一个 分支叫做:master
,那么 A,B,C 进行协同开发的时候会在本地基于这个共同的分支master
进行本地分支,比如 A 的本地分支叫a-dev
,B 的叫:b-dev
,C 的叫c-dev
,怎么来的呢?其次说一下题主说的合并:
如果 C 在本地基于
master
进行了本地分支c-dev
那么 C 一直可以更新本地 master 分支而不影响本地分支c-dev
(而此时你可以一直在c-dev
分支):那么把本地
master
更新了,怎么反应在c-dev
呢? 很简单,GIT 已经为你想好了:经过了上面,可能会发生的情况无非是两种:1. 出现合并冲突,
rebase
失败;2. 无冲突(可能会自动merge
),本地master
最新状况跟本地c-dev
合并;对于 1 的出现,GIT 不会自动搞定冲突,却可以尝试自动合并(
merge
),失败了,叫出现了冲突;出现了冲突一般是指不同的提交,修改了同一文件的同一行(几行)内容,需要开发者自己搞定冲突;个人总结
次に、質問者が言及した合併について話しましょう: C がmaster
に基づいてローカル ブランチc-dev
を作成すると、C はローカル ブランチc-dev >(現時点では、いつでも
c-dev
ブランチに留まることができます): リーリー それでは、ローカルのmaster
が更新された場合、それはc-dev
にどのように反映されるのでしょうか? それは簡単です。GIT がすでに考えてくれています: リーリー 上記を経た後、発生する可能性のある状況は 2 つだけです。 1. マージ競合が発生し、rebase
が失敗します。 2. 競合なし (自動的にmerge
が行われる可能性があります)。master
の最新ステータスはローカルのc-dev
とマージされます。 1 が発生した場合、GIT は競合を自動的に解決しませんが、自動的にマージ (merge
) を試みることができます。これが失敗すると、競合と呼ばれます。同じファイルの同じ行 (数行) の内容は開発者自身が解決する必要があります 個人的なまとめ Branch は他の集中バージョン管理システムとは異なる GIT のキラー機能 (killer feature
) であり、rebase
は GIT のキラー機能であり、GIT の優れた Branch 特性と切り離すことはできません。 ;競合が発生した場合、SVN は行ごとに比較しますが、Git は行の追加、行の削除、行の変更などの操作を記録するため、マージ プロセスが容易になります
あなたが指摘した問題はブランチを通じてのみ解決できます
簡単に言うと、自動的にマージできる場合とできない場合があります。
Git の各コミットは差分を保存します。コミットを git show して確認することができます。 diff は、元の変更された行の前後の数行の一致を試みます。一致する場合、diff は自動的にマージされます。
たとえば、C のパッチが 5 行目の値を変更した場合、そのパッチはコミットされません。 A と B は、GlobalFunction.php に新しい関数を追加しています。これらの関数は、C がマージするときに、チェリーピックを通じてマージを完了できます。
両方の当事者が同じ場所を変更した場合、競合を手動で解決する必要があります。