从一个分支中提取所有提交,将指定的提交推送到另一个分支

我有以下分行:

  • master
  • production

以及下列偏远分行:

  • origin/master
  • origin/production

我有一个脚本,它可以获取 origin/master分支,并获取从上次获取(log -p master..origin/master)中更改的内容的差值。然后合并 origin/master

发现的提交被推送到代码审查工具。

我希望将成功的提交(并且只有它们)推送到生产分支,然后当然是 origin/production

我该怎么做?

另外,我还运行了两个脚本: 一个是从 origin/master获取、将提交细节推送到数据库和合并的脚本,另一个是我当前正在编写的脚本,它必须推送成功的提交。

我想让这两个脚本运行,同时避免竞争条件/合并冲突。由于我只想处理指定的提交,也许有一种方法可以去除我不想要的提交?

94133 次浏览

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.

The problem with this commit is that git considers commits to include all history before them - thus, if you have three commits like so:

A-----B-----C

And try to get rid of B, you have to create an entirely new commit like so:

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.

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.

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 :)

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 :)

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?

I realise this is an old question, but is referenced here: 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   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.