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

git*_*182 676 git cherry-pick

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

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

我正在使用git-svn.我的第一个分支使用git-svntrunk一个颠覆回购,而下一个分支是在git-svn上一个Subversion分支.

Rob*_*ler 830

给出的答案是使用格式补丁,但由于问题是如何从另一个文件夹中挑选,所以这里有一段代码:

$ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k
Run Code Online (Sandbox Code Playgroud)

(来自@cong ma的解释)

git format-patch命令some_other_repo从其SHA指定的提交创建一个补丁(仅-1用于一次提交).此修补程序通过管道传输git am,在本地应用修补程序(-3意味着如果修补程序无法干净地应用,则尝试三向合并).希望解释一下.

  • @ nickF,`git format-patch`命令从其SHA指定的`some_other_repo`提交创建一个补丁(单独一次提交的`-1`).这个补丁通过管道输出到`git am`,它在本地应用补丁(`-3`表示如果补丁无法干净地应用,则尝试三向合并).希望解释一下. (43认同)
  • 这是现场,但如果有人可以扩展这一点,那将是很好的 - 确切地说明正在发生的事情(尤其是那些标志)将会非常有用. (18认同)
  • @Tom尝试使用`--ignore-whitespace`.完整命令:`git --git-dir = ../<some_other_repo>/.git format-patch -k -1 --stout <commit SHA> | git am -3 -k --ignore-whitespace` (8认同)
  • @BoomShadow因为它更简单.添加远程和获取会带来所有其他repo的更改.此命令行是一次性操作. (5认同)
  • 错误:补丁失败:somefile.cs:85错误:somefile.cs:补丁不适用你手动编辑你的补丁吗?它不适用于其索引中记录的blob.不能回退到三方合并.修补程序在0001处失败添加了GUI部件.失败的补丁副本位于:<some_other_repo>/.git/rebase-apply/patch解决此问题后,运行"git am --continue".如果您想跳过此补丁,请改为运行"git am --skip".要恢复原始分支并停止修补,请运行"git am --abort". (3认同)
  • 对我来说,“git show”可以作为“git format-patch”的替代品。并且可以使用`git apply`代替`git am`。不知道为什么人们会使用其中之一。 (2认同)
  • 原来如此.git am实际上使用提交消息提交补丁. (2认同)
  • 从一系列提交创建补丁时不需要 -1 ,比如 git format-patch [..] aaa..bbb 。这里的 `--relative=..` 就像一个过滤器,所以只有来自这个子目录的提交被包含在补丁中。类似于用“filter-branch”做的事情。 (2认同)
  • 对此有很多赞成,评论说这是更好的答案.它对我有用,但我想知道_why_这是更好的答案吗?与'git remote'和cherry-pick方法相比,它有什么优势? (2认同)
  • 这仅对我使用“--ignore-whitespace”有效,并且在 Windows 上根本不起作用。 (2认同)
  • 这不是一个通用的方法。就我而言,结果是一次三向合并。请参阅:/sf/ask/1160041711/ (2认同)

Cha*_*esB 509

您需要将其他存储库添加为远程存储库,然后获取其更改.从那里你看到提交,你可以樱桃挑选它.

像那样:

git remote add other https://example.link/repository.git
git fetch other
Run Code Online (Sandbox Code Playgroud)

现在您可以完成所有信息git cherry-pick.

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

  • 如果您正在使用Github,则可以通过将.patch附加到提交URL,然后将其应用于`git am <d821j8djd2dj812.patch`来提取补丁.在GH之外,可以在下面的替代答案中引用类似的概念. (33认同)
  • 从另一个回购中挑选的详细步骤:https://coderwall.com/p/sgpksw/git-cherry-pick-from-another-repository (7认同)
  • 您实际上不需要添加遥控器。抓取就够了。如果您的磁盘上已经有该存储库,那么 `../&lt;some_other_repo&gt;/` 是一个非常好的 uri。 (3认同)
  • @radicand 下面哪个答案是“替代”答案?请链接到它。 (2认同)

Bri*_*ian 142

这是一个remote-fetch-merge的例子.

cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB
Run Code Online (Sandbox Code Playgroud)

然后你可以:

git cherry-pick <first_commit>..<last_commit>
Run Code Online (Sandbox Code Playgroud)

或者你甚至可以合并整个分支

git merge projectB/master
Run Code Online (Sandbox Code Playgroud)

  • `git merge projectB/master`***是非常非常错误的***,因为你没有应用来自单个提交的更改(比如樱桃选择),你实际上是在合并***更改`projectB/master`中的***,它们不包含在您自己的`master`分支中. (53认同)
  • 当两个存储库相关时,这可以很好地工作. (5认同)
  • 我的假设是这是原始海报的意图.否则,是的,这不是他们的正确选择. (4认同)
  • **IMO这需要是公认的解决方案.**此外,如果您想在完成樱桃选择后删除遥控器,请使用`git remote rm projectB`.还可以使用`git tag -d tag-name`删除从远程仓库获取的任何标记.远程提交将不再显示在您的历史记录中,修剪将最终从存储中删除它们. (4认同)
  • 我已经从 git 存储库创建了一个副本(只是为了在不破坏原始存储库的情况下“玩弄”)并使其源代码保持最新,Brian 的答案正是我所需要的,所以,纸杯蛋糕,我不得不说,这不是“错误”,而是另一个用例。但是你很高兴指出潜在的灾难:D (2认同)
  • 我读到从 git 2.9 开始你必须使用`--allow-unrelated-histories`。使用这个选项对我有用。 (2认同)

doc*_*hat 118

你可以做到,但它需要两个步骤.这是如何做:

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD
Run Code Online (Sandbox Code Playgroud)

替换<remote-git-url>为您想要挑选的存储库的URL或路径.

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

您可以FETCH_HEAD使用分支中的git SHA 替换它.

更新:根据@ pkalinow的反馈修改.

  • 它适用于分支名称,但不适用于SHA.如果你想樱桃挑提交其哈希表示,用这个来代替:'混帐取<回购网址> <分支> && git的樱桃挑选<沙>`. (5认同)
  • 对于跨回购的一次性樱桃选择,这应该是公认的答案。在已经是本地的存储库之间进行选择时,我一直使用它,然后远程 URL 只是一个本地文件系统路径。 (2认同)

jar*_*lli 59

以下是添加远程,获取分支和樱桃选择提交的步骤

# 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
Run Code Online (Sandbox Code Playgroud)

资料来源:https://coderwall.com/p/sgpksw


Aas*_*set 17

请参阅如何使用Git创建和应用修补程序.(根据你的问题的措辞,我假设这个其他存储库用于完全不同的代码库.如果它是相同代码库的存储库,你应该将它添加为@CharlesB建议的远程存储库.即使它是另一个代码库,我想您仍然可以将其添加为远程,但您可能不希望将整个分支添加到您的存储库...)


Don*_*Don 10

您可以在一行中执行以下操作.希望你在git资源库中,需要樱桃挑选的更改,你已经检查出正确的分支.

git fetch ssh://git@stash.mycompany.com:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533
# 
Run Code Online (Sandbox Code Playgroud)

git fetch [branch URL] [分支到樱桃挑选] && git cherry-pick [提交ID]


Xer*_*rus 6

这是一个很容易凭记忆打出的内容,灵感来自@radicand 的评论。它依赖于 forge 的能力,但 Github、Gitlab 和 Gitea 绝对支持它。

您附加.patch到提交 URL 并通过以下方式应用它git am

curl --location URL.patch | git am
Run Code Online (Sandbox Code Playgroud)

--location使其遵循重定向,例如从拉取请求复制补丁时可能会发生这种情况


wil*_*ell 5

是。提取存储库,然后从远程分支中进行选择。


Vic*_*der 5

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

$ 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"
Run Code Online (Sandbox Code Playgroud)

我不需要经常这样做,所以我对这个工作流程很满意。然而,为此编写自定义的 Git 命令应该相当容易,并且让它更好、更自动化。

请注意,里面的命令<(...)可以是为 Git 生成有效补丁的任何命令:git showgit diff、 usingwgetcurl从远程(例如 Github)获取原始 diff 内容(这样您就可以跳过克隆)、cat从文件...该行本身,非常有用。