如何从远程git仓库逐个拉取提交记录?

8
我正在尝试建立一个git存储库的darcs镜像。我有一些正常工作的东西,但存在一个重大问题:如果我向git repo推送了许多提交,那么这些提交将被合并成一个单独的darcs补丁集。我真的希望确保每个git提交都设置为单独的darcs补丁集。我猜这可以通过执行某种git fetch,然后对远程分支的本地副本进行查询来实现,但我的git技能还不足以胜任这项工作。
这是我现在使用的(ksh)代码,或多或少:
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

我的想法是:

  1. 尝试使用git fetch命令获取远程分支的本地副本(不确定需要哪些参数)。
  2. 以某种方式查询本地副本,以获取自上次镜像操作以来的每个提交的哈希值(我不知道如何实现这一点)。
  3. 循环遍历所有哈希值,仅拉取该提交并记录相关的补丁集(如果有哈希值,我相信我知道如何做到这一点)。

我欢迎您对上述情况进行详细阐述或提出其他建议

有什么想法吗?


只是提醒一下,下面有几个新的答案,你还没有评论。 (显然,其中一个我认为特别好地回答了你的问题;)) - Mark Longair
4个回答

2
你尝试过查看一些已有的解决方案来在版本控制系统之间移动变更集吗,比如Tailor。它声称支持git和darcs。(该页面上还有类似系统的建议)如果不想使用这个方法,你可以使用git checkout命令将每个提交从HEADorigin/master都检出到“分离的HEAD”模式下。例如,修改你提供的示例(在Bourne Shell方式下,很抱歉,因为我不使用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的历史线性化,个人而言我不希望这样做。 :) 我认为最好使用现有的工具来完成这个任务,但上述方法也可以实现。

1
你可以像这样做:
#!/bin/bash
git fetch
count=$(git log --pretty=oneline | wc -l)
git merge origin/master
git reset --hard HEAD~$((count-1))

我为这个脚本创建了一个存储库并尝试了它。以下是合并前后的情况:

enter image description here

enter image description here

现在我没有远程仓库,所以我伪造了git fetch和远程分支,使用本地(命名为kalle),但你可以理解我的意思。只需完成完整的合并,然后将HEAD指针备份,直到您达到来自origin/master的第一个提交。


0

git remote update # 获取所有远程仓库,我比只获取更喜欢它

git log origin/master # 可以是任何远程分支

git cherry-pick origin/master # 例如远程/分支,也可以指定sha1

cherry-pick 默认会选择顶部补丁。

对于第三部分,我认为您将不得不编写一个脚本来为您完成。有其他获取哈希和日志的方法和大量选项。实际上,可能会有一个cherry-pick挂钩,或者只是提交后...运行darcs代码。看看git hooks。

事实上,在这个注释中,每个在rebase中应用的修补程序可能调用一个git commit hook,因此您可能能够编写该代码,然后执行git pull --rebase,并在每个应用程序上固定该代码...


1
我已经在网上学习了关于git cherry-pick的信息,但它并不是我想要的!它会创建一个新的、独立的提交!我会继续深入挖掘。 - Norman Ramsey

0
使用此方法从分支中检索哈希值:
git log --pretty=format:"%h" HEAD..origin/master

然后使用git cherry-pick -n <hash>来应用每一个提交。

另一个选择,正如@xenoterracide所引用的,是使用githooks。


4
我已经在网上学习了有关于 git cherry-pick 的信息,但它并不是我想要的!它会创建一个新的、独立的提交记录!我会更深入地挖掘。 - Norman Ramsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接