简体   繁体   English

将现有未提交的工作移动到 Git 中的新分支

[英]Move existing, uncommitted work to a new branch in Git

I started some work on a new feature and after coding for a bit, I decided this feature should be on its own branch.我开始了一些新功能的工作,在编码了一点之后,我决定这个功能应该在它自己的分支上。

How do I move the existing uncommitted changes to a new branch and reset my current one?如何将现有未提交的更改移动到新分支并重置当前分支?

I want to reset my current branch while preserving existing work on the new feature.我想重置我当前的分支,同时保留关于新功能的现有工作。

Update 2020 / Git 2.23 2020 年更新/Git 2.23

Git 2.23 adds the new switch subcommand in an attempt to clear some of the confusion that comes from the overloaded usage of checkout (switching branches, restoring files, detaching HEAD, etc.) Git 2.23 添加了新的switch子命令,试图消除由于checkout的超载使用(切换分支、恢复文件、分离 HEAD 等)而导致的一些混乱。

Starting with this version of Git, replace the checkout command with:从这个版本的 Git 开始,将 checkout 命令替换为:

git switch -c <new-branch>

The behavior is identical and remains unchanged.行为是相同的并且保持不变。


Before Update 2020 / Git 2.23 2020 年更新/Git 2.23 之前

Use the following:使用以下内容:

git checkout -b <new-branch>

This will leave your current branch as it is, create and checkout a new branch and keep all your changes.这将使您当前的分支保持原样,创建并签出一个新分支并保留您的所有更改。 You can then stage changes in files to commit with:然后,您可以暂存文件中的更改以提交:

git add <files>

and commit to your new branch with:并提交到您的新分支

git commit -m "<Brief description of this commit>"

The changes in the working directory and changes staged in index do not belong to any branch yet.工作目录中的更改和索引中暂存的更改尚不属于任何分支 This changes the branch where those modifications would end in.这会更改这些修改将结束的分支。

You don't reset your original branch, it stays as it is.您不会重置原始分支,它会保持原样。 The last commit on <old-branch> will still be the same. <old-branch>上的最后一次提交仍然是相同的。 Therefore you checkout -b and then commit.因此,您checkout -b然后提交。

Alternatively:或者:

  1. Save current changes to a temp stash:将当前更改保存到临时存储:

    $ git stash

  2. Create a new branch based on this stash, and switch to the new branch:基于此存储创建一个新分支,并切换到新分支:

    $ git stash branch <new-branch> stash@{0}

Tip: use tab key to reduce typing the stash name.提示:使用 tab 键减少输入存储名称。

If you have been making commits on your main branch while you coded, but you now want to move those commits to a different branch, this is a quick way:如果您在编写代码时一直在主分支上进行提交,但现在想将这些提交移动到不同的分支,这是一种快速的方法:

  1. Copy your current history onto a new branch, bringing along any uncommitted changes too:将您当前的历史记录复制到一个新分支上,同时带来任何未提交的更改:

     git checkout -b <new-feature-branch>
  2. Now force the original "messy" branch to roll back: (without switching to it)现在强制原来的“混乱”分支回滚:(不切换到它)

     git branch -f <previous-branch> <earlier-commit-id>

    For example:例如:

     git branch -f master origin/master

    or if you had made 4 commits:或者如果你做了 4 次提交:

     git branch -f master HEAD~4

Warning: git branch -f master origin/master will reset the tracking information for that branch.警告: git branch -f master origin/master重置该分支的跟踪信息 So if you have configured your master branch to push to somewhere other than origin/master then that configuration will be lost.因此,如果您已将master分支配置为推送到origin/master以外的其他位置,那么该配置将丢失。

Warning: If you rebase after branching, there is a danger that some commits may be lost, which is described here .警告:如果你在分支后变基,有一些提交可能会丢失的危险,这在此处描述 The only way to avoid that is to create a new history using cherry-pick.避免这种情况的唯一方法是使用cherry-pick 创建新的历史记录。 That link describes the safest fool-proof method, although less convenient.该链接描述了最安全的万无一失的方法,尽管不太方便。 (If you have uncommitted changes, you may need to git stash at the start and git stash pop at the end.) (如果您有未提交的更改,您可能需要在开始时 git git stash并在结束时git stash pop 。)

The common scenario is the following: I forgot to create the new branch for the new feature, and was doing all the work in the old feature branch.常见的情况如下:我忘记为新功能创建新分支,而在旧功能分支中完成所有工作。 I have commited all the "old" work to the master branch, and I want my new branch to grow from the "master".我已将所有“旧”工作提交给主分支,我希望我的新分支从“主”发展而来。 I have not made a single commit of my new work.我的新工作没有一次提交。 Here is the branch structure: "master"->"Old_feature"这是分支结构:“master”->“Old_feature”

