Gitのブランチ、フォーク、クローンの違いを理解したいのですが。
同様に、git fetch
とは対照的にgit pull
を実行するとどうなりますか?
また、rebase
はmerge
と比較してどういう意味ですか?
個々のコミットをまとめて潰すことができますか。
彼らはどのように使われているのか、なぜ使われているのか、そして何を表しているのか?
GitHubはどのように組み込まれているのですか?
クローンは単にリポジトリのコピーです。表面的には、その結果はsvn checkout
と同等です。ここで、他のリポジトリからソースコードをダウンロードします。 Subversionのような一元化されたVCSとGitのようなDVCSの違いは、Gitでは、クローンを作成するときに、実際にはすべての履歴とブランチを含むソースリポジトリ全体をコピーしているということです。これであなたはあなたのマシンに新しいリポジトリを作成し、あなたが行ったコミットはそのリポジトリに入ります。公にアクセス可能であれば、コミットを別のリポジトリ(または元のリポジトリ)にプッシュするか、誰かがコミットをコミットするまで、誰も変更を確認できません。
ブランチはリポジトリ内にあるものです。概念的には、それは開発のスレッドを表します。あなたは通常masterブランチを持っていますが、xyzやバグabcを修正するためにもう1つの機能に取り組んでいるブランチもあるかもしれません。ブランチをチェックアウトすると、コミットはそのブランチに残り、他のブランチとマージするか、問題のブランチにリベースするまで共有されません。もちろん、Gitは、ブランチがどのように実装されているかの基礎となるモデルを見るまで、ブランチに関してはちょっと変に思えます。それを自分で説明するのではなく(私がすでにあまりにも多く言ってしまったように、私は考えます)、GitのWebサイトから抜粋した、Gitモデルの分岐とコミットの仕方に関する「コンピュータサイエンス」の説明にリンクします。
http://eagain.net/articles/git-for-computer-scientists/
フォークはGitの概念ではなく、政治的/社会的な概念です。つまり、プロジェクトの進行状況に満足できない人がいる場合は、元の開発者とは別にソースコードを受け取って作業することができます。それはフォークと見なされます。 Gitは、誰もが自分自身のソースコードの「マスター」コピーをすでに持っているので、フォークを簡単にします。そのため、元のプロジェクト開発者との結びつきを減らすのと同じくらい簡単です。SVNのように共有リポジトリから履歴をエクスポートする必要はありません。 。
編集:私はGitHubのようなサイトで使用されているような "フォーク"の現代の定義を知らなかったので、コメントを見てくださいまた詳細については私の下の マイケルデュラントの答え 。
この回答には、多くの人々がそれについても質問しているように、GitHubが含まれています。
Git(ローカル)には、ファイルをコミットするディレクトリ(.git
)があり、これが「ローカルリポジトリ」です。これは、リモートリポジトリにすぐに追加してコミットするSVNなどのシステムとは異なります。
Gitは、ファイル全体を保存することで変更されるファイルの各バージョンを保存します。また、デルタの変更によって「再作成」せずに個々のバージョンに移動できるため、この点でもSVNとは異なります。
Gitはファイルをまったく「ロック」せず、編集の「排他的ロック」機能を回避します(PVCのような古いシステムが頭に浮かぶため)、オフラインでもすべてのファイルを常に編集できます。実際には、GitHubなどのリモートリポジトリへのプルまたはフェッチ/プッシュ中に、(同じファイル内で)ファイルの変更をマージするという驚くべき仕事をします。手動で変更(実際にファイルを編集)する必要があるのは、2つの変更に同じコード行が関係している場合だけです。
ブランチを使用すると、メインコード(「マスター」ブランチ)を保持し、コピー(新しいブランチ)を作成して、その新しいブランチ内で作業できます。作業に時間がかかる場合、またはブランチが作成されてからマスターが多くの更新を取得した場合、マスターブランチに対するマージまたはリベース(多くの場合、より良い履歴と競合の解決が容易なため)を行う必要があります。終了したら、ブランチで行った変更をマスターリポジトリにマージします。多くの組織では、機能、バグ、または雑用アイテムに関係なく、作業ごとにブランチを使用しています。他の組織では、バージョンアップグレードなどの主要な変更にのみブランチを使用しています。
分岐:分岐では分岐を制御および管理しますが、分岐では他の誰かがコードの受け入れを制御します。
大まかに言えば、分岐を行うには2つの主なアプローチがあります。 1つ目は、マスターブランチでほとんどの変更を保持することです。バージョンの変更のように、異なるニーズに応じて2つのブランチを使用できるようにする、より大きく長時間実行するブランチのみを使用します。 2つ目は、基本的に、すべての機能要求、バグ修正、または雑用ごとにブランチを作成し、それらのブランチを実際にメインマスターブランチにマージするタイミングを手動で決定することです。これは退屈に聞こえますが、これは一般的なアプローチであり、マスターブランチをよりクリーンに保ち、プロダクションに昇格させるマスターであるため、現在使用および推奨しているアプローチです。ブランチのマージ。
ブランチをマスターに「取り込む」ための標準的な方法は、merge
を実行することです。ブランチは、履歴を「クリーンアップ」するために「リベース」することもできます。現在の状態には影響せず、「よりクリーンな」履歴を提供するために行われます。
基本的には、特定のポイント(通常はマスター)から分岐するという考え方です。あなたが分岐したので、「マスター」自体はその分岐点から前進しました。ブランチで行ったすべての変更が、すべての最新の変更を含む現在のマスターの状態に対して実行される場合、「クリーン」になります(問題の解決が容易になり、履歴が理解しやすくなります)。そのため、プロセスは次のとおりです。変更を保存します。 「新しい」マスターを取得してから、その変更を再度適用します(これがリベース部分です)。マージと同様に、リベースは競合を引き起こす可能性があることに注意してください。競合は手動で解決する必要があります(つまり、編集と修正)。
注意すべき1つのガイドライン:
ブランチがローカルで、まだリモートにプッシュしていない場合のみリベースします!
これは主に、リベースにより、他の人が見る履歴に変更を加えることができるためです。
これらは、Origin/branch_name
という名前のブランチです(単にbranch_name
とは対照的です)。コードをリモートリポジトリにプッシュしたり、リモートリポジトリからプルしたりするとき、これが実際にそれが起こるメカニズムです。たとえば、git Push
というブランチをbuilding_groups
という名前にすると、ブランチは最初にOrigin/building_groups
に移動し、次にリモートリポジトリに移動します。同様に、git fetch building_groups
を実行すると、取得されたファイルはOrigin/building_groups
ブランチに配置されます。その後、このブランチをローカルコピーにマージすることを選択できます。私たちのプラクティスは、git fetch
(上記の両方を1ステップで行う)ではなく、常にgit pull
と手動マージを行うことです。
新しいブランチの取得:クローンの最初の時点では、すべてのブランチがあります。ただし、他の開発者がブランチを追加してリモートにプッシュする場合、それらをローカルにプルダウンできるようにするために、それらのブランチとその名前を「知る」方法が必要です。これは、git fetch
を介して行われます。これは、追跡ブランチを使用して、すべての新規および変更されたブランチをローカルリポジトリに取得します(例:Origin/
)。 fetch
edになったら、git branch --remote
で追跡ブランチをリストし、git checkout [branch]
で実際に任意のブランチに切り替えることができます。
マージとは、異なるブランチまたは同じブランチの異なるバージョンからのコード変更を結合するプロセスです(たとえば、ローカルブランチとリモートが同期していない場合)。ブランチで作業を開発し、作業が完了し、準備ができてテストされている場合、それをmaster
ブランチにマージできます。これはgit checkout master
によって行われ、master
ブランチに切り替えてからgit merge your_branch
に切り替えます。マージにより、すべての異なるファイルと同じファイルに対する異なる変更がまとめられます。これは、ファイル内のコードを実際に変更して、すべての変更をマージすることを意味します。
checkout
のmaster
を実行するときは、git pull Origin master
を実行して、最新バージョンのリモートマスターをローカルマスターにマージすることもお勧めします。リモートマスターが変更された場合、つまりmoved forward
の場合、そのgit pull
の間にそれを反映する情報が表示されます。その場合(マスターが変更された場合)、マスターにgit checkout your_branch
してからrebase
することをお勧めします。これにより、変更が実際に「新しい」マスターの上で「リプレイ」されます。次に、次の段落に示すように、マスターを最新の状態に保ちます。
競合がない場合、マスターは新しい変更を追加します。競合がある場合、これは同じファイルが自動的にマージできない同様のコード行の周りに変更があることを意味します。この場合、git merge new_branch
は、解決すべき競合があることを報告します。ファイル(両方の変更が含まれる)を編集し、必要な変更を選択し、不要な変更の行を文字通り削除してからファイルを保存することにより、それらを「解決」します。変更には、========
や<<<<<<<<
などの区切り記号が付いています。
競合を解決したら、git add
とgit commit
の変更をもう一度実行して、マージを続行します(このプロセス中にgitからフィードバックが得られます)。
プロセスがうまく機能しない場合、git merge --abort
がリセットに非常に便利であることがわかります。
たとえば、毎日「進行中の作業」としてコードをコミットするなど、多くの小さなステップで作業を行った場合、それらの多くの小さなコミットをいくつかの大きなコミットに「押しつぶす」ことができます。これは、同僚とコードレビューを行いたい場合に特に役立ちます。 (コミットを介して)行ったすべての「ステップ」を再生したくはありません。ここで、この作業に対するすべての変更の最終的な効果(diff)を1つのコミットで言いたいだけです。
これを行うかどうかを検討する際に評価する重要な要素は、複数のコミットが同じファイルまたは複数のファイルに対するものであるかどうかです(その場合、コミットを無効にする)。これは、インタラクティブなリベースツールを使用して行われます。このツールを使用すると、コミットのスカッシュ、コミットの削除、メッセージの書き換えなどを行うことができます。たとえば、git rebase -i HEAD~10
(注:~
ではなく-
です)次を表示します:
ただし、このツールは「生々しく」使用してください。一度に1つのスカッシュ/削除/並べ替えを行い、終了してそのコミットを保存してから、ツールを再入力してください。コミットが連続していない場合は、順序を変更できます(必要に応じてスカッシュします)。ここで実際にコミットを削除することもできますが、それを行うときには、実際に何をしているかを確認する必要があります!
Gitリポジトリでのコラボレーションには、主に2つのアプローチがあります。上記の詳細な最初の方法は、人々がプルしたりプッシュしたりするブランチを介して直接行われます。これらの共同作業者は、リモートリポジトリにSSHキーを登録しています。これにより、そのリポジトリに直接プッシュできるようになります。欠点は、ユーザーのリストを維持する必要があることです。他のアプローチ-フォーク-誰でもリポジトリを「フォーク」できます。基本的に、自分のGitリポジトリアカウントにローカルコピーを作成します。その後、変更を加えて、「プルリクエスト」(実際には、それらからの「プッシュ」と実際のリポジトリメンテナーに対する「プル」リクエスト)を送信して、コードを受け入れます。
フォークを使用するこの2番目の方法では、notはリポジトリのユーザーのリストを管理する必要があります。
GitHub(リモートリポジトリ)は、このようなリポジトリを持っている(または追加されている)場合、通常、コミットされた変更をプッシュおよびプルするリモートソースです。したがって、ローカルとリモートは実際にはまったく異なります。リモートリポジトリを考えるもう1つの方法は、リモートサーバー上にある.git
ディレクトリ構造です。
「フォーク」すると、GitHub WebブラウザーGUIでこのボタンをクリックできます -yourGitHubアカウントにコードのコピー(「クローン」)を作成します。最初にやるのは少し微妙かもしれませんので、コードベースがリストされているリポジトリを確認してください-元の所有者または「fork from」のいずれかで、次のようになります:
ローカルコピーを取得したら、必要に応じて変更を行うことができます(ローカルマシンにプルアンドプッシュすることにより)。完了したら、元のリポジトリの所有者/管理者に「プルリクエスト」を送信します(派手に聞こえますが、実際にはこれをクリックするだけです: )そして、彼らはそれを「プル」します。
コードを一緒に作業するチームにとってより一般的なのは、リポジトリの「クローン」です(リポジトリのメイン画面の「コピー」アイコンをクリックします)。次に、ローカルでgit clone
と入力して貼り付けます。これにより、ローカルにセットアップされ、(共有)GitHubロケーションにプッシュおよびプルすることもできます。
GitHubのセクションで示したように、クローンはリポジトリのコピーです。リモートリポジトリがある場合、そのURLに対してgit clone
コマンドを発行すると、リポジトリのローカルコピーまたはクローンが作成されます。このクローンには、everything、ファイル、masterブランチ、他のブランチ、既存のすべてのコミット、Shebang全体が含まれます。追加とコミットを行うのはこのクローンであり、リモートリポジトリ自体がこれらのコミットのプッシュ先です。 Git(およびMercurialなどのそれに類似したシステム)をDVCS(Distributedバージョン管理システム)にするのは、このローカル/リモートの概念ですSVN、PVCS、CVSなど、リモートリポジトリに直接コミットする従来のCVS(コードバージョン管理システム)。
コアコンセプトの視覚化については、
http://marklodato.github.com/visual-git-guide/index-en.html および
http://ndpsoftware.com/git-cheatsheet.html#loc=index
変更がどのように機能しているかを視覚的に表示したい場合は、視覚ツールgitg
(macOSの場合はgitx
)を、私が「地下鉄マップ」と呼ぶGUI(特にロンドン)で打ち負かすことはできません地下)、誰が何をしたか、物事がどのように変化し、分岐し、合併したかなどを示すのに最適.
また、それを使用して、変更を追加、コミット、および管理することもできます!
Gitg/gitxはごくわずかですが、GUIツールの数は増え続けています。多くのMacユーザーは、brotherbardのgitxフォークを使用します。Linuxの場合、優れたオプションは、直感的で強力なインターフェースを備えたsmart-gitです。
GUIツールを使用しても、コマンドラインで多くのコマンドを実行することに注意してください。
このため、~/.bash_aliases
ファイルには次のエイリアスがあります(各ターミナルセッションの~/.bashrc
ファイルから呼び出されます)。
# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias Gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard Origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git Push '
そして、私は~/.gitconfig
ファイルに以下の「gitエイリアス」を持っています-なぜこれらがあるのですか?
そのため、ブランチ補完(TABキーを使用)が機能します!
これらは次のとおりです。
[alias]
co = checkout
cob = checkout -b
使用例:git co [branch]
<-ブランチのタブ補完が機能します。
https://learngitbranching.js.org/ は、いくつかの基本概念を学習するのに役立ちます。スクリーンショット:
ビデオ: https://youtu.be/23JqqcLPss
変更を加え、それらを追加してコミットします(ただし、プッシュしないでください)。マスターにいることに気づきます!
git reset [filename(s)]
git checkout -b [name_for_a_new_branch]
git add [file(s)]
git commit -m "A useful message"
Voila! You've moved that 'master' commit to its own branch !
ローカルブランチで作業しているときにいくつかのファイルを台無しにして、最後にgit pull
を実行したときの状態に戻りたい場合:
git reset --hard Origin/master # You will need to be comfortable doing this!
ローカルで変更を開始し、半ダースのファイルを編集した後、マスター(または別の)ブランチにいます:
git checkout -b new_branch_name # just create a new branch
git add . # add the changes files
git commit -m"your message" # and commit them
現在のブランチで特定のファイルを台無しにして、そのファイルをリモートリポジトリから最後にプルしたときの状態に基本的に「リセット」(変更を失います)したい場合:
git checkout your/directories/filename
これにより、実際にファイルがリセットされます(多くのGitコマンドと同様に、ここで実行していることにちなんで名前が付けられていません)。
いくつかの変更をローカルで行い、git reset
またはrebase
を実行している間、それらが失われないようにしたい:プロジェクト全体の手動コピーを作成することが多い(cp -r ../my_project ~/
) Gitを台無しにするのか、重要な変更を失うのかわからないとき。
あなたはリベースしていますが、物事は台無しになります:
git rebase --abort # To abandon interactive rebase and merge issues
GitブランチをPS1
プロンプトに追加します( https://unix.stackexchange.com/a/127800/1004 を参照)。
ブランチはSelenium_rspec_conversion
です。
これがOliver Steeleのイメージです。
フォーク対。クローン - 両方ともコピーを意味する2つの単語
この 図を見てください。 (もともと http://www.dataschool.io/content/images/2014/Mar/github1.png から)。
.-------------------------. 1. Fork .-------------------------.
| Your GitHub repo | <-------------- | Joe's GitHub repo |
| github.com/you/coolgame | | github.com/joe/coolgame |
| ----------------------- | 7. Pull Request | ----------------------- |
| master -> c224ff7 | --------------> | master -> c224ff7 (c) |
| anidea -> 884faa1 (a) | | anidea -> 884faa1 (b) |
'-------------------------' '-------------------------'
| ^
| 2. Clone |
| |
| |
| |
| |
| | 6. Push (anidea => Origin/anidea)
v |
.-------------------------.
| Your computer | 3. Create branch 'anidea'
| $HOME/coolgame |
| ----------------------- | 4. Update a file
| master -> c224ff7 |
| anidea -> 884faa1 | 5. Commit (to 'anidea')
'-------------------------'
(a) - after you have pushed it
(b) - after Joe has accepted it
(c) - eventually Joe might merge 'anidea' (make 'master -> 884faa1')
フォーク
クローン
他の人に追加するために、フォークに固有の注意事項。
技術的には、リポジトリのクローン作成とリポジトリのフォークは同じことであることを認識しておくのは良いことです。行う:
git clone $some_other_repo
そしてあなたは後ろをタップすることができます---あなたはちょうど他のレポを二分したところです。
Gitは、VCSとして、実際のところすべてです。 クローニング フォークcgitのようなリモートUIを使って「ただブラウズする」こととは別に、関与しないgitリポジトリにはほとんど関係がありません。 フォーク ある時点でレポジトリを複製する。
しかしながら、
誰かが私がリポジトリXをフォークしたと言うとき、彼らは公開することを意図してどこかにリポジトリのクローンを作成したことを意味します。 他の人に、たとえばいくつかの実験を見せるため、または異なるアクセス制御メカニズムを適用するため(たとえば、Githubにアクセスできないが社内のアカウントを持つ人々が共同作業できるようにするため)。
事実:リポジトリはたぶんgit clone
以外のコマンドで作成され、誰かのラップトップとは対照的にサーバー上のどこかにホストされ、そして多少異なるフォーマットを持つ(それは "裸のリポジトリ"、すなわち作業ツリーなし) )すべて技術的な詳細です。
おそらくそれがブランチ、タグ、またはコミットの異なるセットを含んでいるという事実は、おそらく彼らがそもそもそれをやった理由です。
(Githubが[fork]をクリックしたときに実行するのは、単に砂糖を追加してクローンを作成することです。リポジトリを複製し、自分のアカウントに配置し、 "fork from"をどこかに記録し、 "upstream"という名前のリモートを追加します。 Niceアニメーションを再生します。)
誰かが私がリポジトリXをクローンしたと言うとき、彼らは意図的にそれを研究して彼らのラップトップまたはデスクトップにローカルにリポジトリのクローンを作成したことを意味します。それに貢献する、あるいはその中のソースコードから何かを構築する。
Gitの長所は、これがすべて完璧にフィットすることです。 ブロック チェインをコミットするので、安全に(下記の注を参照)、必要に応じてこれらすべてのリポジトリ間で変更を前後にマージすることができます。
注:チェーンの共通部分を書き換えない限り、そして変更が矛盾しない限り、「安全に」。