ChatGPT解决这个技术问题 Extra ChatGPT

Create Git branch with current changes

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?

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.
The latest/better answer: stackoverflow.com/a/2569513/1038812
@Matthew Thank you. I have reorganized my answer below to put first the 2.23 git switch (that I previously documented back in 2019)

V
VonC

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

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)

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. Rewind the master branch to get rid of those three commits. 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).


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.
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 …
@ConradMeyer Good point. I have edited the answer and put the git checkout -b first.
Why topic/branch?? why not just branchname, is there a special reason for this naming? just wondering.
@It is just a namespace naming convention (a way to easily classify branches, using hierarchical branch names to define namespaces): stackoverflow.com/a/2527436/6309. For instance, for issues: randyfay.com/content/…. You don't have to use a hierarchy when namming your branches. topic_wip would work too ;)
P
Paul Verest

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


You'll get the 'no upstream branch' error only if you push the new branch, not when you commit the new work.
@sam I've amended the answer accordingly
P
Paul Verest

Follow these steps:

Create a new branch: git branch newfeature Checkout new branch: (this will not reset your work.) git checkout newfeature 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


What does the '-s' do in step 3?
@ScottBiggs It is unnecessary, but a practice some people follow. It is short for "--signoff" and adds your user name to the commit for future people looking at the logs to know that you condoned this commit.
Nice answer, but no need for -s in step 3.
S
Six

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

or as VonC pointed out 'git checkout -b newbranch' and skip the stash
@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.
I tried it and it worked fine, git is very thoughtful and wont overwrite any local changes
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.
in case you have created the branch already, this is helpful.
P
Patrick Schaefer

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