Merging & Rebasing

  • So do you rebase, then merge? It looks like rebase just makes changes?

DescriptionCommands

Merge two branches

  • The branch name used should be the one you are not currently in

git merge <BRANCH_NAME>

Rebase one branch onto another

  • If you are currently on a branch, you can rebase to move all of the commits in that branch to a new attachment point on a different/new branch

  • In the example below, main* was on C3 and the command git rebase C2 was used to rebase/move C3 to after C2

  • This changes the "base" so that it looks like the features were developed sequentially rather than in parallel

  • This makes the git diagram neater

git rebase <BRANCH_NAME/REF> git rebase <REF1> <REF2>

Completely replace Main with a Branch

git checkout main

git pull

git checkout <BRANCH>

git merge -s ours main

git checkout main

git merge <BRANCH>

Merge Example

git checkout main
git pull
git merge side1
git merge side2
git merge side3
git push

Rebase Example

git fetch
git rebase o/main side1
git rebase side1 side2
git rebase side2 side3
git rebase side3 main
git push

Reversing Changes

DescriptionCommands

Reverses changes by moving a branch reference backwards in time to an older commit

  • In this sense you can think of it as "rewriting history"

  • git reset will move a branch backwards as if the commit had never been made in the first place

  • --hard deletes commits between current location and the reference used so they are no longer in the history

git reset <REF>

git reset HEAD^

git reset --hard HEAD^

While resetting works great for local branches on your own machine, its method of "rewriting history" doesn't work for remote branches that others are using.

  • In order to reverse changes and share those reversed changes with others, we need to use git revert

git revert <REF>

git revert HEAD

Moving things around

DescriptionCommands

Copy a series of commits below your current location (HEAD)

  • Think of cherry-pick like a rebase where the commits added before the current location are specifically selected

  • Sure, you can also do some specific selection with git rebase -i but that is only commits in the selected path, cherry-pick commits could come from anywhere

git cherry-pick <COMMIT_1> <COMMIT_2> <...>

Git Interactive Rebase

  • Using the rebase command with the -i option

  • If you include this option, git will open up an editor to show you which commits are about to be copied below the target of the rebase. It also shows their commit hashes and messages, which is great for getting a bearing on what's what.

  • It seems to open in vim

git rebase -i <REF>

git rebase -i HEAD~4

Git Tags

DescriptionCommands

Add a tag

git tag <TAG_NAME> <REF>

git tag 1.0.0 main

Checkout a tag

git checkout <TAG_NAME>

Push tags to remote

git push <REMOTE_NAME> --tags

Describe where you currently are relative to the closest "anchor" (aka tag)

  • If you don't specify a <REF> the git will just use where you're checked out right now (head)

  • Where <TAG> is the closest ancestor tag in history, <NUM_COMMITS> is how many commits away that tag is, and <CURRENT_HASH> is the hash of the commit being described.

git describe <REF>

OUTPUTS:

<TAG>_<NUM_COMMITS>_g<CURRENT_HASH>

Fetch Arguments Example

git fetch origin foo:main
git fetch main^ origin:foo
git checkout foo
git merge main

Last updated