简体   繁体   English

如何从远程git存储库一次提取一个提交?

[英]How to pull one commit at a time from a remote git repository?

I'm trying to set up a darcs mirror of a git repository. 我正在尝试建立一个git存储库的darcs镜像。 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. 我有一些工作正常,但有一个重大问题:如果我将一大堆提交推送到git repo,那些提交将合并到一个darcs补丁集中。 I really want to make sure each git commit gets set up as a single darcs patchset. 我真的想确保每个git commit都设置为单个darcs补丁集。 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. 我打赌这可以通过做某种git fetch然后询问远程分支的本地副本来实现,但是我的git fu不能胜任这项工作。

Here's the (ksh) code I'm using now, more or less: 这是我现在使用的(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

My idea is 我的想法是

  1. Try git fetch to get local copy of the remote branch (not sure exactly what arguments are needed) 尝试使用git fetch获取远程分支的本地副本(不确定需要什么参数)
  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? 想法?

Have you tried looking at some existing solutions for moving changesets between version control systems, such as Tailor , which says that it includes support for git and darcs? 你有没有尝试过一些现有的解决方案,用于在版本控制系统之间移动变更集,例如Tailor ,它说它包括对git和darcs的支持? (There are suggestions for similar systems on that page as well.) (该页面上也有类似系统的建议。)

Otherwise, if you want to use your suggested approach, you could use git checkout on each commit after HEAD to origin/master to checkout that commit in "detached HEAD" mode. 否则,如果你想使用你建议的方法,你可以在HEADorigin/master之后的每次提交中使用git checkout来检查在“分离的HEAD”模式下提交。 For example, to modify the example you give (and in bourne shell, I'm afraid, since I don't use ksh): 例如,要修改你给出的例子(在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

Note that this will linearize the history from git, which wouldn't be what I wanted, personally. 请注意,这将使git中的历史线性化,这不是我想要的,就个人而言。 :) I think it's best to use an existing tool for this, but the above approach could be made to work. :)我认为最好使用现有的工具,但上述方法可以使用。

You could do something like this: 你可以这样做:

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

I created a repository for this script and tried it out. 我为这个脚本创建了一个存储库并试了一下。 The following is before and after merge: 以下是合并前后:

在此输入图像描述

在此输入图像描述

Now I didn't have a remote repository so I faked the git fetch and the remote branch with a local (named kalle), but you get the idea. 现在我没有远程存储库所以我伪造了git fetch和远程分支与本地(名为kalle),但你明白了。 Just do the complete merge and then back up the HEAD pointer until you reach the first commit from origin/master. 只需执行完整合并,然后备份HEAD指针,直到从origin / master获得第一次提交。

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 will pick the top patch by default. cherry-pick将默认选择顶部补丁。

for the third part I think you'll have to write a script to do it for you. 对于第三部分,我认为你必须编写一个脚本来为你做。 there are other ways to get the hashes and lots of options for log. 还有其他方法可以获取日志的哈希和许多选项。 Actually there might be a hook for cherry-pick or maybe just post commit... to run the darcs code. 实际上可能有一个用于樱桃选择的钩子或者可能只是发布提交...来运行darcs代码。 check out git hooks. 看看git hooks。

in fact on that note each patch applied in a rebase might call a git commit hook so you might be able to write that and then do a git pull --rebase and have that code nailed on each apply... 实际上在那个注释中,在rebase中应用的每个补丁都可以调用git commit hook,这样你就可以编写它然后执行git pull --rebase并在每次应用时修复该代码...

Use this to retrieve hashes from a branch: 使用此命令从分支中检索哈希值:

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

Then use git cherry-pick -n <hash> to apply each one. 然后使用git cherry-pick -n <hash>来应用每一个。

Another option, as cited by @xenoterracide, is using githooks. @xenoterracide引用的另一种选择是使用githooks。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM