Gitリモートブランチとrefsファイルの詳細

18186 ワード

最近githubとgitcafeに同時にブログを同期し、いくつかの問題に遭遇しました.以下のいくつかの面に分けて分析します.

リモートブランチを同じサーバにプッシュ


例えばgitサーバをまず構築し、ついでにcloneから2つのコピーを出す
mkdir server cd server git init --bare cd .. git clone server git1 git clone server git2

現在git branchは空です.私たちはmasterブランチを構築するために何かを提出します.
cd git1 touch a.txt git add . git commit -m "init" git push origin master

git branch-aが表示されます.
* master remotes/origin/master

現在システムはmasterブランチにあり、リモートoriginのrepositoryにもmasterブランチがあります.二つはtrackingです.git 2の下にカットします
cd ../git2 git pull origin

このときgit 2はgit 1と完全に同期した.次に、別のブランチを作成し、サーバにプッシュしてみましょう.慣れてgit 1に戻ります
cd ../git1 git checkout -b source

この時点で、ローカルブランチがあります.このブランチが共有する必要がない場合は、このブランチにcommitしてもサーバにpushしないで、このブランチがプライマリブランチにマージされたり、破棄されたりすることができます.git branchは次のように表示されます.
 master * source

最終的に、このブランチpushをサーバ上で他の人と共有することにしました.以下のようにします.
git push origin source:source

このときgit branch-aは、2つのローカル、2つのリモート、ローカル、リモートを含む現在のrepository内のすべてのブランチを見ることができます.
 master * source remotes/origin/master remotes/origin/source

別のコピーにカットします.
cd ../git2 git pull origin

次のように表示されます.
 * [ ] source -> origin/source

git branch-aは、ローカルにリモートブランチのポインタがあることを示しますが、trackingというブランチのローカルブランチはありません.
* master remotes/origin/master remotes/origin/source

同じように私たちはgit/refs/remotes/originの下にブランチの名前が見えますが、refs/headsの下にはありません.このリモートブランチをチェックアウトします.
git checkout -b source origin/source

このときgit branch-a表示はgit 1と一致する.git 2ではsourceブランチを編集して同期することもできます.これらは比較的一般的な操作であり、マルチブランチのデフォルトのパラメータに注意する必要があります.たとえば、2つのブランチで何かを修正します.
cd ../git1 git checkout master //modify  git add . git commit -m "master modify" git checkout source //modify git add . git commit -m "source modify"

このときgit push originは現在のブランチに対するものであるため,2つのブランチが同時にpush更新できるのは
git push origin git checkout master git push origin

pull更新時
cd ../git2 git checkout master git pull origin

これは2つのブランチのポインタを同時に更新しますが、別のブランチはmergeしません.別のブランチの下に行きます.
git checkout source git pull origin

しかし、エラーは次のとおりです.
You asked to pull from the remote 'origin', but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line.

問題は、現在のブランチにmergeを構成するパスがなく、gitはどのブランチに行くか分からないことです.(trackingなら知らないはずないと思うけどね).
1.6.2以降のGitがある場合は、-trackオプションでmergeのパスを同時に構成できます.
git checkout --track origin/serverfix

ここでは、プロファイルを変更してbranch「source」に追加します.
[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true [remote "origin"] url = /media/cxh/backup/work/ceshi/git/server fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master" server refs/heads/master [branch "source"] remote = origin merge = refs/heads/source

これはfetch originのたびにすべてのremotes/originのヘッダポインタをrefs/heads/以下に更新し、具体的には行くことができることを意味する.gitの下でこのディレクトリを調べますが、ヘッダポインタはすべて読み取り専用です.mergeは、所在するbranchによって定義されます.
branch「source」の構成を追加し、現在のsourceのmergeポリシーをサーバ側のrefs/heads/sourceを使用して現在のブランチにマージすることを指定しました.これでスムーズなgit pull originができます.

リモートブランチを別のサーバにプッシュ


まず新しいrepoを構築します.
cd .. mkdir server2 cd server2 git init --bare

git 1コピーを追加し、コミット
git remote add server xxx/server2 git push server

上記の手順の本質は、refs/head/xxxをrefs/remotes/server/にコピーしてコミットすることに相当する現在のブランチヘッダポインタをserverにコミットすることです.git push serverは展開されます
git push server 

git 2コピーにもrepositoryを追加して参照を更新できます
git remote add server xxx/server2 git fetch server

refsの下のディレクトリ構造は次のとおりです.
├── heads    ├── master    └── source ├── remotes    ├── origin       ├── master       └── source    └── server    └── source └── tags

まとめてみる


update
  • fetch操作の本質は、repoによって指定されたリモートブランチのヘッダポインタ(server->refs/remotes/xxx/)
  • を更新することである.
  • mergeオペレーションの本質は、現在のブランチと指定されたヘッダポインタ(refs/remotes/xxx->refs/heads)
  • をマージすることである.
  • pull操作の本質はfetch+merge
  • である.

    commit
  • commitの本質は、現在のブランチのヘッダポインタ(refs/heads)
  • を修正することである.
  • push操作の本質は、現在の分岐ヘッダポインタをserverにコミットすることであり、ついでにローカルに格納されているserverヘッダポインタ(refs/remotes/xxx)
  • も修正する.

    checkout
  • ローカルブランチをコピーする本質は、refs/heads/下のヘッダポインタ
  • をコピーすることである.
  • pushローカルブランチserverの本質は、このヘッダポインタをサーバにアップロードすることであり、ついでにローカルに格納されたserverヘッダポインタ(refs/remotes/xxx)
  • をコピーすることである.
  • trackingリモートブランチの本質は、refs/remotes/下のポインタをrefs/heads下の
  • にコピーすることである.

    注意:上記の手順では、データ・ストリームは含まれていません.

    参考文献:


    [1]Gitブランチ–リモートブランチ、http://git-scm.com/book/zh/Git-%E5%88%86%E6%94%AF-%E8%BF%9C%E7%A8%8B%E5%88%86%E6%94%AF
    [2] The Configuration File – “Branch” Section, http://www.gitguys.com/topics/the-configuration-file-branch-section/
    著作権はCXH_ME所有、オリジナルは容易ではありませんて、人は难しくて写しませんて、転载してまた出典を明记して下さい、ありがとうございます