2523

If I have N commits, how do I branch from the N-3 commit?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
dole doug
  • 34,070
  • 20
  • 68
  • 87

22 Answers22

3605

Create the branch using a commit hash:

git branch branch_name <commit-hash>

Or by using a symbolic reference:

git branch branch_name HEAD~3

To checkout the branch while creating it, use:

git checkout -b branch_name <commit-hash or HEAD~3>
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 55
    Git 1.8.2 let me use the short sha1 for the first form. – Dan Benamy Apr 09 '13 at 20:52
  • 67
    @MattFenwick Git will allow you to use shortened hashes everywhere a hash is allowed, as long as the shortened hash is ''unique'' in the repository. So if it didn’t work, try adding another character from the hash. – poke May 17 '13 at 12:08
  • 43
    To push the new branch correctly to server.. needed this last step: `git push origin BRANCH_NAME` – Gene Bo Oct 15 '15 at 00:04
  • 4
    to start a branch from `` run `git checkout -b ` but if the branch already exists `git checkout -B ` – mostafazh Sep 18 '17 at 18:17
  • Also: `git branch branchname HEAD^^^` – Mendi Barel Jul 31 '20 at 17:11
  • 2
    This also works with the more recent `switch` command using the create option: `git switch -c branchname ` – Herohtar Jul 23 '21 at 16:02
  • Even after pushing to the server with Gene Bo's `git push origin BRANCH_NAME`, git still tells me "fatal: The current branch TDD_2023-05-31 has no upstream branch. To push the current branch and set the remote as upstream, use `git push --set-upstream origin BRANCH_NAME`", which I did. – mike rodent May 31 '23 at 17:36
354

To do this on github.com:

  1. Go to your project.
  2. Click on the "Commits".
  3. Click on the <> ("Browse the repository at this point in the history") on the commit you want to branch from.
  4. Click on the "tree: xxxxxx" up in the upper left. Just below the language statistics bar, you'll get the option to "Find or Create Branch" (just type in a new branch name there) Branch from previous commit
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
OneSolitaryNoob
  • 5,423
  • 3
  • 25
  • 43
  • 104
    Despite the fact that this is Github not git, it was still immensely helpful! – Liz Jan 25 '19 at 19:23
  • Unfortunately it still shows changes from other commits, which I wanted to avoid, which is why I searched for this question – Maxim Oct 01 '19 at 18:03
128

The magic can be done by git reset.

  1. Create a new branch and switch to it (so all of your latest commits are stored here)

    git checkout -b your_new_branch
    
  2. Switch back to your previous working branch (assume it's master)

    git checkout master
    
  3. Remove the latest x commits, keep master clean

    git reset --hard HEAD~x    # in your case, x = 3
    

From this moment on, all the latest x commits are only in the new branch, not in your previous working branch (master) any more.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Jing Li
  • 14,547
  • 7
  • 57
  • 69
  • 11
    This is what I was looking for since it removes the commits from the Master and makes it as though you had remembered to make the branch before those commits were made. Thanks. – superbeck Aug 01 '16 at 20:46
  • 13
    Just don't forget that a `git reset --hard` is not a good idea if you already have pushed the commit to origin... – LuisF May 31 '17 at 09:09
  • 2
    you can `git push --force ` if you had already pushed the branch before – Milan Jan 29 '19 at 14:46
  • 1
    But be really careful when using --force https://blog.developer.atlassian.com/force-with-lease/ – peater Sep 06 '19 at 18:57
  • CAUTION: Assuming "all the latest x commits are only in the new branch, not in your previous working branch (master) any more" is what you want. To people reading this: if you aren't *certain* that describes what you want, don't do this - it alters the master branch. – ToolmakerSteve May 08 '21 at 21:11
  • 9
    I don't understand the logic of this answer. The poster wants to create a new branch with code from the previous commit. This seems to create a branch from the current master, and then revert master to a previous commit. Am I wrong? – andrea m. Dec 03 '21 at 08:42
  • 1
    @andream. yes you got it right, but both your sentences are the same thing – georgiecasey Feb 06 '22 at 02:22
  • @georgiecasery I think I don't understand what a HEAD is, but I thought the poster did not want to change the head of the master branch, (the code seems to revert the head of master to 3 commits before). In other words, if I git checkout master, do I see HEAD or HEAD-3? – andrea m. Feb 07 '22 at 10:36
  • i.e.,do I lose any changes made in head-2, -1, 0? – andrea m. Feb 07 '22 at 10:48
  • @andream. no, you won't. But the head-2, -1 will be in your_new_branch instead of master. – Jing Li Feb 08 '22 at 17:39
  • ok but if so I don't think that's what the poster wanted. He wants the new branch to start from head-3 – andrea m. Feb 09 '22 at 13:30
  • `git push --force` is only appropriate when working without collaborators. – MrYellow Oct 12 '22 at 21:37
  • There seems to be some confusion. There should be no need for `git push --force` if this is done properly. Note in step #2, "previous WORKING branch". If you're doing what the OP is trying to do, the `git reset --hard HEAD~x` resets the local-only changes that you want to be only on your new branch. It can dip into remote changes if you're careless, and that would require a `git push --force`, but that is not what the OP is doing here – acat Mar 29 '23 at 15:50
  • 1
    @andream., that's correct, but still no contradiction. This solution takes the top 3 commits from curent or `master` or whatever and *moves* them to a new branch. So the new branch *does* start from 3 commits back, but those commits are then dropped from the branch where they were originally committed, so the original or `master` is back to where it was. This fits a scenario where you start making commits and then realise you didn't create a new branch. – NeilG Aug 22 '23 at 06:53
95

If you are not sure which commit you want to branch from in advance you can check commits out and examine their code (see source, compile, test) by

git checkout <sha1-of-commit>

once you find the commit you want to branch from you can do that from within the commit (i.e. without going back to the master first) just by creating a branch in the usual way:

git checkout -b <branch_name>
stanm
  • 3,201
  • 1
  • 27
  • 36
  • 1
    I /think/ this answer may have been rendered wrong by time. `git checkout -b` and `git branch` seem to always checkout the head for me, not the current detached position, unless the hash is specified as an extra argument. see `git switch -c newbranchname` – Gem Taylor Nov 16 '22 at 15:14
  • That's what I meant with the angular brackets: you need to specify the hash. – stanm Nov 18 '22 at 08:45
  • But you need to specify the hash in the (second) `branch` or `checkout -b` command, not just the . The first command you show is actually irrelevant if you already knew the hash. – Gem Taylor Nov 18 '22 at 18:19
  • Sorry, I see my previous comment doesn't make sense. Still, I don't understand what you mean by "detached position". How is it different from HEAD? Did you mean to say "main" or "master" in your original comment, instead of "head"? – stanm Nov 20 '22 at 18:48
  • May be poor terminology - I mean the current checked out hash/position is NOT the HEAD. When I checkout to a specific changelist I see this message "You are in a detached state" or similar. Hence "detached position". – Gem Taylor Nov 21 '22 at 12:13
  • I'm asking, because the message for me is "You are in 'detached HEAD' state." Furthermore, HEAD tracks whatever I last checked out. What version of git are you using? Mine is 2.38.1. Also, see https://git-scm.com/book/en/v2/Git-Internals-Git-References#ref_the_ref – stanm Nov 21 '22 at 13:32
  • Anyway. Do you see my issue with your second git statement or not? – Gem Taylor Nov 21 '22 at 19:59
  • Not really. That's why I was trying to clarify. "It works for me." ™ More specifically, the branching point is whatever commit I checked out with the first command. It is also where HEAD moves, after the first command. If I understand you correctly, you're saying HEAD does not move for you there, which is the thing that's confusing for me. From the documentation, I understand that it should. – stanm Nov 23 '22 at 10:24
66

Simply run :

git checkout -b branch-name <commit>

For example :

git checkout -b import/january-2019 1d0fa4fa9ea961182114b63976482e634a8067b8

The checkout command with the parameter -b will create a new branch AND it will switch you over to it

d1jhoni1b
  • 7,497
  • 1
  • 51
  • 37
  • is it possible to create a branch based on the SHA commit of a feature branch that was deleted via a pull request? Or do I have to branch from the commit of the pull request on master? – user2966445 Nov 27 '19 at 15:19
  • run `git fetch` & `git branch` command on your project's folder using the terminal, then check if the feature branch exists, if this is case then yes, of course you wont be able to create a branch from deleted branches, you could also revert a branch deletion in case the branch is gone – d1jhoni1b Nov 27 '19 at 22:55
35
git checkout -b <branch-name> <sha1-of-commit>
Tyler Liu
  • 19,552
  • 11
  • 100
  • 84
  • 4
    How is this different from "`git branch branchname `" (from the accepted answer)? – Peter Mortensen Jan 24 '18 at 22:44
  • 1
    I don't know. I think they are equivalent. I always use `git checkout -b` to create a new branch. – Tyler Liu Jan 29 '18 at 06:05
  • 17
    https://stackoverflow.com/a/7987711/3590629 git branch... creates the branch but leaves you on current branch. git checkout -b... creates the branch and switches you to it. – esme_louise Mar 09 '18 at 19:19
26

This creates the branch with one command:

git push origin <sha1-of-commit>:refs/heads/<branch-name>

I prefer this way better than the ones published above, because it creates the branch immediately (does not require an extra push command afterwards).

Alexander Samoylov
  • 2,358
  • 2
  • 25
  • 28
16

This is what I did:

C:\Users\[path]\build>git checkout -b responsivenavigation 8a75b001096536b3216022484af3026aa9c7bb5b
Switched to a new branch 'responsivenavigation'

C:\Users\jaimemontoya\[path]\app>git branch
  master
* responsivenavigation

In this case, 8a75b001096536b3216022484af3026aa9c7bb5b was and old commit belonging to the master branch.

Jaime Montoya
  • 6,915
  • 14
  • 67
  • 103
16

Using Sourcetree | The easiest way.

  • First, checkout the branch that you want to take the specific commit to make a new branch.
  • Then look at the toolbar, select Repository > Branch ... the shortcut is Command + Shift + B.
  • And select the specific commit you want to take. And give a new branch name then create a branch!

enter image description here

Pengguna
  • 4,636
  • 1
  • 27
  • 32
14

A great related question is: How the heck do you figure this out using the --help option of git? Let's try this:

git branch --help

We see this output:

NAME
       git-branch - List, create, or delete branches    

SYNOPSIS
       git branch [--color[=<when>] | --no-color] [-r | -a]
               [--list] [-v [--abbrev=<length> | --no-abbrev]]
               [--column[=<options>] | --no-column]
               [(--merged | --no-merged | --contains) [<commit>]] [--sort=<key>]
               [--points-at <object>] [<pattern>...]
       git branch [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
       git branch (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
       git branch --unset-upstream [<branchname>]
       git branch (-m | -M) [<oldbranch>] <newbranch>
       git branch (-d | -D) [-r] <branchname>...
       git branch --edit-description [<branchname>]

Gobbledegook.

Search through the subsequent text for the word "commit". We find this:

   <start-point>
       The new branch head will point to this commit. It may be given as a branch name, a
       commit-id, or a tag. If this option is omitted, the current HEAD will be used instead.

We're getting somewhere!

Now, focus on this line of the gobbledegook:

git branch [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]

Condense that to this:

git branch <branchname> [<start-point>]

And done.

Purplejacket
  • 1,808
  • 2
  • 25
  • 43
11

A quick way to do it on your Github repo would be as followed:

  • Find the specific commit from your branch
  • Beside the SHA id, click on 'Browse the repo at this point in the history'
  • Here you can create a new branch from this commit enter image description here
Vatsal Parekh
  • 248
  • 4
  • 12
10

No one mentioned git switch yet?

You can do:

git checkout <commit-hash>

Or by using a symbolic reference:

git checkout HEAD~3

And then:

git switch -c my-new-feature-branch

yshean
  • 331
  • 3
  • 9
  • I suspect because some of the answers here are >10 years old. I /think/ some of them have been rendered wrong by time as well. `git checkout -b` and `git branch` seem to always checkout the head for me, not the current detached position. – Gem Taylor Nov 16 '22 at 15:12
  • This is the modern answer since Git 2.23 which came out Aug 2019. – ewack Aug 23 '23 at 17:48
4

To do this in Eclipse:

  • Go to "Git Repository Exploring" Perspective.
  • Expand "Tags" and choose the commit from which you want to create branch.
  • Right click on the commit and choose "Create Branch".
  • Provide a branch name.

It will create a local branch for you. Then whenever you push your changes, your branch will be pushed to the remote server.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Saurabhcdt
  • 1,010
  • 1
  • 12
  • 24
4

Select Commit

For Git GUI users you can visualize all the history (if necessary) and then right click on the commit you wish to branch from and enter the branch name.

Enter Branch name

Visualize all the history

Ivan
  • 4,383
  • 36
  • 27
  • This will work only if user using any UI based OS like Windows & MAC – Saurabhcdt Feb 01 '19 at 10:11
  • 3
    That's right. My reply specifically starts with the words "For Git GUI users ...". I have not given a reply which will work for everyone - that is already done. I have given an alternative method which might be easier for a lot of people. I think the reason my reply is disliked is because its not a solution for everyone, but that already exists with a couple of thousand upvotes. However that doesn't make my reply wrong "For Git GUI users!". CREATE NEW BRANCH is there in the GUI. I doubt I am the only person in the world using it! – Ivan Feb 01 '19 at 10:33
3

I was able to do it like so:

git branch new_branch_name `git log -n 1 --skip 3 --format=%H`

Where you must enter the skip value. 0 is the latest, 1 is the previous, 2 is the commit before that, etc.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike Graf
  • 5,077
  • 4
  • 45
  • 58
3

You can do it in Stash.

  1. Click the commit
  2. On the right top of the screen click "Tag this commit"
  3. Then you can create the new branch from the tag you just created.
David Ruan
  • 534
  • 4
  • 18
3

Go to a particular commit of a git repository

Sometimes when working on a git repository you want to go back to a specific commit (revision) to have a snapshot of your project at a specific time. To do that all you need it the SHA-1 hash of the commit which you can easily find checking the log with the command:

git log --abbrev-commit --pretty=oneline

which will give you a compact list of all the commits and the short version of the SHA-1 hash.

Now that you know the hash of the commit you want to go to you can use one of the following 2 commands:

git checkout HASH

or

git reset --hard HASH

checkout

git checkout <commit> <paths>

Tells git to replace the current state of paths with their state in the given commit. Paths can be files or directories.

If no branch is given, git assumes the HEAD commit.

git checkout <path> // restores path from your last commit. It is a 'filesystem-undo'.

If no path is given, git moves HEAD to the given commit (thereby changing the commit you're sitting and working on).

git checkout branch //means switching branches.

reset

git reset <commit> //re-sets the current pointer to the given commit.

If you are on a branch (you should usually be), HEAD and this branch are moved to commit.

If you are in detached HEAD state, git reset does only move HEAD. To reset a branch, first check it out.

If you wanted to know more about the difference between git reset and git checkout I would recommend to read the official git blog.

L Y E S - C H I O U K H
  • 4,765
  • 8
  • 40
  • 57
  • 2
    thank you for your answer, FYI: This : `git log --abbrev-commit --pretty=oneline ` can be abbreviated to `git log --oneline` – Suhaib Feb 04 '19 at 02:02
1

With GitHub Desktop, display the history pane and right click on the commit you want, then choose the menu item "Create branch from commit".

jlaurens
  • 529
  • 5
  • 10
1

With Source Tree [Version currently used : 3.1.3]

  1. Open the History in Source Tree

Find history in source tree

  1. It will list all the commits in the main window
  2. Right-click on the desired commit and click on the Branch... option.
  3. Give a name for the branch in the new window and click Create branch.
  4. The new branch (local to your system) will come on the left side along with the other existing branches, which you can push to the origin to get it to the repository, that way it becomes available to other users.
Arun Sudhakaran
  • 2,167
  • 4
  • 27
  • 52
0

If you are looking for a command-line based solution, you can ignore my answer. I am gonna suggest you to use GitKraken. It's an extraordinary git UI client. It shows the Git tree on the homepage. You can just look at them and know what is going on with the project. Just select a specific commit, right-click on it and select the option 'Create a branch here'. It will give you a text box to enter the branch name. Enter branch name, select 'OK' and you are set. It's really very easy to use.

shamiul97
  • 315
  • 1
  • 3
  • 13
0

I used Git Gui (which comes with GIT for Windows).

  1. On the menu bar, open the Branch menu and select Create...
  2. Specify the name for the new branch in the Branch Name section
  3. Select Revision Expression: in the Start Revision section and enter the commit ID (I just used the 8 digit ID from Visual Studio and it worked)

Create New Branch dialog window

Trisped
  • 5,705
  • 2
  • 45
  • 58
-1

if you use source tree that is pretty straight forward.

  • Right click the commit from where you need to create a new branch
  • Click on 'branch'
  • Type name of new branch in the dialog appeared and click 'create branch'
Ibtisam Asif
  • 67
  • 1
  • 1
  • 7