20

以前git svnは、既存のSubversionリポジトリをgitにインポートしていました。次に、これをgitサーバーのgitリポジトリにプッシュしました。過去数か月の間に、Subversionリポジトリとgitリポジトリの両方でソフトウェアに変更が加えられました。残念ながら、svnとgitの間のリンクを含む私のローカルコピーは削除されました。

もう一度を使用してローカルコピーを再作成しようとしましたgit svnが、gitサーバーからプルすると文句warning: no common conflictsが表示され、最初に同じコミットで2つの別々のブランチをマージすることになります。このような:

F
|\
| \
E  D
|  |
C  C
|  |
B  B
|  |
A  A

元のリポジトリからのブランチで発生したようにsvnの変更を処理するにはどうすればよいですか?

F
|\
| \
E  D
| /
|/
C
|
B
|
A
4

5 に答える 5

22

デフォルトgit-svnでは、SVN リビジョンと Git コミット間のマッピングをコミット メッセージに保存します。git-svn-id元の Git リポジトリに古いコミットのこれらの行が表示されますか? ここで私が意味するのは、最近 SVN から取得したものではなく、Git サーバーでホストされている Git リポジトリです。

もしそうなら、実際にはリンクが失われておらず、git-svn は履歴から必要なデータを復元できるはずです。ただし、異なるバージョンの git-svn 間の互換性の問題により、これは少し難しい場合があります。

  1. 元の Git リポジトリを複製します。

    $ git clone $GIT_SERVER repo
    $ cd repo
    
  2. .git/config で git-svn 構成を更新します。

    $ git config svn-remote.svn.url $SVN_URL
    $ git config svn-remote.svn.fetch trunk:refs/remotes/trunk
    $ git config svn-remote.svn.branches branches/*:refs/remotes/*
    $ git config svn-remote.svn.tags tags/*:refs/remotes/tags/*
    
  3. ここで、git-svn-id 行を使用して refs/remotes/* refs を最新のコミットに更新する必要があります。

    $ git log --first-parent refs/heads/master
    commit d566edf5f77ae0a2f7418c40949757e75ef8e83c
    D
    
    commit 4df9f21346526c6505a954d8310637864710308d
    C
    git-svn-id: $SVN_URL .../trunk@3...
    
    commit 116a6760d3e278aa4d54f5bb22e531d30d731661
    B
    git-svn-id: $SVN_URL .../trunk@2...
    
    commit d8bb201c6fd55ea5e645f2d8a07248593d177910
    A
    git-svn-id: $SVN_URL .../trunk@1...
    

    ご覧のとおり、コミット D には git-svn-id 行がありませんが、コミット C には行があり、その行はトランクを参照しているため、refs/remotes/trunk を更新して C をコミットする必要があります。

    $ git update-ref refs/remotes/trunk 4df9f21346526c6505a954d8310637864710308d
    
  4. ブランチとタグが多数ある場合は、上記で指定したマッピングに関して、同じ手順を繰り返します。

    • ブランチ/foo => refs/remotes/foo

    • タグ/1.0 => 参照/リモート/タグ/1.0

  5. 最後のステップは、.git/svn ディレクトリにマッピングを復元することです。

    $ git svn fetch
    Migrating from a git-svn v1 layout...
    Data from a previous version of git-svn exists, but
        .git/svn
        (required for this version (X.Y.Z) of git-svn) does not exist.
    Done migrating from a git-svn v1 layout
    Rebuilding .git/svn/refs/remotes/trunk/.rev_map.694389ff-b137-4359-84f9-4d1a25628e89...
    r1 = d8bb201c6fd55ea5e645f2d8a07248593d177910
    r2 = 116a6760d3e278aa4d54f5bb22e531d30d731661
    r3 = 4df9f21346526c6505a954d8310637864710308d
    Done rebuilding .git/svn/refs/remotes/trunk/.rev_map.694389ff-b137-4359-84f9-4d1a25628e89
    

最後のコマンドは、SVN サーバーから新しいリビジョンもフェッチします。コマンドが完了すると、Subversion リポジトリの git-svn クローンが作成されます。このリポジトリの履歴は分岐しているため、通常どおり SVN と Git リポジトリの間で変更を同期する必要があります。

$ git svn rebase
$ git svn dcommit

それが役立つことを願っています。

于 2012-10-28T00:38:48.013 に答える
3

まず、git svn infoコマンドの出力を確認します。そこに奇妙なものが見えますか?

次に、git svnローカル リポジトリ以外のセカンダリ git リポジトリを使用することはお勧めできません。

その理由は、各git svn dcommitgitが以前に行ったすべてのコミットを自動的に書き換えた後です。最初にそれらを svn にコミットしてから、コミットの svn リビジョン番号を追加します (一意の識別子 と呼ばれgit-svn-idます)。

新しい を作成したリポジトリでは、次のようになりますdcommit

$ git log -1
commit 1234abc...
Author: ...
Date:   ...

Some commit message

git-svn-id: http://your.svn.repo/svn/trunk@10 1234abc

詳細については、ProGit book のセクションを次に示します。

あなたが書いたエラーメッセージはおそらくwarning: no common commitsconflicts質問に書いたものとは異なります)であり、gitがこれらのメタデータをリモートレポにプッシュしなかったというのが私の印象です。

この SVN リンクを復活させることはできると思いますが、注意して、リポジトリの別のクローンに作成し、必要なメタデータについてドキュメントを注意深く読んでください。git では、配管ツールを使用して非常に多くのことを行うことができます。それらを見てください。

ところで、リモートの git リポジトリを単純に複製して使用することはできませんか?

これが何かの役に立てば幸いです。少なくとも、解決策を探し始めるためのいくつかのアイデアが得られることを願っています。

于 2012-10-21T12:06:45.657 に答える
1

最も簡単な解決策は、次のように、ローカルのgit-svnブランチをgitサーバーにプッシュすることです。

git push <git-server> <branch-name>:<branch-name>

git-serverブランチをローカルブランチでオーバーライドします。

これは、git-svnブランチにgitサーバーが持つすべてのコミットがあることが確実な場合にのみ行ってください。

于 2012-10-23T18:17:11.077 に答える
1

コミットグラフから

F
|\
| \
E   D
|   |
C1  C2
|   |
B1  B2
|   |
A1  A2

次のコマンドを使用します

git checkout <SHA1-B1>
git checkout -b new
git cherry-pick <SHA1-C2> <SHA1-D>
git checkout <SHA1-F>
git checkout -b position_f
git merge new

終わり。とにかく、まだ試していません。最初にリポジトリをバックアップします。

于 2012-10-23T09:28:04.377 に答える
1

これはどう:

  • バックアップを取る!
  • svn 履歴を git に再インポートする
  • 古いブランチと新しいブランチを同じレポに入れる
  • ブランチをコミット前に巻き戻しますF
  • Cnew -svn-imported の上にあるため、ブランチのすべての変更をリベースしますC
  • マージを再試行します

これが機能しない場合は、Git replaceを試すことができますが、それは悪い考えかもしれません。

于 2012-10-26T22:19:26.867 に答える