How to change the branching point in Git?
Suppose I have the following structure in my git repo:
C'---D'---E'---F' (dev) / A---B---C---D---E---F (master)
I would like to pull
C' into the master branch and change the branching point to
C', i.e., I want to turn the above into
D'---E'---F' (dev) / A---B---C---C'---D---E---F (master)
I believe I should use a combination of cherry-picking and rebasing, but I am confused about how to do so exactly. Which sequence of operations should I perform?
Suggestion after comments for a clearer schema (since same-letter commits in the original were in fact unnecessary)
G---H---I---J (dev) / A---B---C---D---E---F (master)
with the associated expected result :
H---I---J (dev) / A---B---C---G---D---E---F (master)
The short answer, for your new diagram, is you rebase off
git checkout master git rebase <commit_id_G>
The longer answer is that you're having difficulty seeing this because you're thinking of
master as the "main" branch, and thinking of
dev as the "offshoot". But, of course, these branch names are just labels, and you can consider either of them as the "main" branch.
master is the branch we actually want to change, we can redraw the diagram like this:
H---I---J (master) / A---B---C---D---E---F---G (dev)
with the associated expected result :
H'--I'--J' (master) / A---B---C---D---E---F---G (dev)
Hopefully it's easier to see here, that we simply need to rebase
master off this new
D instead of
Change branching point in git, Since no commits have been added to BranchA yet, you can simply reset it to Branch2 : git checkout BranchA git reset --hard Branch2. Had there been any� You want the branch to point to a different commit. You can do that by running. git branch -f <branch-name> <starting-branch> Note that if branch-name is the current branch, you have to switch to a different branch first, for example with git checkout master.
You just need to rebase
git checkout master git rebase <id-of-G>
That will rewrite all the commits found in
master which aren't found in
G on top of
G. There's no need for cherry-picking. Your
dev branch will be unchanged.
Basic Branching and Merging, This is an important point to remember: when you switch branches, Git resets your Your change is now in the snapshot of the commit pointed to by the master� Figure 18. A simple commit history. You’ve decided that you’re going to work on issue #53 in whatever issue-tracking system your company uses. To create a new branch and switch to it at the same time, you can run the git checkout command with the -b switch: $ git checkout -b iss53 Switched to a new branch "iss53".
You would need to do the following:
Take not of the hash-refs of these commits:
git checkout master
git reset --hard C
git cherry-pick C'
git checkout dev
git rebase -i master(interactive rebase to get rid of C')
git checkout master
git cherry-pick D
git cherry-pick E
git cherry-pick F
Push both branches with
--force to finish.
I do not recommend this if you're not comfortable with
git but that's how I would go about it if absolutely needed to do it like that.
You can always go this route
D'---E'---F' (dev) / A---B---C---D---E---F---C' (master)
cherry-pick C' then rebase your
dev branch against
master. That would be the simplest solution.
Branches in a Nutshell, Figure 14. HEAD points to the current branch. What is the significance of that? Well, let's do another commit: $ vim test.rb $ git commit -a -m 'made a change'. Additionally you can checkout a new local branch and reset it to the remote branches last commit. git checkout -b <branchname>git reset --hard origin/<branchname>. Detached HEADS. Now that we’ve seen the three main uses of git checkouton branches, it's important to discuss the “detached HEAD”state.
Git: How to rebase your feature branch from one branch to another , Just doing a simple git rebase production from my-feature-branch will not work, as it will move commits 3 through 6 to production, effectively merging master into � A solution relying on the order of parents of a commit obviously won't work in situations where a branch has been fully integrated at some point in the branch's history. git commit --allow-empty -m root # actual branch commit git checkout -b branch_A git commit --allow-empty -m "branch_A commit" git checkout master git commit --allow-empty -m "More work on master" git merge -m "Merge branch_A into master" branch_A # identified as branch point git checkout branch_A git merge --ff-only master
Move branch pointer to different commit without checkout, In case if you just want to move a branch to another commit: $ git branch -f branch -name new-tip-commit. In order to move a branch pointer:. 1. Pick the branch you need. Use git branch -v. You see a list of existing local branches. Grab the branch name that suits your needs. 2. Move HEAD to it. Use git checkout <branch_name> You will see Switched to branch <branch_name>. Success!
Branching and merging, How to combine the changes of parallel tracks of work? How can I permanently reference a point in history, like a software version? Objectives. Be able to create � A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master. As you start making commits, you’re given a master branch that points to the last commit you made. Every time you commit, the master branch pointer moves forward automatically.
- What is the relation between same-letter commits? (i.e.
C') Are these rebased versions of the same, or reverts? or something else? (Also, your expected result is impossible since
Dwill always have
Cfor its parent, no matter what)
Cis the parent of
C'(also parent of
D). Your point about
Dalways needing to have
Cas its parent makes sense. So, perhaps I would need to replace
D''in the diagram, that is the same as
Dexcept that it has
C'as its parent?
- You did not answer my question. Of course
C''s parent, your schema already told us that. I'll rephrase : why did you NOT name all your commits with different letters if they're all just commits. We often use
A'to mean the rebased version of
Aor the reversion of
- @RomainValeri Sorry, I had misunderstood your question. There is no relation between
C''s parent.) My commit labels are confusing and I was not aware of the convention about rebased commits.
- No offense, it was just to help you avoid creating false assumptions on answerers. I'd suggest renaming your schema if you feel like it.
- That should be
git rebase hash-of-D(not hash of G) but otherwise this is right (and upvoted). Note that the original
H-I-Jchain remains in the repository (found temporarily via
ORIG_HEADand for at least 30 days by default through the reflog for
master). I like to draw the new commits with names
H'-I'-J'to denote that although we are using them as if they were the original
H-I-Jchain, they are in fact new commits with new, different hash IDs.
- @torek I was referring to the G in the second diagram for the OP. It is a bit confusing right enough. I'll redo my second diagram with primes as you suggest though.
- Thank you! It looks like my understanding of rebase was complete incorrect. Would anyone be able to kindly introduce a good tutorial on git? (I've mostly been using git for version control on a single branch, kind of a replacement of svn, but I know there are many more things you can do with git and would be interestead to learn them.)
- @CalumHalpin Thanks!
- This is a convoluted way to do it and will rewrite history on
devfor no reason.
- @CalumHalpin From the original post, he wants to rewrite history on both branches. he wants to take something from
dev, put it in the middle of
devout of the commit that was put in
- His diagram showed exactly the same history for
dev. It branched off
masterat a different point but that was because
- "I would like to pull
masterbranch and change the branching point to
C'". His original diagram shows this clearly. Not sure why everyone is just ignoring the original question here. As I said, I wouldn't do this personally but I'm sure he must have a reason to do this.
- The "branching point" is just the point at which the history of the two branches diverges. Rebasing
Gchanges it because now master also contains that commit. Either way the history of
A -> B -> C -> G -> H -> I -> J, there's no need to rebase/rewrite those commits. That's why we're "ignoring" that part of the original question.