Various ways to create a branch in Git from another branch:
This answer adds some additional insight, not already present in the existing answers, regarding just the title of the question itself (Create a branch in Git from another branch), but does not address the more narrow specifics of the question which already have sufficient answers here.
I'm adding this because I really needed to know how to do #1 below just now (create a new branch from a branch I do not have checked out), and it wasn't obvious how to do it, and Google searches led to here as a top search result. So, I'll share my findings here. This isn't touched upon well, if at all, by any other answer here.
While I'm at it, I'll also add my other most-common git branch
commands I use in my regular workflow, below.
1. To create a new branch from a branch you do not have checked out:
Create branch2
from branch1
while you have any branch whatsoever checked out (ex: let's say you have master
checked out):
git branch branch2 branch1
The general format is:
git branch <new_branch> [from_branch]
man git branch
shows it as follows. What I call <new_branch>
is what they call <branchname>
, and what I call [from_branch]
is what they call [<start-point>]
:
git branch [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
2. To create a new branch from the branch you do have checked out:
git branch new_branch
This is great for making backups before rebasing, squashing, hard resetting, etc.—before doing anything which could mess up your branch badly.
Example: I'm on feature_branch1
, and I'm about to squash 20 commits into 1 using git rebase -i master
. In case I ever want to "undo" this, let's back up this branch first! I do this ALL...THE...TIME and find it super helpful and comforting to know I can always easily go back to this backup branch and re-branch off of it to try again in case I mess up feature_branch1
in the process:
git branch feature_branch1_BAK_20200814-1320hrs_about_to_squash
The 20200814-1320hrs
part is the date and time in format YYYYMMDD-HHMMhrs
, so that would be 13:20 hours (1:20 pm) on 14 Aug. 2020. This way I have an easy way to find my backup branches until I'm sure I'm ready to delete them. If you don't do this and you mess up badly, you have to use git reflog
to go find your branch prior to messing it up, which is much harder, more stressful, and more error-prone.
Interjection: notes about git checkout
vs git switch
- The classic, universal "Swiss army knife" which can do 1000 things:
git checkout
.
- The new and experimental alternative commands to
git checkout
: git switch
+ git restore
.
git switch
was added recently in Git v2.23. See your git version with git --version
. It is designed to be an extremely limited form of git checkout
, designed only to switch branches rather than also having the ability to check out or restore files, like git checkout
can do. Read more here: https://www.git-tower.com/learn/git/commands/git-switch.
See also: What does git checkout still do after git switch got introduced?. git restore
offers some of the rest of the functionality of git checkout
which git switch
does not contain.
Both man git switch
and man git restore
caution:
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
So, feel free to stick with git checkout
if you like. Its behavior is not likely to change.
I pretty much just use git checkout
myself, but you are welcome to use git switch
(and git restore
to restore or "check out" files) if you like.
3. To create and check out a new branch from the branch you do have checked out:
# the standard, "classic" command most people still use; `-b` stands
# for "create 'b'ranch"
git checkout -b new_branch
# the newer, "experimental" command now available as of Git v2.23; `-c` stands
# for "'c'reate branch"
git switch -c new_branch
To make it obvious what is happening there, know that this one command above is equivalent to these two separate commands:
# classic
git branch new_branch
git checkout new_branch
# OR: new/experimental as of Git v2.23
git branch new_branch
git switch new_branch
4. To create and check out a new branch from a branch you do not have checked out:
# classic
git checkout -b new_branch from_branch
# OR: new/experimental as of Git v2.23
git switch -c new_branch from_branch
To make it obvious what is happening there, know that this one command above is equivalent to these three separate commands:
# classic
git checkout from_branch
git branch new_branch
git checkout new_branch
# OR: new/experimental as of Git v2.23
git switch from_branch
git branch new_branch
git switch new_branch
5. To rename a branch
Just like renaming a regular file or folder in the terminal, git
considered "renaming" to be more like a 'm'ove command, so you use git branch -m
to rename a branch. Here's the general format:
git branch -m <old_name> <new_name>
man git branch
shows it like this:
git branch (-m | -M) [<oldbranch>] <newbranch>
Example: let's rename branch_1
to branch_1.5
:
git branch -m branch_1 branch_1.5
OR, if you already have branch_1
checked out, you can rename the currently-checked-out branch to branch_1.5
like this:
git branch -m branch_1.5
6. To create a new feature branch (feature2
) based off of the latest upstream changes on main
when you currently have feature1
checked out
Let's put a lot of what we learned above together to present a very common example we need to run whenever we finish one feature and need to start another one.
# The beginner/intermediate way
git checkout main # check out main branch
git pull # pull latest upstream changes down
git checkout -b feature2 # create branch `feature2` from `main`, and check
# it out, all in one step`
# The advanced way
# [this is what I do--I'll explain why, below]
git fetch origin main:main # pull latest upstream changes down from the
# remote `main` branch, to the
# locally-stored remote-tracking **hidden**
# branch named `origin/main`, **and** to
# the local `main` branch
git checkout -b feature2 main # create branch `feature2` from `main`, and
# check it out, all in one step`
# OR (nearly the same thing)
git fetch origin main # pull latest upstream changes down from the
# remote `main` branch, to the
# locally-stored remote-tracking **hidden**
# branch named `origin/main`. This does NOT
# update the local `main` branch though!
git checkout -b feature2 origin/main # create branch `feature2` from
# `origin/main`, and check it out, all
# in one step`
So, when I'm on branch feature1
, and have just finished it and am ready to start on a new feature2
based off of the latest main
branch, why do I do this:
git fetch origin main:main
git checkout -b feature2 main
...instead of this?:
git checkout main
git pull
git checkout -b feature2
The answer, surprisingly, is that git checkout
can be a horribly slow and heavy operation!—taking up to 3+ hours on a massive mono-repo utilizing git lfs
post-checkout hooks in the repo's .git/hooks/post-checkout
file. Let me explain. The .git/hooks/post-checkout
file is an executable file containing a script that git will run after each time you run git checkout
. If it contains a call to git lfs post-checkout "$@"
, then it may try to download 20+ GB of git lfs
data (specific to the repo I work in—your scenario may vary) after running an innocent-looking git checkout
. I don't want to do that! So, I skip the git checkout
process to avoid that hassle and get started on my feature2
branch immediately without downloading all of that stuff I don't need first!
See also:
- Quick links to my answers I reference frequently and consider to be "git fundamentals":
- Various ways to create a branch in git from another branch
- All about checking out files or directories in git
- Who is "us" and who is "them" according to Git?
- How to use
git diff
filters via --diff-filter=
- All about searching (via
grep
or similar) in your git repositories
- How to use
git lfs
as a basic user: What is the difference between git lfs fetch
, git lfs fetch --all
, and git lfs pull
?