Git:根据主服务器上未上演的/未提交的更改创建分支


991

上下文:我正在为master添加一个简单的功能。几分钟后,我意识到这并不是那么简单,进入一个新分支应该更好。

这总是发生在我身上,我不知道如何切换到另一个分支,并在我离开主分支的情况下进行所有这些未提交的更改。我本来git stash && git stash branch new_branch可以做到的,但这就是我所得到的:

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ echo "hello!" > testing 

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git stash
Saved working directory and index state WIP on master: 4402b8c testing
HEAD is now at 4402b8c testing

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ git stash branch new_branch
Switched to a new branch 'new_branch'
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b)

~/test $ git s
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git checkout master
M   testing
Switched to branch 'master'

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

你知道有没有办法做到这一点?


1
尽管有一个更简单的解决方案,但是您可以指定所得到的结果与您想要的结果有何不同?
Gauthier '04

2
通过执行上面的操作或底部的答案,未提交的更改将同时出现在master和新分支上。我只希望它们在新分支上,所以我可以签出master并处理另一件事,而不会使这些更改浮在水面
knoopx 2010年

1
看到我编辑的答案。如果要签出干净的母版,则需要在新分支上提交本地更改。本地更改只是当前HEAD与磁盘上文件之间的差异。这些对本地文件的更改未进行版本控制,如果您以后想要检索它们,则需要告诉git将它们保存在某个位置。
Gauthier '04

Answers:


1207

不需要藏起来。

git checkout -b new_branch_name

不会影响您的本地更改。它只是从当前HEAD创建分支,并在此处设置HEAD。所以我想这就是您想要的。

---编辑以解释结帐母版的结果---

您是否因为checkout master不放弃所做的更改而感到困惑?

由于更改仅是本地的,因此git不想让您太容易丢失它们。更改分支后,git不会覆盖您的本地更改。您的结果checkout master是:

M   testing

,这意味着您的工作文件不干净。git确实更改了HEAD,但没有覆盖本地文件。因此,即使您处于开启状态,您的最后状态仍然显示本地更改master

如果您确实要放弃本地更改,则必须使用强制结帐-f

git checkout master -f

由于您的更改从未提交,因此您将丢失它们。

尝试回到您的分支,提交更改,然后再次签出主数据库。

git checkout new_branch
git commit -a -m"edited"
git checkout master
git status

M第一次结帐后,您应该会收到一条消息,但在之后,您将再收到一条消息checkout master,并且git status不应该显示任何已修改的文件。

---编辑以消除有关工作目录(本地文件)的混乱---

在回答您的第一个评论时,本地更改只是...本地。Git不会自动保存它们,您必须告诉它保存它们以备后用。如果您进行更改并且未明确提交或隐藏它们,则git不会对它们进行版本控制。如果更改HEAD(checkout master),则本地更改不会保存,因为未保存。


32
令人困惑的是,git的手册页指出git checkout“更新工作树中的文件以匹配索引或指定树中的版本。”。假设您在文件系统中所做的更改之后将消失。没有任何机会让他们回来。即使您说他们不会,也会留下非常不好的感觉。我不相信这在所有。文档真的很糟糕,或者git的默认行为真的很危险。在这种情况下,您不必非要依靠某种“自动”启发法来检测您不想丢失所做的更改。
Evi1M4chine 2013年

16
如果您要签出将覆盖本地更改的提交(如果当前提交和目标提交之间的历史记录触及了本地修改的文件),则git拒绝。仅当checkout与您的本地更改不冲突时,结帐才有效,并仅保留本地更改。我确实理解这种不好的感觉,手册页可能应该说“更新工作树中未修改的文件”。另一方面,Git并不会很容易丢失本地更改。git checkout或者只让您进行本地更改,或者在发生冲突时拒绝。
Gauthier

1
好吧,如何在不进行本地更改的情况下结帐到另一个分支?
アレックス

5
@Alex git checkout <other_branch> -f。您将丢失本地更改,而不会发出警告。
Gauthier 2014年

2
@ Evi1M4chine第一个。该文档非常糟糕的。
Qwertie

62

尝试:

git stash
git checkout -b new-branch
git stash apply

6
这与仅自己执行“ git checkout -b new-branch”有所不同吗?
Adrian Mouat 2013年

我不认为答案最初是写的,但是我可能是错的。不幸的是,由于我的工作环境,最近几年我一直在使用perforce,因此现在无法证明它的准确性。
Grant Limberg

6
或者代替最后两个步骤:git stash branch new-branch
rethab 2014年

1
不再需要git stash
kory

当您已经有一个分支要放置所有内容时,stash对我来说很有意义:(最终git fetch --all;以便在源头获得远程分支)git stash; git checkout <现有分支>; git stash适用;
Paolof76

24

您可以做两件事:

git checkout -b sillyname
git commit -am "silly message"
git checkout - 

要么

git stash -u
git branch sillyname stash@{0}

git checkout -<-破折号是您上一个分支的快捷方式)

git stash -u<- -u表示它还可以进行未分级的更改)


7

如果您使用的是GitHub Windows客户端(就像我一样),并且您要进行未提交的更改并希望移至新分支,则可以通过GitHub客户端简单地“创建新分支”。它将切换到新创建的分支并保留您的更改。

在此处输入图片说明


会在创建新分支之前存储更改,因此不会保留更改(在Mac OS上为223版)
Fernando Gallego

2

如果要将当前分支上的当前未提交的更改移至新分支,请使用以下命令创建一个新分支,并自动复制未提交的更改。

git checkout -b branch_name

这将从当前分支(假设它是主分支)创建一个新分支,复制未提交的更改并切换到新分支。

将更改提交到新分支。

git commit -m "First commit"

由于创建了新分支,因此在将其推送到远程之前,您需要设置上游。使用以下命令设置上游并将其推送到远程。

git push --set-upstream origin feature/feature/NEWBRANCH

按下此命令后,将在远程创建一个新分支,并将新的本地分支推送到远程。

现在,如果您想放弃master分支中未提交的更改,请使用:

git checkout master -f

这将丢弃任何未提交的本地结帐更改。


这个答案与公认的答案有何不同?
kometen

尽管所接受的答案有些重叠,但这提供了简单的逐步指南,还包括远程推送新分支所需的操作。简单,清晰和有用。
贾尔坦(Kjartan)

这个答案很清楚,对我有很大帮助。
瓦迪姆

0

在最新的Windows GitHub客户端中,如果您尚未提交更改,请选择创建一个新分支。 它提示您如何处理这种确切的情况:

在此处输入图片说明

如果您只是简单地切换分支,同样适用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.