-1

is it possible to go from this:

a--b--c--f
       \
        d--e

to this?

a--b--c--d--e--f

I'm a bit lost on this one. Any help will be welcome.

Jose Ramirez
  • 381
  • 6
  • 20

2 Answers2

1

Not exactly. Git cannot move commits, it can only copy and create new, different commits. To achieve want you want do

git checkout e
git cherry-pick f

You will have

a--b--c--d--e--f`

where f` is a copy of f.

phd
  • 82,685
  • 13
  • 120
  • 165
0

The piece missing from your diagram is the branch names that point to commits f and e:

a--b--c--f   <-- branch_f
       \
        d--e   <-- branch_e

You cannot literally move commit f: a commit, once made, is quite permanent and unchange-able. You can, however, copy commit f to a new commit that's a lot like f, but different in some way(s).

What you want is a commit that is like f, except that it has e as its parent, and probably has a different source base (e's source rather than c's).

Cherry picking

To get this kind of copy, one can use git cherry-pick, which literally just makes the copy:

$ git checkout branch_e
$ git cherry-pick branch_f

giving:

a--b--c--f   <-- branch_f
       \
        d--e--f'  <-- branch_e (HEAD)

Note that we've added the new commit f' (the copy) to the current branch, branch_e.

Rebasing

Instead of using git cherry-pick, we can use git rebase. This copies some number of commits, automatically:

$ git checkout branch_f
$ git rebase branch_e

The set of commits that get copied are those on the current branch—which is why we have to check out branch_f first—that aren't on the other branch, which is why we tell it branch_e.

The place it copies them to, is "after the tip of the other branch".

Once it finishes making the copy, git rebase "peels away" the label branch_f from where it was before, and moves it to after the last-copied commit:

a--b--c--f   [abandoned]
       \
        d--e   <-- branch_e
            \
             f'  <-- branch_f (HEAD)

Note that this is the same set of commits as before: the key difference is that branch_e has not moved (still points to e) and branch_f has moved (now points to new copy f').

(Also, the current branch is branch_f this time.)

torek
  • 448,244
  • 59
  • 642
  • 775