是否有可能从另一个git存储库中挑选一个提交?

我正在使用一个git存储库,它需要从另一个不知道第一个的git存储库提交。

通常我会在reflg中使用HEAD@{x}进行选择,但是因为这个.git对这个reflg条目(不同的物理目录)一无所知,我怎么能选择这个,或者我可以吗?

我正在使用git-svn。我的第一个分支使用Subversion仓库trunk中的git-svn,下一个分支在Subversion分支上使用git-svn

345761 次浏览

您需要将另一个存储库添加为远程,然后获取其更改。从那里您可以看到提交并选择它。

像这样:

git remote add other https://example.link/repository.gitgit fetch other

现在你有了所有的信息来简单地做git cherry-pick

完成后,您可能希望再次删除遥控器,如果您不再需要它,请使用

git remote remove other

有关使用遥控器的更多信息:https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes

是的。获取存储库,然后从远程分支中挑选。

参见如何使用Git创建和应用补丁。(从你问题的措辞来看,我假设这个其他存储库是用于完全不同的代码库。如果它是相同代码库的存储库,你应该按照@CharlesB的建议将其添加为远程。即使它是用于另一个代码库,我想你仍然可以将其添加为远程,但你可能不想将整个分支放入你的存储库…)

给出的答案是使用format-patch,但由于问题是如何从另一个文件夹中挑选,这里有一段代码可以做到这一点:

$ git --git-dir=../<some_other_repo>/.git \format-patch -k -1 --stdout <commit SHA> | \git am -3 -k

来自Cong MaAug 28'14评论的解释

git format-patch命令从some_other_repo的提交创建一个补丁由其SHA指定(仅一次提交为-1)。这个补丁是管道到git am,它在本地应用补丁(-3意味着尝试如果补丁无法干净地应用,则三路合并)。

这是一个远程获取合并的示例。

cd /home/you/projectAgit remote add projectB /home/you/projectBgit fetch projectB

然后您可以:

git cherry-pick <first_commit>..<last_commit>

或者你甚至可以合并整个分支(只有当你真的需要合并所有内容时)

git merge projectB/master

你可以做到这一点,但它需要两个步骤。

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD

<remote-git-url>替换为您要从中挑选的存储库的url或路径。

<branch>替换为您要从远程存储库中挑选的分支或标记名称。

您可以将FETCH_HEAD替换为分支中的git SHA。

更新:根据@pkalinow的反馈进行修改。

我的情况是,我有一个团队推送到的裸存储库,以及它旁边的一个克隆。Makefile中的这组行对我来说正确工作:

git reset --hardgit remote update --prunegit pull --rebase --allgit cherry-pick -n remotes/origin/$(BRANCH)

通过使裸存储库的master保持最新,我们能够挑选发布到裸存储库的拟议更改。我们还有一种(更复杂的)方法来挑选多个分支进行合并审查和测试。

如果“什么都不知道”意味着“不能用作远程”,那么这没有帮助,但是当我在谷歌上搜索这个工作流程时,这个问题出现了,所以我想我会做出贡献。

以下是添加远程、获取分支和挑选提交的步骤

# Cloning our fork$ git clone git@github.com: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存储库中,需要樱桃选择的更改,并且你已经签出了正确的分支。

git fetch ssh://git@stash.mycompany.com:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533#

git Fatech[分支URL][从樱桃采摘的分支]&&git chryr-picer[提交ID]

假设A是您要选择的存储库,而B是您要选择的存储库,您可以通过将</path/to/repo/A/>/.git/objects添加到</path/to/repo/B>/.git/objects/info/alternates来做到这一点。如果不存在,请创建此alternates文件。

这将使存储库B访问存储库A中的所有git对象,并使樱桃选择为您工作。

如果您想为给定文件选择多个提交,直到达到给定的提交,请使用以下方法。

# Directory from which to cherry-pickGIT_DIR=...# Pick changes only for this fileFILE_PATH=...# Apply changes from this commitFIST_COMMIT=master# Apply changes until you reach this commitLAST_COMMIT=...
for sha in $(git --git-dir=$GIT_DIR log --reverse --topo-order --format=%H $LAST_COMMIT_SHA..master -- $FILE_PATH ) ; dogit --git-dir=$GIT_DIR  format-patch -k -1 --stdout $sha -- $FILE_PATH |git am -3 -kdone

在这种情况下,对于某些本地化的验证,提交必须是“樱桃选择”的。对于相同的存储库签出,它也可能是本地提交(即尚未推送到服务器)。

例如。

  • repo1similar到repo2
  • repo1具有分支b1-HEAD在本地进行了2次提交(包括commit_x)。
  • repo2有分支bb1-需要to cherry-pickcommit_x。

为此,

$ cd repo2

repo2$ git获取

repo2$ git车厘子

在上述情况下,现在可以识别commit_x并将其拾取(借助fetch)。

如果另一个存储库存在于同一台机器上,您可以通过应用补丁然后提交原始消息来实现与樱桃挑选类似的效果。这是一个例子:

$ git apply <(git -C "$PATH_TO_OTHER_REPO" show "$COMMIT_HASH")$ MSG="$(git -C "$PATH_TO_OTHER_REPO" log -n 1 --pretty=format:'%s' "$COMMIT_HASH")"$ git commit -m "$MSG"

我不必经常这样做,所以我对这个工作流程很好。但是,为此编写一个自定义的Git命令应该相当容易,并且它更好,更自动化。

请注意,<(...)中的命令可以是为Git生成有效补丁的任何内容:git showgit diff,使用wgetcurl从Github等远程获取原始diff内容(因此您可以跳过克隆),cat从文件……这一行本身非常有用。