git stash 
git checkout master
git checkout -b "New_branch"
git stash apply

If you commit it, you could also cherry-pick the single commit ID.如果您提交它,您还可以挑选单个提交 ID。 I do this often when I start work in master, and then want to create a local branch before I push up to my origin/.当我开始在 master 中工作时,我经常这样做,然后想在我推送到我的 origin/ 之前创建一个本地分支。

git cherry-pick <commitID>

There is alot you can do with cherry-pick, as described here , but this could be a use-case for you.如此处所述,您可以使用cherry-pick 做很多事情,但这对您来说可能是一个用例。

There is actually a really easy way to do this with GitHub Desktop now that I don't believe was a feature before.实际上,使用 GitHub Desktop 有一种非常简单的方法可以做到这一点,现在我不相信这是一个功能。

All you need to do is switch to the new branch in GitHub Desktop, and it will prompt you to leave your changes on the current branch (which will be stashed), or to bring your changes with you to the new branch.您需要做的就是切换到 GitHub Desktop 中的新分支,它会提示您将更改留在当前分支(将被隐藏),或者将您的更改带到新分支。 Just choose the second option, to bring the changes to the new branch.只需选择第二个选项,将更改带到新分支。 You can then commit as usual.然后,您可以像往常一样提交。

GitHub 桌面

This may be helpful for all using tools for GIT这可能对所有使用 GIT 工具的人都有帮助

Command命令

Switch branch - it will move your changes to new-branch.切换分支 - 它会将您的更改移动到新分支。 Then you can commit changes.然后您可以提交更改。

 $ git checkout -b <new-branch>

TortoiseGIT乌龟GIT

Right-click on your repository and then use TortoiseGit->Switch/Checkout右键单击您的存储库,然后使用 TortoiseGit->Switch/Checkout

在此处输入图像描述 在此处输入图像描述

SourceTree源树

Use the "Checkout" button to switch branch.使用“结帐”按钮切换分支。 You will see the "checkout" button at the top after clicking on a branch.单击分支后,您将在顶部看到“结帐”按钮。 Changes from the current branch will be applied automatically.当前分支的更改将自动应用。 Then you can commit them.然后你可以提交它们。

在此处输入图像描述

Option 1 (with an existing branch)选项 1(现有分支)

git stash (from main/any-branch)
git checkout your-existing-branch
git stash apply 

Option 2 (creating a new branch)选项 2(创建新分支)

git switch -c your-new-branch

I used @Robin answer & listing all that I did,我使用@Robin回答并列出我所做的一切,

git status                               <-- review/list uncommitted changes
git stash                                <-- stash uncommitted changes
git stash branch <new-branch> stash@{1}  <-- create a branch from stash
git add .                                <-- add local changes
git status                               <-- review the status; ready to commit
git commit -m "local changes ..."        <-- commit the changes
git branch --list                        <-- see list of branches incl the one created above
git status                               <-- nothing to commit, working tree (new-branch) is clean
git checkout <old-branch>                <-- switch back

! If the repo has more than one stash, see which one to apply to the new-branch:如果 repo 有多个存储,请查看将哪一个应用于新分支:

git stash list  
  stash@{0}: WIP on ...  
  stash@{1}: WIP on ...

and inspect the individual stash by,并通过以下方式检查个人藏匿处,

git stash show stash@{1}

Or inspect all stashes at once:或一次检查所有藏匿处:

git stash list -p

3 Steps to Commit your changes提交更改的 3 个步骤

Suppose you have created a new branch on GitHub with the name feature-branch .假设您在 GitHub 上创建了一个名为feature-branch的新分支。

在此处输入图像描述

FETCH拿来

    git pull --all         Pull all remote branches
    git branch -a          List all branches now

Checkout and switch to the feature-branch directory.签出并切换到功能分支目录。 You can simply copy the branch name from the output of branch -a command above您可以简单地从上面的 branch -a 命令的输出中复制分支名称

git checkout -b feature-branch

VALIDATE证实

Next use the git branch command to see the current branch.接下来使用 git branch 命令查看当前分支。 It will show feature-branch with * In front of it它将在前面显示带有 * 的功能分支

git branch         

COMMIT犯罪

git add .   add all files
git commit -m "Rafactore code or use your message"

Take update and the push changes on the origin server在源服务器上进行更新和推送更改

 git pull origin feature-branch
 git push origin feature-branch

