web-dev-qa-db-ja.com

SVNとGitのブランチの違いを理解する

私はSVNのユーザーですが、現在Gitを学習しています。

SVNでは通常、ローカルマシンでレポジトリをチェックアウトします。これには、プロジェクト内のすべてのブランチが含まれており、興味のあるブランチのフォルダーを選択してそこで作業していました。

Gitを使用すると違いがわかります。

現在、私はリポジトリのクローンを作成していて、gitkを使用して特定のブランチのクローンを作成しています。

プロジェクトフォルダーにはそのブランチのコンテンツのみが含まれており、SVNのようにすべてのブランチを表示することはできません。これは少し混乱します。

Gitを使用してローカルリポジトリのすべてのブランチを表示する簡単な方法が見つかりません。

  • 私が説明したGitプロセスが「標準」であるかどうか、そしてどれだけ正しいか、または何か不足しています。

  • また、マスターにホットフィックスを作成する必要があり、別のブランチのコンテンツも保持する必要がある場合など、2つのブランチを同時に処理する必要があるプロセスの処理方法についても知りたいです。

  • Gitのリポジトリからクローンされたブランチを含むフォルダーを作成するための推奨される名前の規則は何ですか、例myproject-branchname

47
Radex

私はSVNのユーザーですが、現在GITを学習しています。

ギャングへようこそ!

SVN再教育

SVNでは私は通常[...]

しばらくお待ちください。 CVSとSVN、および他の従来の(つまり、集中型)バージョン管理システムは、MercurialやGitなどの最新(つまり、分散)バージョン管理システムと(ほとんど)同じ目的を果たしますが、Gitをゼロから学習する方がはるかに優れています。 SVNワークフローをGitに転送しようとしています。

http://hginit.comarchive.orgのビュー )Joel Spolsky(Stack Exchangeの創設者の1人)は、GitではなくMercurialのチュートリアルです。 "Subversion Re-education" は、SVNから any 分散バージョン管理システムに切り替えるときに役立ちます。 (一時的に)n-learn(または stash away (Gitユーザーが言うように)に頭を回せるようにする必要があるSVNの概念分散バージョン管理システムの概念と、それらを操作するために確立された慣用的なワークフロー。

したがって、その0番目の章を読んで、ほとんどの場合、「Mercurial」という単語を「Git」に置き換えるだけで、Gitに向けて自分と心を適切に準備できます。

細字

(これは今のところスキップするかもしれません。) MercurialとGitはSVNよりもはるかに似ていますが、 /それらの違いのため、「Mercurial」を「Git」に置き換えると、「Subversion Re-education」のステートメントとアドバイスの一部が技術的に間違ってしまいます。

  • Mercurialはチェンジセットを内部的に追跡して保存しますが、GitはSubversionと同様に、リビジョン(つまり、ディレクトリツリーのコンテンツの状態)を内部的に追跡して保存します。 But Subversion 以外のGitは、関連する各ブランチと共通の祖先リビジョン(真の3ポイントマージ)の違いを確認してマージを実行します。したがって、結果はMercurialの場合とほとんど同じです。マージはSVNよりもはるかに簡単で、エラーが発生しにくくなります。
  • (Mercurialで慣例となっているように)リポジトリのクローンを作成することでGitで can ブランチを作成できますが、Gitリポジトリ内に新しいブランチを作成する方がはるかに一般的です。 (これは、Gitブランチがリビジョンへの単なる(移動)ポインタであるのに対し、Mercurialブランチはすべてのリビジョンに適用される永続的なラベルです。これらの永続的なラベルは通常望ましくないため、Mercurialワークフローは通常、開発を分岐するために完全なリポジトリを複製することによって機能します。)

SVNでは、すべてがディレクトリです(ただし、必ずしもそのように扱う必要はありません)。

しかし、私はあなたを邪魔してきました。あなたは言っていました?

SVNでは、通常、ローカルマシンでレポジトリをチェックアウトします。これには、プロジェクトのすべてのブランチが含まれ、以前は興味のあるブランチのフォルダーを選択してそこで作業していました。

それによって、SVNリポジトリのルートフォルダー(またはtrunkまたは単一のブランチに対応する他のフォルダー、たとえば従来のSVNリポジトリレイアウトでbranchesフォルダーにはすべての非トランクブランチが含まれています)、SVNを間違って使用している可能性があります。または、トランク、ブランチ、タグがすべて1つに折りたたまれていることを少し悪用しました(階層的ですが)。名前空間とディレクトリ within revisions/codebase。

いくつかのSVNブランチを並行して変更するのは魅力的かもしれませんが、それはSVNがどのように使用されることが意図されているかではなく、私の知る限りです。 (私はそのように機能する特定の不利な点が何であるかについてはわかりませんが。)

