1

We just switched from Subversion to Git.

The problem that came up this morning was that we cherry-picked a commit from a branch into master so maser would have a bug fix. Then we merged master back to the branch.

When we tried to compile, all of the additions from the cherry-picked commit were in the code twice.

The cherry-picked commit consisted of the addition of a couple of lines of code, which ended up afterward being in the code twice. Luckily they were entire functions so it threw a compiler error.

There was never a conflict raised.

How do we avoid this. It's a major problem.

Thanks.

James Baker
  • 67
  • 1
  • 8
  • 1
    You should try something like the `git-flow` workflow. (Explanation: http://nvie.com/posts/a-successful-git-branching-model/ Tooling: https://github.com/nvie/gitflow) In this case, the "right" way would've been creating a new branch for the bug in the old code (not the one being developed on the feature branch) and merging it into both master and the feature branch - then git can track the commit correctly. – millimoose Jan 09 '13 at 15:01
  • @millimoose That nvie workflow definitely doesn't seem like it is applicable in all situations. A develop branch doesn't seem too friendly with continuous delivery. – Sled Jan 09 '13 at 15:21
  • Unfortunately, a cherry pick is sometimes the only answer. Many times we will find a bug that affects all branches, and we need to put the fix in all branches, but we don't want the other changes from any branch. This is why cherry-picking exists in the first place. – James Baker Jan 09 '13 at 15:45
  • @ArtB I'll admit I have only limited practice with the model, it just seemed appropriate in the OP's situation. What do you mean by "not friendly with continuous delivery"? Presumably you still want have new features go through some sort of integration process, and if I understand the explanation right `develop` is mostly the place to do that, whereas the feature branches are "private" to groups. Or to put it another way, you don't QA "private" code. (Although obviously the model in its entirety would be overkill for smaller apps that don't really have dedicated QA.) – millimoose Jan 09 '13 at 19:28
  • @JamesBaker If the bug affects all branches, then you could base the bugfix branch off of whatever their shared ancestor is, then merge this branch into all of them. – millimoose Jan 09 '13 at 19:35

1 Answers1

6

A cherry-pick is a different commit from Git's point of view. i.e. when you merge back, you're merging back a new commit on top of that originally applied.

That is to say, you create a commit with hash ABC. You cherry-pick it across, creating a new commit DEF. The merge back then applies DEF alongside ABC.

In the above, I would perhaps expect you to simply perform the commit on master (say) and cherry-pick that to your branch.

This blog post has more info.

Notice that it creates a new commit on the master branch. If, on master, you run "git log", you'll see a different hash for the same commit message. Why?

This is because of how Git models what a commit is. A commit is a complete snapshot of the whole repository, and the hash for a given commit reflects the state of every file in the whole directory - it is a hash of all their hashes.

So clearly, since master branch doesn't have all of the commits from the feature branch, a complete snapshot of it at the time the bugfix is applied will generate a different hash than a complete snapshot of the feature branch at the time the bugfix is applied there. Thus, different hashes.

But when you do merge the feature branch into master, that won't matter; the hashes for the individual file where you made the bugfix will be the same, because their contents will be the same, so there will be nothing to update on master for that file.

This blog post details a similar situation and how to use git rebase to avoid such issues.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
  • I would have thought that Git would realize that the contents of the commits were the same and not duplicate it. This may be a showstopper. – James Baker Jan 09 '13 at 15:08
  • See the above blog post and the excerpt I've highlighted. – Brian Agnew Jan 09 '13 at 15:09
  • The problem isn't that there are two commits with the same change. We're used to that having just come from Subversion. The problem is that when we merge back, Git applies the same change twice so that we have the same line of code twice in the source file. – James Baker Jan 09 '13 at 15:47
  • The last paragraph from the blog post isn't correct from what we've seen It says the contents will be the same, but they're not. THe code changes are in the file twice. – James Baker Jan 09 '13 at 15:48