How to re-use a branch of commits periodically?

67 views Asked by At

I have code base in which I need to reuse a branch full of changes at a later time. This code is for testing, and will not be merged into the main codebase, but I would like to maintain the provenance of the branch if possible.

For example, let's say I have this

a-b-c-d-e-f-g-h-i
     \            
      1-2-3

I want to do this.

a-b-c-d-e-f-g-h-i
     \           \
      1-2-3       1-2-3

I can cherry-pick 1, 2, and 3 onto i, but I am hoping there is an easier and more traceable way to do this.

Do I git pull --rebase the 1st 1-2-3 branch?

2

There are 2 answers

6
knittl On

You cannot have

a-b-c-d-e-f-g-h-i
     \           \
      1-2-3       1-2-3

But you can easily have

a-b-c-d-e-f-g-h-i
     \           \
      1-2-3       1'-2'-3'

(A commit can only exist once. If you rebase or cherry-pick, you create new commits.)

The following command will work in your local repository:

git rebase i branch-which-points-to-3

It takes all commits reachable from branch-which-points-to-3 , but not reachable from i (i.e. commits 1..3) and re-applies them as new commits on top of i. The original commits 1..3 are no longer reachable and the new commits will have new commit ids (commit hashes). You can no longer do a simple fast-forward push of this branch, but would need to do a force-push since you are effectively rewriting history.

If you want your old commits to still be reachable, create a new branch pointing to your old commit(s) before rebasing. This will keep them reachable through this branch name. You can either rebase the old or the newly created branch, depending on your requirements.

Note that this is not all that different from cherry-picking: git cherry-pick 1..3 will create copies of the commits too. I like to think of cherry-picking as the inverse of rebasing (source and destination are swapped) – with rebasing I tell Git where to I want to rebase, whereas with cherry-picking I tell Git where from I want to pick.

0
jthill On

more traceable

The way Git traces provenance is with ancestry. Ancestry is literally provenance here, the normal-usage distinctions simply don't exist in Git's world.

a-b-c-d-e-f-g-h-i    mainline
     \             
      1-2-3          instrumented-base

The way to merge the subsequent mainline changes is to merge them:

git checkout -b this-test-today instrumented-base
git merge mainline

producing

a-b-c-d-e-f-g-h-i    mainline
     \           \
      \     ,---- T    this-test-today       
       1-2-3         instrumented-base
           

and now your this-test-today tip records its provenance.