Gitでは、ディレクトリのみがディレクトリです

Gitリポジトリのすべてのクローンは、それ自体がGitリポジトリです。デフォルトでは、すべてのリビジョン、ブランチ、タグを含む、Originリポジトリの履歴の完全なコピーを取得します。ただし、Gitは、リポジトリのルートフォルダーの非表示.git/サブフォルダーにある、ファイルベースの一種のデータベースに保存します。

しかし、リポジトリフォルダに表示される非表示でないファイルは何ですか?

リポジトリをgit cloneすると、Gitはいくつかのことを行います。おおよそ:

  1. target folderを作成し、その中に「データベース」を含む.git/サブフォルダーを作成します
  2. Originリポジトリのデータベースのreferences(タグ、ブランチなど)を転送し、新しいデータベースにそれらのコピーを作成して、「リモート」参照としてマークするわずかに変更された名前を付けます。
  3. これらの参照が指すすべてのrevisions(つまり、ファイルツリーの状態)、およびこれらのリビジョンが直接または推移的に指すすべてのリビジョン(その親と祖先)を新しいデータベースに転送して保存します。新しいリモート参照は、実際には新しいリポジトリで利用可能なものを指します。
  4. Originリポジトリのデフォルトブランチ(通常はmaster)に対応するリモートリビジョンを追跡するローカルブランチを作成します。
  5. そのローカルブランチをチェックアウトします。

最後のステップは、Gitがこのブランチが指すリビジョンを検索し、そこに格納されているファイルツリーを解凍する(データベースは圧縮と重複排除のいくつかの手段を使用する)ことでリポジトリのルートフォルダーに展開することを意味します。そのルートフォルダーとそのすべてのサブフォルダー(特別な.gitサブフォルダーを除く)は、リポジトリの「作業用コピー」と呼ばれます。ここで、現在チェックアウトされているリビジョン/ブランチのコンテンツを操作します。それらは通常のフォルダとファイルです。ただし、リポジトリ自体(リビジョンと参照の「データベース」)と対話するには、gitコマンドを使用します。

Gitブランチの表示とGitブランチの操作

現在、私はリポジトリのクローンを作成し、gitkを使用して特定のブランチのクローンを作成しています。

gitk のバージョンでは、リポジトリのクローンを作成できません。リポジトリの履歴の表示、ブランチの作成、ブランチのチェックアウトのみが可能です。また、ブランチの「クローン」はありません。複製できるのはリポジトリのみです。

git clone ... を使用してリポジトリを複製し、次にgitkcheck outブランチを使用することを意味しましたか?

プロジェクトフォルダーにはそのブランチのコンテンツのみが含まれており、SVNのようにすべてのブランチを表示することはできません。これは少し混乱します。

[...]

  • 私が説明したgitプロセスが「標準」であるかどうかと、いくつかの方法が正しいことを知りたい[...]

はい、それはかなり標準的です:

  • git clone ...を使用してリポジトリを複製する
  • git checkout ... を使用するか、giktのようなグラフィカルツールを使用して、作業するブランチを確認してください

GITを使用してローカルリポジトリのすべてのブランチを表示する簡単な方法が見つかりません。

  • [...]または私はsmtがありません。

多分:

  • git branchでローカルブランチをリストできます
  • git branch -rでリモートブランチをリストするか、git branch -aですべてのブランチをリストできます
  • gitkを使用して、完全な履歴(ローカルリポジトリが認識しているすべてのブランチタグなど)を表示するには、

    gitk --all
    

複数のブランチを並行して操作する方法

  • また、マスターにホットフィックスを作成する必要があり、別のブランチのコンテンツも保持する必要がある場合など、2つのブランチを同時に処理する必要があるプロセスの処理方法についても知りたいです。

ここにはさまざまなシナリオがあります。

新しい(まだ作成されていない)変更を複数のブランチに適用する必要がある

このワークフローを使用してください:

  1. 新しいブランチcを、これらのすべてのブランチの祖先にあるリビジョン(たとえば、変更がバグ修正となるときにバグを導入したリビジョン)から、またはそのリビジョン(そのすべての祖先を含む)から作成します。これらすべてのブランチに導入することは許容されます。
  2. 新しいブランチcに変更を加えてコミットします。
  3. 変更が必要な各ブランチbについて:

    1. bをチェックしてください:

      git checkout b
      
    2. cbにマージ:

      git merge c
      
  4. ブランチを削除c

    git branch --delete c
    

別のブランチで既存の変更が必要です

(...しかし、その変更が存在する場所で行われた他の変更なし)

  1. 変更が必要なブランチをチェックしてください
  2. チェリーピック 変更を加えるリビジョンを順番に

