git 从一个分支拉取所有提交,将指定的提交推送到另一个
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/880957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pull all commits from a branch, push specified commits to another
提问by Sylvain
I have the following branches:
我有以下分支:
master
production
master
production
and the following remote branches:
以及以下远程分支:
origin/master
origin/production
origin/master
origin/production
I have a script that fetches the origin/master
branch and gets the diff of what changed from my last fetch (log -p master..origin/master
). Then I merge origin/master
.
我有一个脚本可以获取origin/master
分支并获取与上次获取 ( log -p master..origin/master
) 相比发生的变化的差异。然后我合并origin/master
。
The commits found are pushed to a code review tool.
找到的提交被推送到代码工具。
I want to push the successful commits – and only them – to the production branch, and then of course to origin/production
.
我想将成功的提交——而且只有它们——推送到生产分支,然后当然是origin/production
.
How can I do so?
我怎么能这样做?
Also, I have 2 scripts running: the one that fetch from origin/master
, push commits details to a database, and merge, and the other that I'm currently writing that will have to push the successful commits.
此外,我有 2 个脚本正在运行:一个从 获取origin/master
,将提交细节推送到数据库,然后合并,另一个是我目前正在编写的,必须推送成功的提交。
I'd like to have those 2 scripts running while avoiding race conditions/merge conflict. Since I only want to work with specified commits, maybe there's a way to get rid of the commits that I don't want?
我希望在避免竞争条件/合并冲突的同时运行这两个脚本。由于我只想处理指定的提交,也许有办法摆脱我不想要的提交?
回答by bdonlan
The term I think you're looking for is a 'cherry pick'. That is, take a single commit from the middle of one branch and add it to another:
我认为您正在寻找的术语是“樱桃选择”。也就是说,从一个分支的中间进行一次提交并将其添加到另一个:
A-----B------C
\
\
D
becomes
变成
A-----B------C
\
\
D-----C'
This, of course, can be done with the git cherry-pick command.
当然,这可以通过 git cherry-pick 命令来完成。
The problem with this commit is that git considers commits to include all history before them - thus, if you have three commits like so:
这个提交的问题是 git 认为提交包含它们之前的所有历史记录——因此,如果你有三个像这样的提交:
A-----B-----C
And try to get rid of B, you have to create an entirely new commit like so:
并尝试摆脱 B,您必须像这样创建一个全新的提交:
A-----------C'
Where C' has a different SHA-1 ID. Likewise, cherry picking a commit from one branch to another basically involves generating a patch, then applying it, thus losing history that way as well.
其中 C' 具有不同的 SHA-1 ID。同样,从一个分支到另一个分支的樱桃提交基本上涉及生成一个补丁,然后应用它,因此也会以这种方式丢失历史记录。
This changing of commit IDs breaks git's merging functionality among other things (though if used sparingly there are heuristics that will paper over this). More importantly though, it ignores functional dependencies - if C actually used a function defined in B, you'll never know.
提交 ID 的这种更改破坏了 git 的合并功能等(尽管如果谨慎使用,会有一些启发式方法可以解决这个问题)。更重要的是,它忽略了函数依赖——如果 C 真的使用了 B 中定义的函数,你永远不会知道。
Perhaps a better way to handle this would be to have more fine grained branches. That is, instead of just having a 'master', have 'featureA', 'bugfixB', etc. Perform code review on an entire branch at a time - where each branch is very focused on doing only one thing - and then merge that one branch when you're done. This is the workflow that git is designed for, and what it's good at :)
也许处理这个问题的更好方法是拥有更细粒度的分支。也就是说,不仅仅是有一个“master”,还有“featureA”、“bugfixB”等。一次对整个分支进行代码——每个分支都非常专注于只做一件事——然后合并它完成后一个分支。这是 git 设计的工作流程,以及它的优点:)
If you insist on dealing with things at the level of patches, you may want to look at darcs - it considers a repository to be a set of patches, and thus cherry picking becomes the fundamental operation. However this has its own set of problems, such as being very slow :)
如果您坚持在补丁级别处理事情,您可能需要查看 darcs - 它认为存储库是一组补丁,因此挑选樱桃成为基本操作。但是,这有其自身的一系列问题,例如速度非常慢:)
Edit: Also, I'm not sure I understand your second question, about the two scripts. Maybe you could describe it in more detail, possibly as a separate question to keep things from getting confusing?
编辑:另外,我不确定我是否理解关于这两个脚本的第二个问题。也许你可以更详细地描述它,可能作为一个单独的问题来防止事情变得混乱?
回答by MattJenko
I realise this is an old question, but is referenced here: How to merge a specific commit in Git
我意识到这是一个老问题,但在此处引用:How to merge a specific commit in Git
Hence, a newer answer: Use feature branches and pull requests.
因此,一个更新的答案:使用功能分支和拉取请求。
What this looks like, where fA is a commit with feature A, and fB is a commit with feature B:
这看起来像什么,其中 fA 是具有特征 A 的提交,而 fB 是具有特征 B 的提交:
fA fC (bad commit, don't merge)
/ \ /
master ----A----B----C
\ /
fB
Pull requests are associated with GitHub's functionality, but really all I mean is that someone has the responsibility of merging the feature branches into master.
拉取请求与 GitHub 的功能相关联,但实际上我的意思是有人有责任将功能分支合并到主分支中。