2

I have a git workflow scenario question and have provided the "current" and "desired" branch structures, but I don't know the correct commands to get to the desired state.

Current:

a -- b                --> Branch1 (there are no commits after b)
     \
      \
       c -- d -- e    --> Branch2

I want to rebase or reset head (not merge, as I want a straight line history in log) such that Branch 1 looks like this:

Desired:

a -- b -- c -- d -- e --> Branch1
     \
      \
       c -- d -- e    --> Branch2 (this branch may be removed)

I realise that the head of Branch2 must now be the head of Branch1, but don't know if the following commands will ensure changes c and d will also become part of Branch1 or if the new commit history will look like a -- b -- e:

git checkout Branch1 
git reset Branch2 

Thank you for your time!

Vada Poché
  • 763
  • 5
  • 16
  • 2
    You just need to move the pointer... the simples way to do it is `git branch -F branch1 branch2` so that `branch1` moves to the same commit that `branch2` is pointing to. If you want to remove `branch2` you might instead delete `branch1` and _renam_ branch2 to branch1: `got branch -m branch2 branch1`. It's the same end result as moving the pointer and then deleting `branch2`. – eftshift0 May 02 '23 at 10:03
  • 3
    As a side note, I think you should say _tip_ instead of `head` or `HEAD`. `HEAD` has a very special meaning in git: **it's whatever commit/branch you are working on**, and it's not necessarily pointing to a branch. – eftshift0 May 02 '23 at 10:04
  • 2
    Thank you so much. For the benefit of anyone else who may come and read this, I found another link here that clarifies the difference between tip and HEAD in git: https://stackoverflow.com/questions/39752604/git-terminology-difference-between-tip-and-head#:~:text=A%20tip%20is%20the%20most,a%20commit%20to%20a%20branch. – Vada Poché May 02 '23 at 10:14

2 Answers2

3

Branches are just string names attached to some commit, and you can manipulate what commit a branch name is attached to.

So your formulation is basically right. Say this:

git switch Branch1 
git reset --hard Branch2
git branch -D Branch2

Alternatively you could use the first branch name to replace the second branch name:

git switch Branch2
git branch -M Branch1
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Thank you. Will this method also ensure that commits c and d are present in Branch1? – Vada Poché May 02 '23 at 10:35
  • 1
    Commits are not "present in a branch". The branch is just a name for one commit. Nothing but names are affected here. – matt May 02 '23 at 10:38
  • Thank you, much appreciated. I am slowly moving away from the 'SVN' way of thinking, so your comment is very helpful. – Vada Poché May 02 '23 at 10:40
  • 2
    Read my https://www.biteinteractive.com/picturing-git-conceptions-and-misconceptions/ to discover what Git is and how to think about it – matt May 02 '23 at 10:42
2

Since Branch1 has no commits after b, you can simply fast-forward it to Branch2:

git checkout Branch1
git merge --ff-only Branch2

--ff-only forces a fast-forward and forbids a merge commit. See man git-merge#ff.

After the fast-forward, your tree will look like this:

a -- b -- c -- d -- e --> Branch1, Branch2

Branch2 can safely be removed. This whole operation is strictly equivalent to removing Branch1 and renaming Branch2 to Branch1. Remember, for git a branch is simply an alias/pointer to a commit.

YSC
  • 38,212
  • 9
  • 96
  • 149