我正在使用一个Git存储库,它需要来自另一个不知道第一个的Git存储库的提交。
通常我会在reflog中使用HEAD@{x}进行cherry pick,但是由于这个.git对reflog条目(不同的物理目录)一无所知,我如何才能cherry pick这个,或者我可以?
我用的是git-svn。我的第一个分支机构使用的是颠覆性回购的trunk的git-svn,下一个分支机构使用的是颠覆性回购的git-svn。
- 这就是本·李在这个问题上开诚布公的原因:"我要把这个赏金奖励给正确的答案,而不是公认的答案。我只是等了24小时才这么做,"但是,我不明白哪一个应该是"正确的答案",为什么接受的答案不是"正确的"。
- 目前还不清楚问题的性质。这些不同的回购协议是如何相关的,如果有的话?一个是另一个的叉子吗?或者他们实际上是两个完全独立和不相关的项目?
- @纸杯蛋糕,被接受的答案是好的,而且明显有助于操作,所以应该被接受。所谓"对",我的意思是"对我来说是对的"(根据评论判断,对其他几个人来说也是对的)。我只是觉得,我给的赏金应该得到和公认的答案一样多的回报。
给出的答案是使用格式补丁,但由于问题是如何从另一个文件夹中挑选,下面是一段代码:
1 2 3
| $ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k |
(explanation from @cong ma)
The git format-patch command creates a patch from some_other_repo's
commit specified by its SHA (-1 for one single commit alone). This
patch is piped to git am, which applies the patch locally (-3 means
trying the three-way merge if the patch fails to apply cleanly). Hope
that explains.
- 太棒了!!!!正是我想做的。
- @本利,谢谢你的代表!我很感激。当涉及多个许可证时,我使用我的方法而不是相关分叉的公认答案。我控制着保持代码的整洁。
- 哦,伙计,这太好了,非常感谢!!!!
- 这是一个很好的例子,但是如果有人能在此基础上进行扩展的话那就太好了——对正在发生的事情(尤其是那些旗帜)的详细分析将是非常有用的。
- 正是以正确的方式需要什么!!!!盯住人!!
- @nickf,git format-patch命令从其sha(-1)指定的some_other_repo提交创建一个补丁,只针对一个提交。此补丁通过管道连接到git am,后者在本地应用补丁(-3意味着如果补丁不能完全应用,则尝试三向合并)。希望能解释清楚。
- 这绝对应该是答案!!!!
- 错误:修补失败:somefile.cs:85错误:somefile.cs:patch不适用您手动编辑了修补程序吗?它不适用于其索引中记录的blob。无法返回到三向合并。修补程序在添加了0001个GUI部件时失败。失败补丁的副本位于:/.git/rebase apply/patch解决此问题后,运行"git am--continue"。如果您喜欢跳过这个补丁,请改为运行"git am--skip"。要恢复原始分支并停止修补,请运行"git am--abort"。
- 是否可以指定一个藏匿点来代替"commit sha"?在大多数git命令中,它们是可互换的,只是想确认这里是否也是这样。尤其是因为他们有两个父母(比如合并承诺),所以藏匿点略有不同。
- @汤姆试着用--ignore-whitespace。全指挥:git --git-dir=..//.git format-patch -k -1 --stdout | git am -3 -k --ignore-whitespace。
- 令人惊叹的!谢谢!
- 对我来说,git show是git format-patch的替代品。可以用git apply代替git am。不知道为什么一个会使用另一个。
- 哦,我明白了。git-am实际上提交了带有commit消息的补丁。
- 似乎git format-patch接受了--relative=..参数,尽管在man git format-patch中没有记录。这允许从子目录创建补丁。
- 当从一系列提交(如git format-patch [..] aaa..bbb创建补丁时,不需要-1。这里,--relative=..就像一个过滤器,所以补丁中只包含来自这个子目录的提交。类似于用其他方法处理filter-branch。
- 有很多人对此表示赞成,并评论说这是更好的答案。这对我有用,但我想知道为什么这是更好的答案?与"git-remote"和cherry-pick方法相比,它的优势是什么?
- @罗伯特瓦勒有没有办法直接从另一个回购商通过curl piping在Github的承诺中做到这一点?我玩过你的命令,但还没弄清楚!
- @因为这很简单。添加遥控器和提取会带来所有其他回购的变化。此命令行是一次性操作。
- -k不是这个问题的必要条件,它增加了答案的复杂性。
- 这个git dir的物理位置可以在另一台服务器上吗?我的意思是,有没有一种方法可以具体说明:--git-dir=other_server:/path/to/repo/.git?
- 这只适用于我使用--ignore-whitespace,它根本不适用于Windows。
您需要将另一个存储库添加为远程存储库,然后获取其更改。从那里你看到了承诺,你可以选择它。
像这样:
1 2
| git remote add other https://example.link/repository.git
git fetch other |
现在您有了所有信息,只需执行git cherry-pick。
有关使用遥控器的详细信息,请访问:https://git-scm.com/book/en/v2/git-basics-working-with-remotes
- 如果我使用Git SVN呢?我的第一个分支使用主干的git-svn,下一个分支使用一个分支的git-svn(感谢您的快速回复)
- @Gitcoder182:不确定,因为我从未使用过Git SVN,但它应该可以工作。
- 第一次克隆Subversion存储库时,请确保克隆整个存储库,而不仅仅是主干。如果在Subversion中使用标准的主干/分支/标签布局,请确保使用git svn的--stdlayout选项。那么subversion分支将只是一个远程git分支。
- 真的有必要把它作为一个遥控器添加吗??
- 如果您使用的是Github,那么可以通过在提交URL上附加.patch,然后将其应用到git am < d821j8djd2dj812.patch来获取补丁。在GH之外,类似的概念可以在下面的替代答案中引用。
- @radicand下面哪个答案是"备选"答案?请链接到它。
- @他指的是stackoverflow.com/a/9507417/347777
- 从另一个回购选择cherry的详细步骤:coderwall.com/p/sgpksw/git cherry pick from another reposito&zwnj;&8203;ry
- 如果这里有实际的命令就好了。
- 您不需要添加遥控器。提取就足够了。如果磁盘上已经有了repo,那么..//是一个非常好的URI。
- 太好了,谢谢!
下面是一个远程获取合并的示例。
1 2 3
| cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB |
然后你可以:
1
| git cherry-pick <first_commit>..<last_commit> |
或者你甚至可以合并整个分支
1
| git merge projectB/master |
- git merge projectB/master是非常非常非常错误的,因为您没有应用来自单个提交的更改(就像cherry pick那样),实际上您合并了projectB/master中不包含在您自己的master分支中的所有更改。
- 这是我的假设,这是原海报的意图。否则,是的,这不是他们的正确选择。
- 当两个存储库相关时,这一点非常有效。
- 我已经从Git存储库中创建了一个副本(只是为了在不破坏原始回购的情况下"到处玩"),为了使其保持最新的来源,Brian的回答正是我需要的,所以,我不得不说,cupcake,它不是"错误的",而是另一个用例。但你能指出潜在的灾难是件好事:d
- 我认为这是公认的解决方案。此外,如果您想在从遥控器中挑选樱桃后删除遥控器,请使用git remote rm projectB。还可以使用git tag -d tag-name删除从远程repo中提取的任何标记。远程提交将不再显示在您的历史记录中,修剪最终会将它们从存储中删除。
- 我从Git2.9开始就知道你必须使用--allow-unrelated-histories。使用这个选项对我很有用。
- 非正统:复制文件并重新提交。仅当您确定覆盖不会放弃任何更改时才执行此操作。
你可以做到,但这需要两个步骤。以下是如何:
1
| git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD |
将替换为要从中挑选cherry的存储库的URL或路径。
将替换为要从远程存储库中挑选的分支或标记名。
你可以用分支机构的Git-Sha替换FETCH_HEAD。
更新:根据@pkalinow的反馈修改。
- 它使用分支名称,但不使用sha。如果您希望挑选一个由散列表示的提交,请使用它:git fetch && git cherry-pick 。
- 谢谢。这正是我需要从一个存储库向另一个存储库插入大量提交的地方,我为此创建了这些提交。
- 这正是我为不同的客户机(每个客户机都有自己的存储库/分支)定制的代码实现所需要的,我们需要一种方法来将特定的提交提交到我们的基/主干中。谢谢!
- 这应该是对一次樱桃采摘跨越回购接受的答案。当在已经是本地的repos之间进行选择时,我一直使用它,远程URL只是一个本地文件系统路径。
以下是添加远程、获取分支和cherry选择提交的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # Cloning our fork
$ git clone [email protected]:ifad/rest-client.git
# Adding (as"endel") the repo from we want to cherry-pick
$ git remote add endel git://github.com/endel/rest-client.git
# Fetch their branches
$ git fetch endel
# List their commits
$ git log endel/master
# Cherry-pick the commit we need
$ git cherry-pick 97fedac |
来源:https://coderwall.com/p/sgpksw
请参阅如何使用Git创建和应用修补程序。(从您问题的措辞来看,我假设这个其他存储库用于完全不同的代码库。如果它是同一代码库的存储库,那么应该按照@charlesb的建议将其作为远程库添加。即使它是用于另一个代码库,我想您仍然可以将它作为远程代码添加,但您可能不想将整个分支放到您的存储库中…)
您可以按以下一行操作。希望您在需要cherry-picked更改的Git存储库中,并且已经签出以更正分支。
1 2
| git fetch ssh:// [email protected]:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533
# |
git fetch[branch url][branch to cherry pick from]&;git cherry pick[commit id]
对。获取存储库,然后从远程分支中选择cherry-pick。
假设A是你想要从中挑选的回购,而B是你想要从中挑选的回购,你可以通过在/.git/objects/info/alternates中添加/.git/objects来实现这一点。如果此alternates文件不存在,则创建它。
这将使repo b访问repo a中的所有git对象,并使cherry-pick为您工作。
我的情况是,我有一个团队推动的空回购,以及紧挨着它的复制品。makefile中的这组行对我来说工作正常:
1 2 3 4
| git reset --hard
git remote update --prune
git pull --rebase --all
git cherry-pick -n remotes/origin/$(BRANCH) |
通过保持裸回购主数据的最新,我们可以挑选一个发布到裸回购的提议变更。我们也有一种(更复杂的)方法来挑选多个分支进行合并审查和测试。
如果"什么都不知道"的意思是"不能用作遥控器",那么这没有帮助,但是这个问题是在我到处搜索来提出这个工作流程时出现的,所以我想我会做出贡献。