リポジトリをフェッチした後に作成されたリモートブランチについてgit-svnにどのように通知しますか?


193

私はgit-svn会社の中央のSubversionリポジトリに対して作業するために使用しています。最近、セントラルリポジトリに新しい機能ブランチを作成しました。

Gitにそれを伝えるにはどうすればよいですか?実行すると、Subversionリポジトリに対してgit branch -r実行fetchしてGitリポジトリを初期化したときに存在していたブランチしか表示されません。


ここからの回答:stackoverflow.com/questions/13376917/…も役立つでしょう。
Tomasz Gandor

回答:


294

リモートブランチを手動で追加できます。

git config --add svn-remote.newbranch.url https://svn/path_to_newbranch/
git config --add svn-remote.newbranch.fetch :refs/remotes/newbranch
git svn fetch newbranch [-r<rev>]
git checkout -b local-newbranch -t newbranch
git svn rebase newbranch

3
このリンクを参照としてドキュメントに追加するだけですkernel.org/pub/software/scm/git/docs/git-svn.html
slf

1
.git / configから、単一または複数のリポジトリからリモートブランチを構成する方法を理解するのは非常に簡単です。
ミカエルレピスト

6
もしこれを8回くらい賛成できれば、そうします。最後に、非標準の場所に追加されるsvnブランチを追加する方法!
Tim Keating

7
fatal: Cannot setup tracking information; starting point 'newbranch' is not a branch.はgitチェックアウトのステップに進みます。
phpguru

17
@phpguru -tオプションフラグを削除して「git checkout -b local-newbranch newbranch」になるようにして、リモートのプレフィックスをne​​wbranchに含めることを忘れないでください(例:origin / newbranch)。
mj1531 2014年

96

すべてのリモートsvnブランチを追跡する場合、解決策は次のように簡単です。

git svn fetch

これにより、まだフェッチされていないすべてのリモートブランチがフェッチされます。

追加のヒント:最初にトランクのみをチェックアウトし、後ですべてのブランチを追跡する場合は、次の.git/configように編集して再実行しますgit svn fetch