あるブランチaで、1つまたはいくつかのファイルを別のブランチbの正確な状態に変更したい

  1. チェックa
  2. ブランチbからファイルの内容を取得します。

    git checkout b -- path/to/a/file.txt path/to/another/file.cpp or/even/a/complete/directory/ ...
    

    git checkout以外は、パスを渡さない場合、このブランチbに切り替えず、そこから要求されたファイルのコンテンツのみを取得します。これらのファイルは、 aにまだ存在していない可能性があります。存在する場合、bのコンテンツで上書きされます。)

あるブランチで作業しているときに、別のブランチでの状態を確認したい

作業したいブランチをチェックしてください。

次に、もう一方のブランチを見るために、

  • 現在チェックアウトされていないリビジョンの内容を表示できるグラフィカルツールを使用する(たとえば、gitkでラジオボタンを「パッチ」から「ツリー」に切り替えてみてください)
  • またはリポジトリを一時ディレクトリに複製し、そこにある他のブランチをチェックアウトします
  • または git worktree を使用して、同じリポジトリの別の作業ディレクトリを作成します(つまり、データベースの.git/ディレクトリにあるデータベースも使用します)現在のローカルリポジトリ)他のブランチをチェックアウトできます
69
das-g

SVNでは通常、ローカルマシンでレポジトリをチェックアウトします。これには、プロジェクト内のすべてのブランチが含まれており、興味のあるブランチのフォルダーを選択してそこで作業していました。

トランクの上のディレクトリをチェックアウトしない限り、Subversionでは通常notを実行して、すべてのブランチをローカルで使用できるようにします。 Gitでは、すべてのコンテンツ(コミット、メッセージ、ブランチなど)が常にすべてのコピーに複製されます。

現在、私はリポジトリのクローンを作成していて、gitkを使用して特定のブランチのクローンを作成しています。

不可能です。上記を参照してください。 git checkout branch-nameはできますが、git clone something branch-nameはできません。 Subversionでは、ブランチはフォルダです。 Gitでは、ブランチはコミットへのポインターです。

GITを使用してローカルリポジトリのすべてのブランチを表示する簡単な方法が見つかりません。

git branchを実行します。デフォルトでは、ローカルブランチのみが表示されます。リモートブランチを表示するには、git branch --remoteを使用します。

31
l0b0

これは git でタグ付けされているので、私のSVN知識の欠如が無視できることを願っています。

現在、私はリポジトリのクローンを作成し、gitkを使用して特定のブランチのクローンを作成しています。

特定のブランチだけでなく、リモートリポジトリ全体をクローンしています。

リポジトリはデータベースとして最適であると考えられるため、リモートデータベースの現在の状態のクローンを作成します。しかしその後は、そのデータベースの独自のコピーに取り組んでいます。コミットすると、ローカルデータベースが変更されます。

fetchコマンドは、ローカルデータベースとリモートデータベースの同期を維持するために使用されます。

通常、そのローカルデータベースから、作業するブランチをチェックアウトします。これは、現在の作業が始まったgitの内部マーカーのようなものではありません。

たとえば、master以外にブランチがない単純なリポジトリで作業している場合、.gitフォルダを調べて「マジック」を明らかにすることができます。

masterでの)最後のコミットが182e8220b404437b9e43eb78149d31af79040c66だったとすると、cat .git/refs/heads/masterの下に正確に表示されます。

新しいブランチgit checkout -b mybranchから分岐すると、ファイルcat .git/refs/heads/mybranchにまったく同じポインタが見つかります。

ブランチは「ポインタ」にすぎません。 「作動」マーカーはHEADと呼ばれます。

HEADの場所を知りたい場合:

cat .git/HEADと表示されます。 ref: refs/heads/mybranchは、コミットハッシュを指す(cat .git/refs/heads/mybranch78a8a6eb6f82eae21b156b68d553dd143c6d3e6f

実際のコミットはobjectsフォルダーに保存されます(独自のトピックの方法です)。

プロジェクトフォルダーにはそのブランチのコンテンツのみが含まれており、SVNのようにすべてのブランチを表示することはできません。これは少し混乱します。

working directoryと「git-database」全体を混同しないでください。上で述べたように、作業ディレクトリはサブセットの(たぶん)スナップショットにすぎません。

別のブランチがあるとすると、作業ディレクトリはそのブランチでの作業専用です(ただし、そこから作業を他の場所に置くこともできます)。

通常、プロジェクトに定義されているブランチを確認したい場合は、

  • git branch(ローカルブランチの場合)
  • git branch --remoteリモートブランチの場合
  • git branch -aの両方

(またはgit branch -v

Gitは分散バージョン管理システムであるため、ローカル/リモートで異なるブランチを作成することは可能であるだけでなく、推奨されます。

私の典型的なワークフローは:

  • 機能を分岐する
  • wIP(進行中の作業)のブランチ
  • 1行の後でコミットしたとしても、好きなように動作します。関係ない

機能が完了すると:

  • WIPブランチをスカッシュ/リワーク(インタラクティブなリベース付き)=そこから単一のコミットを作成
  • WIPブランチを機能ブランチにマージし、それを提供して(githubで作業している場合、そのオファーは「プルリクエスト」と呼ばれます)、安定した(マスター)ブランチに統合します。

また、たとえば、マスターでホットフィックスを作成する必要があるが、別のブランチのコンテンツも保持する必要がある場合に、2つのブランチで同時にwprlを実行する必要があるプロセスの処理方法を知りたいです。

プロジェクトの構造によって異なります。

あなたが安定したマスターを持っているとしましょう。また、機能はその安定したブランチからのみ開発されているため、通常は機能ブランチの背後にあります。次に、機能ブランチのルートになるマスターで最後のコミットを行います。

次に、マスターブランチにコミットし、両方のブランチをmergeするか、またはrebaseするかを決定できます(いわば高度なニーズを持つユーザーのための一種のマージです)。

または、いつでもブランチ(masterなど)を変更して、他のブランチにチェリーピックすることができます。

Myproject-branchnameの例のように、GITのリポジトリから複製されたブランチを含むフォルダーを作成するために推奨される名前の規則は何ですか

それはあなた次第です。

通常、最終的にリポジトリ名になります。

しかし、これが望まれない場合があります。

例えばgit clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zshを使用してoh-my-zshのクローンを作成します。ここでは、.oh-my-zshが明示的にターゲットとして指定されています。

3
Thomas Junk

Git cloneは実際にはリポジトリ全体を複製しますが、作業ディレクトリをデフォルト(通常はマスター)に設定します。

git branchを使用して他のブランチを表示し、ローカルブランチを表示したり、git branch -rを使用してリモートブランチを表示したり、git checkoutを使用して既存のブランチに切り替えたり、現在のブランチに基づいて新しいブランチを作成したりできます。

詳細についてはgitのドキュメントを読んでください。Atlassianにも優れた記事があります。

2
HorusKol

Gitとsvnのブランチは根本的に異なるものです。

Svnでは、ブランチ(またはタグ)はリポジトリ内のディレクトリです。

Gitでは、ブランチ(またはタグ)はコミットへのポインタです。

Svnでは、リポジトリのルートをチェックアウトしたい場合に使用できます。つまり、すべてのブランチとタグが一度にチェックアウトされます。これはsvnを使用する通常の方法ではありません。

Gitブランチはディレクトリではないため、「リポジトリのルートをチェックアウトする」ことに相当するものはありません。複数の作業ツリーのサポートがいくつかあるので、スクリプトをまとめてすべてのブランチを同時にチェックアウトすることもできます。

さらに、SVNを使用すると、リポジトリが1つだけ存在します。 gitでは、すべての開発者が独自のリポジトリを持っています。これは、開発者がオフラインで作業できることを意味しますが、開発者が異なれば、各ブランチの内容も異なる可能性があります。

ディレクトリであることとsvnの単純な線形履歴モデルのおかげで、svnブランチは堅牢な履歴を持っています。 y日にブランチxに何があったか知りたい場合は、簡単にその質問をすることができます。

一方、Gitブランチには実際に履歴はありません。 「reflog」はありますが、長期的な履歴というよりは、災害復旧メカニズムとして意図されています。特に、reflogはリモートで読み取ることができず、デフォルトでベアリポジトリに対して無効になっています。

もちろんコミットには履歴がありますが、それらの履歴は「日付zのリポジトリyのブランチxに何があったか」という質問に答えるには十分ではありません。

Gitを使用してローカルリポジトリのすべてのブランチを表示する簡単な方法が見つかりません。

「git branch」と入力すると、すべてのローカルブランチを一覧表示できます。

「git branch -a」を使用して、ローカルとリモートの両方のすべてのブランチを一覧表示できます

また、マスターにホットフィックスを作成する必要があり、別のブランチのコンテンツも保持する必要がある場合など、2つのブランチを同時に処理する必要があるプロセスの処理方法についても知りたいです。

いくつかのオプション。

「その他のブランチ」で変更をコミットし、マスターに切り替えて作業を行ってから、元に戻すことができます。

追加の作業ツリーを作成することもできます。構文の詳細については、Googleの「git-worktree」。

Myproject-branchnameの例のように、Gitのリポジトリからクローンされたブランチを含むフォルダーを作成するための推奨される命名規則は何ですか?

確立された慣習があるとは思いません。複数の作業ツリーを一度にチェックアウトすることは例外ではありません。

0
Peter Green