0

I have a doubt in Git. We have been pushing our features to master where most recent commit is c2. Between c1 and c2 there are almost 10 commits. Today due to some issues, we had to create a branch from c1 commit in master that I have done like following:

 git branch bugfix c1

And in this bugfix branch the changes I have done as part of commit c2, has to be present. So I am going to do following:

 git checkout bugfix
 git cherry-pick -x c2

Is it safe? I mean from git perspective is there any way changes in commit from c1+1 to c2-1 may come to bugfix branch, because we don't want any of the changes between c1 and c2 from master come to bugfix branch.

Joy
  • 4,197
  • 14
  • 61
  • 131
  • If your code in `c2` relies on any of the changes between `c1` and `c2` then it won't work correctly or perhaps won't compile, but a cherrypick will only get the changes from *one* commit. – crashmstr Sep 25 '17 at 14:45
  • I think the correctness depends on what kind of change c2 is. If it depends on previous 10 commits, than your cherry-picking will not work correctly (will not include all necessary changes). – vahancho Sep 25 '17 at 14:47
  • I will think about correctness. But just tell me from git prespective, whetther any changes between those commits will come to bugfix? – Joy Sep 25 '17 at 14:50

2 Answers2

1

It is safe, as the cherry-pick only takes the changes of the commit identified as c2. However, as stated in the comments, this might cause problems if the c2 change depends on previous changes between c2 and c1. Furthermore, the cherry-pick will fail if the c2 changes do not match the state you have in c1 (i.e., because it requires previous changes that are part of a commit between c1 and c2).

In general it is safe to just create a commit. Normally, you only cause harm by pushing problematic commit to an external (build) server. In your case it might help to just inspect the changes after cherry-picking.

C-Otto
  • 5,615
  • 3
  • 29
  • 62
1

Fundamentally, what git cherry-pick does is to convert each "cherry" (each commit to be picked) into a changeset—a set of diffs—and then attempt to apply that changeset to your current (or HEAD) commit1 and make a new commit from the result.

The diff for any one particular commit is obtained by running git diff between that commit and its parent commit. This diff is easy to obtain: git show <hash> does it for any non-merge commit. (Cherry-picking a merge requires specifying which parent and is therefore a bit more complex.) Thus, you can use git show to view what changes git cherry-pick will pick.

Note that if git show shows a change to a file that does not exist in HEAD, or to a region of code that does not exist in a file that does exist in HEAD, Git will be unable to complete the cherry-pick on its own. In this case, Git will treat the cherry-pick operation as a request to merge the changes, using a full 3-way merge, with the merge base being the parent of the commit being cherry-picked and the two branch tips being HEAD (--ours) and the commit being cherry-picked (--theirs). This will leave the merge conflict in the work-tree, with the in-progress merge stored in the index; you resolve this as you would any other merge conflict, then run git cherry-pick --continue to finish the operation, or git cherry-pick --abort to stop and go back to the way things were before you started.


1Or, with -n, to the index and work-tree only.

torek
  • 448,244
  • 59
  • 642
  • 775