This is the only answer that tells you to use git stash -k , which you will need...这是告诉您使用git stash -k的唯一答案,您将需要...

if you already spent an hour with git add -p如果你已经用git add -p花了一个小时

and then decided you want to test what you added to the index before doing the actual commit.然后决定在进行实际提交之前测试您添加到索引中的内容。 In that case do not use plain git stash !在这种情况下,不要使用普通的git stash

Instead do:而是这样做:

git stash -k

That keeps the index and removes the rest that is still in the working directory and wasn't added to the index yet.这会保留索引并删除仍在工作目录中且尚未添加到索引中的其余部分。 Exactly what you want.正是你想要的。

Now you can try to compile/test and commit.现在您可以尝试编译/测试和提交。 Ie IE

make
git commit -m 'Yay!'

Then get back the uncommitted changes with然后取回未提交的更改

git stash pop

If you discover that it does NOT compile however, then making changes and adding those also the index and committing that might confuse git stash pop .但是,如果您发现它无法编译,则进行更改并添加索引并提交可能会使git stash pop混淆。 It isn't that good when it comes to merging.合并的时候就不好说了。 In that case you probably should just commit anyway;在这种情况下,您可能应该无论如何都应该提交; thus:因此:

make
git commit -m 'Grrrr'

Then create a new branch,然后新建一个分支,

git switch -c tmpbranch

do your work there (changing code, doing testing and more commits)在那里做你的工作(改变代码,做测试和更多的提交)

/* blood sweat and tears */

Once everything works commit it to the new branch一旦一切正常,将其提交到新分支

commit -a -m 'Finally!'

go back to the old branch and then do the git stash pop with the same working directory as where you was when you pushed to the stash.返回旧分支,然后使用与推送到存储时相同的工作目录执行git stash pop

git checkout youknowwhatbranchyouwereonright
git stash pop

Commit that too, otherwise you can't merge the tmpbranch.也提交,否则你不能合并 tmpbranch。 Then merge the temporary branch that you created.然后合并您创建的临时分支。

git commit -a -m 'Still working on this.'
git merge tmpbranch
/* fix collisions and commit */

Now you can do a rebase to put the 'Still working on this' at the top and squash/fixup the rest into a single comment.现在您可以进行变基以将“仍在处理此问题”放在顶部,并将其余部分压缩/修复为单个评论。 For example例如

git rebase -i

might give you:可能会给你:

pick 540623a Grrr
pick a8589d3 Still working on this.
pick d3b602c Finally

Then change that to:然后将其更改为:

reword 540623a Grrr
fixup d3b602c Finally
pick a8589d3 Still working on this.

And finally undo the last commit (the 'Still working on this')最后撤消最后一次提交(“仍在处理此问题”)

git reset HEAD~1

For those using Visual Studio Community 2022 (and possibly earlier versions) when you have uncommitted changes then create a new branch, you'll see a dialog like this:对于那些使用 Visual Studio Community 2022(可能还有更早版本)的用户,当您有未提交的更改然后创建新分支时,您将看到如下对话框:

在此处输入图像描述

Just select the first option Bring the changes to '[your-new-branch-name]' and click Continue checkout .只需选择第一个选项将更改带到 '[your-new-branch-name]'并单击Continue checkout The new branch will be created and you can proceed to commit your changes there.新分支将被创建,您可以继续在那里提交您的更改。

You can also create bash aliases to do all of this.您还可以创建 bash 别名来执行所有这些操作。

This will create new commands...这将创建新命令...

  • gitco <branch> - checks out the specified branch, taking your current changes with you gitco <branch> - 检出指定的分支,带走你当前的更改
  • gitconew <new branch name> - creates a new branch with the specified name (branched off of master) taking your current changes with you gitconew <new branch name> - 创建一个具有指定名称的新分支(从 master 分支出来)并带走您当前的更改

Here are the steps to set up the aliases...以下是设置别名的步骤...

  1. Add the following to ~/.bash_profile将以下内容添加到~/.bash_profile
gitco ()
{
  git stash && git checkout $1 && git stash apply
}

gitconew ()
{
  git stash && git checkout master && git checkout -b $1 && git stash apply
}
  1. Run source ~/.bash_profile to reload the profile运行source ~/.bash_profile以重新加载配置文件

Now you can run the gitco and gitconew alias commands.现在您可以运行gitcogitconew别名命令。

Here is some more info on bash aliases -> https://linuxize.com/post/how-to-create-bash-aliases/这是有关 bash 别名的更多信息 -> https://linuxize.com/post/how-to-create-bash-aliases/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM