1192

I started working on my master branch thinking that my task would be easy. After a while I realized it would take more work and I want to do all this work in a new branch.

How can I create a new branch and take all these changes with me without dirtying master?

vsync
  • 118,978
  • 58
  • 307
  • 400
willcodejavaforfood
  • 43,223
  • 17
  • 81
  • 111
  • 19
    possible duplicate of [Move existing, uncommited work to a new branch in Git](http://stackoverflow.com/questions/1394797/move-existing-uncommited-work-to-a-new-branch-in-git) – Marijn Jun 19 '13 at 09:29
  • 2
    dup of http://stackoverflow.com/questions/2569459/git-create-a-branch-from-unstaged-uncommited-changes-on-master – andrej Jan 28 '14 at 12:51
  • 13
    Yes these are duplicate questions, but the wording is so different that I think this is useful to keep. Note the keywords here: `branch current changes` vs `existing uncommited branch`. Anyone who speaks English will immediately see that they are the same, but search engines probably won't. Keep this question. – SMBiggs Sep 25 '19 at 22:08
  • The latest/better answer: https://stackoverflow.com/a/2569513/1038812 – Matthew Jun 29 '21 at 00:56
  • @Matthew Thank you. I have reorganized [my answer below](https://stackoverflow.com/a/3899660/6309) to put *first* the 2.23 `git switch` (that I [previously documented back in 2019](https://stackoverflow.com/a/57066202/6309)) – VonC Jun 29 '21 at 05:51

6 Answers6

952

If you hadn't made any commit yet, only (1: branch) and (3: checkout) would be enough.
Or, in one command: git checkout -b newBranch

With Git 2.23+ (Q3 2019), the new command git switch would create the branch in one line (with the same kind of reset --hard, so beware of its effect):

# First, save your work in progress!
git stash

# Then, one command to create *and* switch to a new branch
git switch -f -c topic/wip HEAD~3

Or, as suggested in Alia's answer, use git switch -m, without git stash:

git switch -c topic/wip -m

--merge

If you have local modifications to one or more files that are different between the current branch and the branch to which you are switching, the command refuses to switch branches in order to preserve your modifications in context.

However, with this option, a three-way merge between the current branch, your working tree contents, and the new branch is done, and you will be on the new branch.

When a merge conflict happens, the index entries for conflicting paths are left unmerged, and you need to resolve the conflicts and mark the resolved paths with git add (or git rm if the merge should result in deletion of the path).


As mentioned in the git reset man page:

$ git stash                # (0) Save your work in progress
$ git branch topic/wip     # (1)
$ git reset --hard HEAD~3  # (2)  NOTE: use $git reset --soft HEAD~3 (explanation below)
$ git checkout topic/wip   # (3)
  1. You have made some commits, but realize they were premature to be in the "master" branch. You want to continue polishing them in a topic branch, so create "topic/wip" branch off of the current HEAD.
  2. Rewind the master branch to get rid of those three commits.
  3. Switch to "topic/wip" branch and keep working.

Again: new way (since 2019 and Git2.23) to do all that in one command:

git switch -f -c topic/wip HEAD~3

Note: due to the "destructive" effect of a git reset --hard command (it does resets the index and working tree. Any changes to tracked files in the working tree since <commit> are discarded), I would rather go with:

$ git reset --soft HEAD~3  # (2)

This would make sure I'm not losing any private file (not added to the index).
The --soft option won't touch the index file nor the working tree at all (but resets the head to <commit>, just like all modes do).


VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 6
    It's probably also worth noting that this wouldn't be a good idea if you have committed topic material to your master branch in a repository that other people pull from. Or at least, if you do need to do a reset you'll need to tell people that's what you are doing so the warnings from their next pull aren't too much of a shock. – Andrew Walker Oct 10 '10 at 09:54
  • I actually had not made any commits yet. So really easy, thanks mate – willcodejavaforfood Oct 10 '10 at 11:05
  • 58
    Note to future readers: read from bottom to top (or be sure to read the whole thing). `git reset --hard` will nuke your changes, and if they aren't committed yet they are unrecoverable! You may just need `git checkout -b …` – Conrad Meyer May 30 '12 at 18:58
  • 4
    @ConradMeyer Good point. I have edited the answer and put the `git checkout -b` first. – VonC May 30 '12 at 19:54
  • 6
    Why topic/branch?? why not just branchname, is there a special reason for this naming? just wondering. – Sam Stoelinga Jun 29 '12 at 06:50
  • 3
    @It is just a namespace naming convention (a way to easily classify branches, using **hierarchical** branch names to define namespaces): http://stackoverflow.com/a/2527436/6309. For instance, for issues: http://randyfay.com/content/pushing-and-deleting-git-topic-branches-screencast. You don't have to use a hierarchy when namming your branches. `topic_wip` would work too ;) – VonC Jun 29 '12 at 07:51
  • 1
    Should I always use "HEAD~3", or should the number depend on the number of commits to master? – qbolec Jun 01 '17 at 08:21
  • 1
    @qbolec No: you should rewind by number of commits right for your case. – VonC Jun 01 '17 at 09:37
  • After `git checkout -b newBranch` a push fails with the message ***`fatal: The current branch newBranch has no upstream branch`***. As far as I know this is the latest version of Git (2.16.3). What is so broken with this tool? – jww Apr 04 '18 at 08:18
  • @jww Would a `git push -u origin` newBranch work better? – VonC Apr 04 '18 at 08:34
  • 3
    A reminder to readers: when attempting a git operation you're not familiar with and whose outcome you're not certain about while dealing with data you'd be unhappy/devastated to lose (such as OP's changes present only in the local master branch), make a copy of your repo dir first. That way if things don't turn out as expected, you can always go back. – Ville Aug 29 '18 at 18:08
  • I don't understand why this answer has been accepted and voted so much since it starts by giving a command that actually destroys the changes that you want to keep. I suggest its author to fix that. Don't joke around with other people's work. – Johan Boulé Nov 05 '21 at 17:25
  • @JohanBoulé I (the author) agree with you, and have edited the answer to propose a way to save the work in progress first, then create a switch branch (without losing anything). – VonC Nov 05 '21 at 21:40
  • I didn't commit changes in local branch; so I just used `git checkout -b newBranch` – DanielBell99 Mar 01 '22 at 15:45
  • 1
    @StressedBoi_69420 That would work too, although `git switch` is the recommended command, now. – VonC Mar 01 '22 at 15:50
  • Ahh ok. Thank you, will research about that. Cheers lad – DanielBell99 Mar 01 '22 at 15:51
410

Like stated in this question: Git: Create a branch from unstagged/uncommited changes on master: stash is not necessary.

Just use:

git checkout -b feature/newbranch

Any uncommitted work will be taken along to the new branch.

If you try to push you will get the following message

fatal: The current branch feature/newbranch has no upstream branch. To push the current branch and set the remote as upstream, use

git push --set-upstream origin feature/newbranch

Just do as suggested to create the branch remotely:

git push --set-upstream origin feature/newbranch

Paul Verest
  • 60,022
  • 51
  • 208
  • 332
EeKay
  • 6,494
  • 3
  • 24
  • 24
113

Follow these steps:

  1. Create a new branch:

     git branch newfeature
    
  2. Checkout new branch: (this will not reset your work.)

    git checkout newfeature
    
  3. Now commit your work on this new branch:

    git commit -s
    

Using above steps will keep your original branch clean
and you dont have to do any 'git reset --hard'.

P.S. -s parameter for commit is for --signoff

Paul Verest
  • 60,022
  • 51
  • 208
  • 332
AvadhP
  • 1,421
  • 2
  • 12
  • 11
  • 3
    What does the '-s' do in step 3? – SMBiggs Dec 11 '15 at 16:54
  • 15
    @ScottBiggs It is unnecessary, but a practice some people follow. It is [short for "--signoff"](https://git-scm.com/docs/git-commit) and adds your user name to the commit for future people looking at the logs to know that you condoned this commit. – Frank Bryce Feb 03 '16 at 15:46
  • 10
    Nice answer, but no need for `-s` in step 3. – Mohammed Ali Jul 18 '16 at 16:37
45

Since you haven't made any commits yet, you can save all your changes to the stash, create and switch to a new branch, then pop those changes back into your working tree:

git stash  # save local modifications to new stash
git checkout -b topic/newbranch
git stash pop  # apply stash and remove it from the stash list
Six
  • 5,122
  • 3
  • 29
  • 38
Ether
  • 53,118
  • 13
  • 86
  • 159
  • 13
    or as VonC pointed out 'git checkout -b newbranch' and skip the stash – willcodejavaforfood Oct 10 '10 at 15:46
  • 1
    @will: I was thinking that creating a new branch would overwrite any uncommitted changes you had, but if this is not the case, yes you can skip the stash. – Ether Oct 10 '10 at 15:58
  • 1
    I tried it and it worked fine, git is very thoughtful and wont overwrite any local changes – willcodejavaforfood Oct 10 '10 at 16:35
  • 2
    I assume it was a typo but just a heads up that `git stash push` is not a command. You would presumably want to use `git stash` or `git stash save`. If you want to include untracked files in the stash, use the `--include-untracked` option. Likewise, if you want to include both untracked and ignored files in the stash, use the `--add` option instead. – Six Oct 10 '15 at 13:43
  • in case you have created the branch already, this is helpful. – Surely Mar 10 '16 at 06:32
31

I see that the most of the answers here are outdated. There is no need to do stash and pop with the new switch command.

git switch -c new_branch -m

will create a new branch named "new_branch", switch to it it and bring along all uncommitted changes as modified files. You can then continue working on the changes or commit them to the new branch etc.

AliA
  • 690
  • 6
  • 8
  • Good point. Upvoted. I have referenced your option in my [own answer](https://stackoverflow.com/a/3899660/6309) – VonC Aug 02 '22 at 06:26
15

To add new changes to a new branch and push to remote:

git branch branch/name
git checkout branch/name
git push origin branch/name

Often times I forget to add the origin part to push and get confused why I don't see the new branch/commit in bitbucket

Patrick Schaefer
  • 821
  • 10
  • 20