8

I'm trying to set up a darcs mirror of a git repository. I have something that works OK, but there's a significant problem: if I push a whole bunch of commits to the git repo, those commits get merged into a single darcs patchset. I really want to make sure each git commit gets set up as a single darcs patchset. I bet this is possible by doing some kind of git fetch followed by interrogation of the local copy of the remote branch, but my git fu is not up to the job.

Here's the (ksh) code I'm using now, more or less:

git pull -v # pulls all the commits from remote --- bad!

# gets information about only the last commit pulled -- bad!
author="$(git log HEAD^..HEAD --pretty=format:"%an <%ae>")"
logfile=$(mktemp)
git log HEAD^..HEAD --pretty=format:"%s%n%b%n" > $logfile

# add all new files to darcs and record a patchset. this part is OK
darcs add -q --umask=0002 -r .
darcs record -a -A "$author" --logfile="$logfile"
darcs push -a
rm -f $logfile

My idea is

  1. Try git fetch to get local copy of the remote branch (not sure exactly what arguments are needed)
  2. Somehow interrogate the local copy to get a hash for every commit since the last mirroring operation (I have no idea how to do this)
  3. Loop through all the hashes, pulling just that commit and recording the associated patchset (I'm pretty sure I know how to do this if I get my hands on the hash)

I'd welcome either help fleshing out the scenario above or suggestions about something else I should try.

Ideas?

4

4 に答える 4

2

バージョン管理システム間で変更セットを移動するための既存のソリューションをいくつか試してみましたか? たとえば、git と darcs のサポートが含まれていると述べているTailorなどがあります。(そのページにも同様のシステムの提案があります。)

それ以外の場合は、提案されたアプローチを使用する場合はgit checkout、各コミットで使用HEADしてorigin/master、そのコミットを「分離された HEAD」モードでチェックアウトすることができます。たとえば、あなたが与えた例を変更するには(そしてボーンシェルでは、私はkshを使用していないので、恐れています):

# Update all remote-tracking branches from origin
git fetch origin

for c in `git log --pretty=format:"%h" HEAD..origin/master`
do
     git checkout $c
     author=$(git log -1 --pretty=format:"%an <%ae>")
     logfile=$(mktemp)
     git log -1 --pretty=format:"%s%n%n%b%n" > $logfile

     darcs add -q --umask=0002 -r .
     darcs record -a -A "$author" --logfile="$logfile"
     darcs push -a
     rm -f $logfile         
done

# Now go back to master, and merge to keep your master branch up to date:
git checkout master
git merge origin/master

これは git からの履歴を線形化することに注意してください。個人的には、これは私が望んでいたことではありません。:)これには既存のツールを使用するのが最善だと思いますが、上記のアプローチを機能させることができます。

于 2010-09-07T08:55:32.927 に答える
1

次のようなことができます。

#!/bin/bash
git fetch
count=$(git log --pretty=oneline | wc -l)
git merge origin/master
git reset --hard HEAD~$((count-1))

このスクリプトのリポジトリを作成して試してみました。以下はマージ前後です。

ここに画像の説明を入力

ここに画像の説明を入力

今はリモート リポジトリを持っていなかったので、git fetch とリモート ブランチをローカル (kalle という名前) で偽装しましたが、おわかりいただけたでしょうか。完全なマージを実行してから、origin/master からの最初のコミットに到達するまで HEAD ポインターをバックアップします。

于 2011-04-27T21:55:53.740 に答える
0

git remote update # fetch all remotes I like it better than just fetch

git log origin/master # can be any remote/branch

git cherry-pick origin/master # example remote/branch you can also specify a sha1

cherry-pick はデフォルトで一番上のパッチを選びます。

3 番目の部分では、それを行うスクリプトを作成する必要があると思います。ログのハッシュと多くのオプションを取得する方法は他にもあります。実際には、cherry-pick 用のフックがあるか、コミットを投稿するだけで、darcs コードを実行できる可能性があります。gitフックをチェックしてください。

実際、リベースに適用された各パッチは git commit フックを呼び出す可能性があるため、それを記述してから git pull --rebase を実行し、適用するたびにそのコードを釘付けにすることができます...

于 2010-04-21T05:16:19.810 に答える
0

これを使用して、ブランチからハッシュを取得します。

git log --pretty=format:"%h" HEAD..origin/master

次に、git cherry-pick -n <hash>それぞれを適用します。

@xenoterracide で引用されている別のオプションは、githook を使用することです。

于 2010-04-21T05:36:15.290 に答える