[svn-remote "svn"]
        url = https://svn/path_to_repo_root/
        fetch = path_to_trunk:refs/remotes/git-svn
        branches = path_to_branches/*:refs/remotes/*

重要な点はurl、リポジトリのルートを指す必要があり、で定義されているパスはfetchからのbranches相対パスである必要がありますurl

ALLではなく特定のブランチのみをフェッチしたい場合は、次の例をご覧git svn --helpください。

[svn-remote "huge-project"]
        url = http://server.org/svn
        fetch = trunk/src:refs/remotes/trunk
        branches = branches/{red,green}/src:refs/remotes/branches/*
        tags = tags/{1.0,2.0}/src:refs/remotes/tags/*

古いバージョンのではgit-svn、このようにブランチを指定すると、で新しいブランチを取得できない場合がありますgit svn fetch。1つの回避策はfetch、次のように行を追加することです。

[svn-remote "huge-project"]
        url = http://server.org/svn
        fetch = trunk/src:refs/remotes/trunk
        fetch = branches/blue:refs/remotes/branches/blue
        fetch = branches/yellow:refs/remotes/branches/yellow
        branches = branches/{red,green}/src:refs/remotes/branches/*

別の@AndyEstesによって回避策:編集.git/svn/.metadataや変更の値branches-maxRevまたはtags-maxRev任意の新たに指定された枝やタグの前のリビジョンには作成されました。これを実行git svn fetchしたら、実行して新しいsvnリモートブランチを追跡します。


1
これらの設定を設定する前に、svnブランチを実行したリビジョンをすでにフェッチしている場合は、git svn resetを実行することをお勧めします。
kcm1700

3
編集.git/svn/.metadataはとても役に立ちました!メタデータのリビジョン番号が「あまりにも先だった」ため、私はに追加のブランチを追加していましたが.git/config、それgit svn fetchは受け入れられませんでした。あるケースでは、ブランチからの最後のコミットのみがフェッチされました。私は手動で問題のあるブランチを削除しました(名前.git/svn/refs/remotes/svn/qa/XYZ.git/svn/refs/remotes/svn/qa/XYZ~に変更された、その存在をにドロップした.git/packed-refsなど)...メタデータの「以前の」リビジョン番号を選択しました...実行さgit svn fetchれて、最終的に、正しい接続グラフを含む完全な履歴が取得されました。
starlocke 2013

8
これは受け入れられた回答でなければなりません!@janos、あなたは私に頭痛の時間を節約しただけです!インドに来たらビールを飲みに行きます!
Roopesh Shenoy 2013

1
または:git svn fetch --all
ケノーブ2015年

1
この答えは驚くべきものです。なぜなら、私が答えを見つけることができなかった7つの質問に答えるものであり、6ページの説明を書かなくてもそうであるからです。
Droj

53

必要なのはgit svn fetch; どういうわけか私は変更だけでなくリポジトリ全体を取得するだろうと自分自身を確信していました。


7
@mitjakそれが解決策である場合、なぜそれが正しい答えではないのですか?微妙な対応がわかりません。
rholmes

「解決策」は「解決策」ではないかもしれません
slf

1
@rholmes:mitjakが問題の解決策であることは確かだと思いますが、質問への回答ではありません。(間違った質問をしたため、その時点で問題を誤って解釈したため。)
Mike Nelson

これは、svnリポジトリをgitに複製したときにブランチが存在していた場合に機能します。svnリポジトリのブランチが後で作成された場合は機能しません。
Petr Gladkikh 2012年

3
クローンの後にブランチが作成されたときは正常に動作しますが、私は常にそれを行います。
Tim Gautier

15

多分私はそれをなんとか台無しにしたが、私はvjangusの答えの指示に従い、それはほとんどうまくいった。唯一の問題は、newbranchがトランクから分岐しているように見えないことでした。gitkでは、それ自体が一種の「フローティング」でした。幹と共通の祖先はありませんでした。

これに対する解決策は:

  1. ブランチが作成される前にトランクで発生した最後のコミットのSHA1を見つけます。
  2. 新しいブランチで最初のコミットのSHA1を見つけます(メッセージはおそらく「Created new branch、copy from trunk @ 12345」など)
  3. git diff-tree <sha1 from step 1> <sha1 from step 2>-出力はありません。出力がある場合は、間違ったコミットを選択した可能性があります。
  4. git checkout local-newbranchその後git rebase <sha1 from step 1>。これはlocal-newbranch新しいツリーにリベースしますが、remotes/newbranchそれでも切断されます。
  5. ファイルに移動し、.git/refs/remotes/newbranch編集して、現在指している古いコミットに対応する(リベースの)新しいコミットの完全なSHA1を含めnewbranchます。(または多分使用しますgit-update-ref refs/remotes/newbranch <new-SHA>。ありがとうございます。)
  6. あなたは次の時間git svn dcommitにはnewbranch、あなたはそれがいくつかのログを更新に関するメッセージの束を取得します。これは普通だと思います。

私はgitk --allあなたが何をしているかを追跡するために、常に開いたままにし、頻繁に更新することをお勧めします。私はまだgitとgit svnの初心者なので、この方法の改善を提案してください。


2
ありがとう、これは便利に聞こえます。約5.おそらく 'git-update-ref refs / remotes / newbranch <new-SHA>'がより安全なオプションです。
歌手2011年

vjangusの方法をもう一度試したところ、完全に機能しました。これは誰かにとって価値があるかもしれないので、とにかくここに置いておきます...
MatrixFrog

1
vjangusソリューションは、常にトランクから切断された新しいブランチを作成します。これは、SVN自体が実際のコンテンツがどのようにコピーされるかについての手がかりがないためだと思います。
bogdan.mustiata 2011

大規模なgit-svnリポジトリでの私の経験では、svnブランチは常にトランクから切り離されたgitで作成されます。それらを接続するいくつかの方法があるはずですが、私はそれを理解するための時間を割いていません。私の知る限り、svnブランチに接続されているgitブランチをリベースすることはできません。これは、dcommitロジックを台無しにするためです。私たちはそれとともに生きることを学びました。
スペンサー、

7

vjangusの答えの簡略化:

SVNで標準レイアウトを使用していて、通常のsvn initを実行している場合は、git-svnが設定を行います。ただ:

  1. SVNでブランチコピーリビジョンを見つける
  2. git-svnでそのリビジョンを取得します
  3. 新しいローカルブランチトラッキングリモートを作成する

例。SVN URLはsvn+ssh://gil@svn.myplace.com/repoです。私が探しているSVNブランチはですnewbranch。ローカルgitブランチ(リモート追跡newbranch)はになりますgit-newbranch

手順1:ブランチコピーのリビジョンを見つける

    #は--stop・オン・コピーログのsvnのsvn + sshを://gil@svn.myplace.com/repo/branches/newbranchを| 尾-4
    r7802 | 誰か| 2014-03-21 18:54:58 +0000(2014年3月21日金曜日)| 1行

    HEADからnewbranchへの分岐
    -------------------------------------------------- ----------------------

したがって、SVNの分岐点はリビジョン7802です。

ステップ2:リビジョンを取得する

gitのSVN 7802 -rフェッチ
    可能な分岐点が見つかりました:svn + ssh://gil@svn.myplace.com/repo/trunk => svn + ssh://gil@svn.myplace.com/repo/branches/newbranch、7801
    ブランチの親が見つかりました:(refs / remotes / trunk)8dcf3c5793ff1a8a79dc94d268c91c2bf388894a
    do_switchで親をフォロー
    親のフォローに成功しました
    r7802 = 9bbd4194041675ca5c9c6f3917e05ca5654a8a1e(refs / remotes / newbranch)

git-svnがすべての作業を行い、リモートについて認識しています。

    #git show-ref | grep newbranch
    2df23af4733f36f5ad3c14cc1fa582ceeb3edb5c refs / remotes / newbranch

ステップ3:リモートブランチを追跡する新しいローカルブランチを作成します。

gitのチェックアウト-bのgit-newbranch -t newbranch
    ファイルのチェックアウト:100%(413/413)、完了。
    ローカルref refs / remotes / newbranchを追跡するために設定されたブランチgit-newbranch。
    新しいブランチ「git-newbranch」に切り替えました

これをたどることで、ようやく理解することができました(show-refとても貴重です)誤ってリモートブランチを参照することで立ち往生している人は、それらを削除して(私はgit branch -d newbranchref dirを強制的に削除する必要がありました.git/svn/refs/remotes/newbranch)、ステップ2(上記)からやり直すことができます。
tutuDajuju 2014

5

この機能に関するドキュメントは見つかりませんでしたが、git svn configurationが複数のフェッチエントリをサポートしているようです。このようにして、別のリモートsvnリポジトリエントリを設定に追加したり、ワイルドカードを使用して特定のディレクトリのすべてのブランチを取得したりすることなく、ブランチを個別に追加することもできます。

あなたのSVNツリーは、それらがどのように配置されているかのロジックなしに、たくさんのブランチを持っている、本当に厄介であると仮定します。例えば、ブランチとより多くのブランチを含むサブディレクトリを持っています。

すなわち

trunk
branches
  -> branch1
  -> sub-dir1
    -> branch2
    -> branch3
  -> sub-dir2
    -> branch4
    -> sub-dir3
      -> branchX 
<... hundreds more ...>

gitリポジトリに含めるブランチの一部を手動で選択したいだけです。

最初に、追加のブランチなしでトランクのみを使用してリポジトリを初期化できます。

git svn clone -r 10000:HEAD https://svn.com/MyRepo myrepo --prefix=svn/ --trunk=trunk 

その後、次の構成が表示されます。

localhost: elhigu$ git config --get-regexp "svn-remote."
svn-remote.svn.url https://svn.com/MyRepo
svn-remote.svn.fetch trunk:refs/remotes/svn/trunk

MyRepoから新しいブランチをフェッチする場合は、次のようにして新しいフェッチエントリを構成に追加できます。

git config --add svn-remote.svn.fetch branches/sub-dir2/branch4:refs/remotes/svn/branches/sub-dir2/branch4

または、同じ構成を.git / configで編集することもできます

configに追加した後で新しいブランチを取得するには、次のコマンドを実行します。

git svn fetch -r 10000:HEAD

[編集]新しく追加されたブランチを取得するには、-allパラメータを指定してfetchを実行する必要がある場合があります。

git svn fetch --all -r 10000:HEAD

4

git-svnの癖を処理する代わりに、SubGitを試すことができます。

SubGitをSubversionリポジトリにインストールする必要があります。その後、特別なgit-svnコマンドを使用する代わりに、標準のgitワークフローを使用できます。

  1. 新しいコミットをプッシュする:

    git-svn:

    $ git commit
    $ git svn rebase
    $ git svn dcommit
    

    SubGit:

    $ git commit
    $ git push
    
  2. 着信変更を取得しています

    git-svn:

    $ git svn rebase
    

    SubGit:

    $ git pull [--rebase]
    
  3. 新しいブランチを作成する:

    git-svn:

    $ git svn branch foo
    $ git checkout -b foo -t remotes/foo
    $ git commit
    $ git svn dcommit
    

    SubGit:

    $ git checkout -b foo
    $ git commit
    $ git push
    

詳細については、SubGitのドキュメントを参照してください。


1
SubGitには、svnと「シャドウ」gitリポジトリの2つのリポジトリを作成するという欠点があります。これは巨大なSVNリポジトリでは問題になる可能性があります...
Udo

@Udo SVNリポジトリにいくつかのプロジェクトがある場合、そのうちの1つだけを指定してGitリポジトリと同期することができます。この場合、Subversionリポジトリ全体をGitに変換する必要はありません。しかし、このリポジトリに巨大なSVNプロジェクトがある場合、このリポジトリの履歴全体ではなく、いくつかの最小限のリビジョンから始まる履歴を変換する可能性があります。これにより、翻訳されたGitリポジトリのサイズを減らすことができます。
vadishev 2012

1
@Udo-リポジトリサーバーのハードドライブを購入したくない企業は、優先順位をめちゃくちゃにしています。しかし、巨大なリポジトリを持つほとんどの場所はリポジトリをかなり真剣に受け止めており、リポジトリのディスク容量要件は、数十年の歴史と数千万のコード行と数十万のリビジョンを持つ企業であっても、一般的に大きな問題ではありません。これは、同社のコアとなる知的資産の中で最も具体的な形式であり、ディスク容量はかなり安価です。RAIDコントローラーをアップグレードする必要があるかもしれませんが、それでも生産性は向上します...
Bob Kerns、2012年

@ボブカーンズ-ポイントは、「サイズに関して」SVNとGitであり、互換性がないということです。ディスクストレージなどの問題ではありません。ただし、通常は数個のファイル/プロジェクトのみをチェックアウトする必要があるため、巨大なSVNリポジトリを操作できます。しかし、巨大なGitリポジトリを複製することはできません-それは少なくとも面白くありません;-)「巨大」とは、いくつかのギグを意味します。
Udo

2

助けになったvjangusの回答に追加するには、適切なポイントでブランチをトランクに接続するためにgitグラフトを使用して追加することも有用であることがわかりました-gitが履歴を確認してマージを正しく実行できるようにします。

これは単純に.git/info/graftsハッシュで行を追加する場合です:

<initial branch commit> <parent commit in trunk>

例えば。

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638

http://evan-tech.livejournal.com/255341.htmlへのクレジット

(コメントとして追加しますが、評判が足りません。)


0

有効なレイアウトでチェックアウトしないと、リモートブランチをチェックアウトできません。

これが私がすることです:

git svn init -s <svn path with no trunk> local_repo
cd local_repo
git svn fetch 
## wait

その後、リモートブランチに切り替えることができます。

git checkout --track -b branch_name branch_name

その後、自動的にブランチに切り替わります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.