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

发布于 2024-08-29 19:37:46 字数 966 浏览 11 评论 0原文

我正在尝试设置 git 存储库的 Darcs 镜像。我有一些工作正常的东西,但有一个重大问题:如果我将一大堆提交推送到 git 存储库,这些提交就会合并到单个 darcs 补丁集中。我真的想确保每个 git 提交都设置为单个 darcs 补丁集。我敢打赌,通过执行某种 git fetch ,然后询问远程分支的本地副本,这是可能的,但我的 git fu 无法胜任这项工作。

这是我现在使用的(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. 循环遍历所有哈希值,仅提取该提交并记录相关的补丁集(我很确定我知道如何执行此操作)如果我得到了哈希)

我欢迎帮助充实上面的场景或关于我应该尝试的其他东西的建议。

有想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

花海 2024-09-05 19:37:47

git Remote update # 获取所有遥控器,我比只获取更喜欢它

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

gitcherry-pick origin/master # 例如远程/分支,您还可以指定 sha1

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

对于第三部分,我认为您必须编写一个脚本来为您完成它。还有其他方法来获取哈希值和许多日志选项。实际上,可能有一个用于cherry-pick的钩子,或者可能只是提交后...来运行darcs代码。查看 git hooks。

事实上,在这一点上,rebase 中应用的每个补丁都可能调用 git commit hook,因此您可以编写它,然后执行 git pull --rebase 并将该代码钉在每个应用上......

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.

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. check out 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...

长不大的小祸害 2024-09-05 19:37:47

使用它从分支检索哈希值:

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

然后使用 gitcherry-pick -n应用每个哈希值。

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

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.

Another option, as cited by @xenoterracide, is using githooks.

岁月无声 2024-09-05 19:37:46

您是否尝试过查看一些在版本控制系统之间移动变更集的现有解决方案,例如 Tailor,它说它包括对 git 和 darcs 的支持? (该页面上也有类似系统的建议。)

否则,如果您想使用建议的方法,您可以在 HEAD 之后的每次提交上使用 git checkoutorigin/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 的历史记录线性化,这不是我个人想要的。 :) 我认为最好使用现有的工具来实现此目的,但上述方法可以发挥作用。

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? (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. For example, to modify the example you give (and in bourne shell, I'm afraid, since I don't use 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. :) I think it's best to use an existing tool for this, but the above approach could be made to work.

哽咽笑 2024-09-05 19:37:46

你可以这样做:

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

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

在此处输入图像描述

在此处输入图像描述

现在我没有远程存储库,所以我用本地(名为 kalle)伪造了 git fetch 和远程分支,但你明白了。只需进行完整的合并,然后备份 HEAD 指针,直到到达来自 origin/master 的第一个提交。

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:

enter image description here

enter image description here

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. Just do the complete merge and then back up the HEAD pointer until you reach the first commit from origin/master.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文