Gitのブランチ、フォーク、クローンの違いを理解したいですか?
同様に、私がやるとどういう意味ですか git fetch
ではなくgit pull
ですか?
また、何をしますか rebase
と比較どういう意味merge
ですか?
個々のコミットを一緒にスカッシュするにはどうすればよいですか?
それらはどのように使用され、なぜ使用され、何を表していますか?
GitHubはどのように機能しますか?
Gitのブランチ、フォーク、クローンの違いを理解したいですか?
同様に、私がやるとどういう意味ですか git fetch
ではなくgit pull
ですか?
また、何をしますか rebase
と比較どういう意味merge
ですか?
個々のコミットを一緒にスカッシュするにはどうすればよいですか?
それらはどのように使用され、なぜ使用され、何を表していますか?
GitHubはどのように機能しますか?
回答:
クローンは単にリポジトリのコピーです。表面的には、その結果はsvn checkout
、他のリポジトリからソースコードをダウンロードします。Subversionのような集中型VCSとGitのようなDVCSの違いは、Gitではクローンを作成すると、すべての履歴とブランチを含むソースリポジトリ全体が実際にコピーされることです。これで、マシンに新しいリポジトリが作成され、コミットはそのリポジトリに送られます。それらのコミットを別のリポジトリー(または元のリポジトリー)にプッシュするまで、またはリポジトリーが公にアクセス可能である場合は、誰かがリポジトリーからコミットをプルするまで、変更は誰にも表示されません。
ブランチは、リポジトリ内にあるものです。概念的には、開発のスレッドを表します。通常はマスターブランチがありますが、機能xyzとバグabcを修正する別のブランチに取り組んでいるブランチがある場合もあります。ブランチをチェックアウトすると、コミットはそのブランチに留まり、問題のブランチとマージまたはリベースするまで他のブランチと共有されません。もちろん、ブランチがどのように実装されるかについての基礎となるモデルを見るまで、Gitはブランチに関しては少し奇妙に見えます。自分で説明するのではなく(私はすでにあまりにも多く言ってきましたが)、Gitがブランチとコミットをモデル化する方法の「コンピューターサイエンス」の説明にリンクします。
http://eagain.net/articles/git-for-computer-scientists/
フォークは実際にはGitの概念ではなく、より政治的/社会的なアイデアです。つまり、プロジェクトの進行状況に満足できない人がいる場合は、ソースコードを取得して、元の開発者とは別に自分たちで作業できます。それはフォークと考えられます。誰もがソースコードの「マスター」コピーをすでに持っているため、Gitはフォークを簡単にします。そのため、元のプロジェクト開発者との関係を切断するのと同じくらい簡単で、SVNのように共有リポジトリから履歴をエクスポートする必要がありません。 。
編集:GitHubなどのサイトで使用されている「フォーク」の現代的な定義を認識していなかったので、コメントと詳細については、以下のマイケル・ダラントの回答をご覧ください。
この回答には、GitHubも含まれています。
Git(ローカル)には、.git
ファイルをコミットするディレクトリ()があり、これが「ローカルリポジトリ」です。これは、リモートリポジトリにすぐに追加してコミットするSVNなどのシステムとは異なります。
Gitは、ファイル全体を保存することで変更されるファイルの各バージョンを保存します。また、デルタの変更を通じて「再作成」せずに個々のバージョンに移動できるという点で、SVNとは異なります。
Gitはファイルをまったく「ロック」しないため、編集のための「排他ロック」機能を回避するため(pvcsなどの古いシステムが思い浮かびます)、オフラインのときでもすべてのファイルを常に編集できます。実際には、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
、単なるaではなく、常に手動でマージすることですgit pull
(1つのステップで上記の両方を実行します)。
新しいブランチを取得する:クローンの最初の時点では、すべてのブランチがあります。ただし、他の開発者がブランチを追加してリモートにプッシュする場合、それらをローカルにプルダウンできるようにするために、それらのブランチとその名前について「知る」方法が必要です。これはgit fetch
、追跡ブランチ(例:)を使用して、すべての新しいブランチと変更されたブランチをローカルリポジトリに取得するa を介して行われますorigin/
。一度fetch
編集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
リセットするのに非常に便利です。
毎日 'work-in-progress'としてコードをコミットするなど、多くの小さなステップで作業を行った場合、多くの小さなコミットをいくつかの大きなコミットに「つぶす」ことができます。これは、同僚とコードレビューを行う場合に特に役立ちます。(コミットを介して)実行したすべての「ステップ」を再生するのではなく、1回のコミットでこの作業に対するすべての変更の最終結果(diff)をここに示したいだけです。
これを行うかどうかを検討する際に評価する重要な要素は、複数のコミットが同じファイルまたは複数のファイルに対して行われるかどうかです(その場合は、コミットをスカッシュする方がよい)。これは、インタラクティブなリベースツールで行われます。このツールを使用すると、コミットを押しつぶしたり、コミットを削除したり、メッセージを書き換えたりすることができます。たとえば、git rebase -i HEAD~10
(注:はであり~
、はありません-
)以下が表示されます。
ただし注意して、このツールを「生々しく」使用してください。一度に1つのスカッシュ/削除/並べ替えを実行し、終了してそのコミットを保存してから、ツールを再入力します。コミットが連続していない場合は、それらを並べ替えることができます(その後、必要に応じてスカッシュします)。ここで実際にコミットを削除することもできますが、それを行うときは、本当に何をしているのかを確認する必要があります!
Gitリポジトリでのコラボレーションには、主に2つの方法があります。1つ目は、上記で詳述したように、人々がプルしたりプッシュしたりするブランチを介して直接行われます。これらの共同編集者は、リモートリポジトリに登録されたSSHキーを持っています。これにより、そのリポジトリに直接プッシュできます。欠点は、ユーザーのリストを維持する必要があることです。他のアプローチ-フォーク-では、誰でもリポジトリを「フォーク」して、基本的に自分のGitリポジトリアカウントにローカルコピーを作成できます。次に、変更を加え、完了したら「プル要求」を送信して(実際には、実際のリポジトリメンテナーに対する「プル」要求と「プル」要求のほうが多い)、コードを受け入れます。
フォークを使用するこの2番目の方法では、誰かがリポジトリのユーザーのリストを管理する必要はありません。
GitHub(リモートリポジトリ)は、そのようなリポジトリがある(または追加されている)場合に、コミットされた変更を通常プッシュおよびプルするリモートソースであるため、ローカルとリモートは実際にはかなり異なります。リモートリポジトリを考えるもう1つの方法は、リモートリポジトリが.git
ディレクトリ構造であることです。
「フォーク」するとき-GitHub WebブラウザーGUIでこのボタンをクリックできます -GitHubアカウントにコードのコピー(「クローン」)を作成します。初めて実行するときは少し微妙な場合があるので、コードベースがリストされているレポジトリ(元の所有者または「forked from」のいずれか)と、たとえば次のように確認してください。
ローカルコピーを取得したら、必要に応じて(ローカルマシンにプルしてプッシュすることにより)変更を加えることができます。完了したら、元のリポジトリ所有者/管理者に「プルリクエスト」を送信します(空想に聞こえますが、実際にはこれをクリックするだけです)。彼らはそれを「プル」します。
コードを共同で作業するチームでより一般的なのは、リポジトリを「複製」することです(リポジトリのメイン画面で「コピー」アイコンをクリックします)。次に、ローカルに入力git clone
して貼り付けます。これにより、ローカルでセットアップされ、(共有された)GitHubの場所にプッシュおよびプルすることもできます。
GitHubのセクションで示したように、クローンはリポジトリのコピーです。リモートリポジトリがある場合、git clone
そのURLに対してコマンドを発行すると、リポジトリのローカルコピーまたはクローンが作成されます。このクローンには、すべて、ファイル、マスターブランチ、その他のブランチ、すべての既存のコミット、シバン全体が含まれます。追加とコミットを行うのはこのクローンであり、リモートリポジトリ自体がそれらのコミットをプッシュします。SVN、PVCS、CVSなどの従来のCVS(コードバージョン管理システム)とは対照的に、Git(およびMercurialなどのそれに類似したシステム)をDVCS(分散バージョン管理システム)にするのは、このローカル/リモートの概念です。リモートリポジトリに直接コミットします。
コアコンセプトの視覚化は、
http://marklodato.github.com/visual-git-guide/index-en.htmlおよびhttp://ndpsoftware.com/git-cheatsheet.html#loc=indexで確認できます。
変更がどのように機能しているかを視覚的に表示したい場合、ビジュアルツールgitg
(gitx
macOSの場合)を、「地下鉄の地図」(ロンドン地下鉄など)と呼ぶ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/23JqqcLPss0
変更を加え、追加してコミットします(ただしプッシュしないでください)。あなたはあなたがマスターであることを理解しています!
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!
ローカルで変更を開始し、6ダースのファイルを編集してから、いや、まだマスター(または別の)ブランチにいます。
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
現在のブランチで特定のファイルを1つ台無しにして、基本的にそのファイルをリモートリポジトリから最後にプルしたときの状態に変更(変更を失う)したい場合:
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/10043を参照)。たとえば、
ブランチはselenium_rspec_conversion
です。
以下は、すべてがどのように組み合わされるかについてのオリバー・スティールのイメージです。
フォーク対。クローン-両方がコピーを意味する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')
フォーク
クローン
anidea
ます。OTOHジョーと合意に達しない場合は、フォークを開発して使用し続けることができます(後で彼に考えを変えさせることができるかどうかを確認してください)。
他の人に追加するために、フォークに固有のメモ。
技術的には、レポのクローンとレポのフォークは同じものであることを理解するのは良いことです。行う:
git clone $some_other_repo
自分の背中をたたくことができます---他のレポをフォークしたところです。
VCSとしてのGitは、実際にはすべてforkのクローン作成に関するものです。cgitなどのリモートUIを使用した「ブラウジング」以外に、フォークを含まないgit repoを使用することはほとんどありません。ある時点でレポのクローン。
しかしながら、
誰かが私がレポXをフォークしたと言うとき、彼らは公開する意図でレポのクローンをどこか他の場所に作成したことを意味しますするします、たとえば、いくつかの実験を示すため、または異なるアクセス制御メカニズムを適用するため(たとえば、 Githubへのアクセスが可能ですが、コラボレーションするために会社の内部アカウントが必要です)。
事実:レポはおそらく他のコマンドで作成されます
git clone
、誰かのラップトップではなくサーバーのどこかでホストされている可能性が高く、おそらく形式がわずかに異なる(「ベアリポジトリ」、つまり作業ツリーなし)技術的な詳細です。
おそらくブランチ、タグ、またはコミットの異なるセットが含まれているという事実が、おそらく最初にそれを行った理由です。
(「フォーク」をクリックしたときにGithubが実行するのは、追加された砂糖でクローンを作成することです。リポジトリをクローンし、アカウントの下に置き、「フォーク元」をどこかに記録し、リモートの「アップストリーム」という名前を追加します。最も重要なのは、素晴らしいアニメーションを再生します。)
私がリポジトリXのクローンを作成したと誰かが言ったとき、彼らは意図的にそれを研究し、それで遊んで、それに貢献し、またはその中のソースコードから何かを構築して、自分のラップトップまたはデスクトップでローカルにリポジトリのクローンを作成したことを意味します。
Gitの優れた点は、これがすべて完全に一致することです。これらのすべてのリポジトリは、ブロックコミットチェーンの共通部分を共有するため、これらのすべてのリポジトリ間で変更を安全に(下記の注を参照)マージして、適切に合わせることができます。
注:チェーンの共通部分を書き直さない限り、および変更が競合しない限り、「安全に」。