忘记转移到另一个分支而不是使用Git



我在rails项目中使用Git

今天我做了很多更改,但我忘记了移动到another branch,所以所有这些更改都在master分支中,但尚未提交

这是我执行git status命令时得到的结果:

# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   app/controllers/sessions_controller.rb
#   modified:   app/controllers/users_controller.rb
#   modified:   app/helpers/sessions_helper.rb
#   modified:   app/models/user.rb
# .....
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   app/assets/javascripts/password_resets.js.coffee
#   app/assets/stylesheets/password_resets.css.scss
#   app/controllers/password_resets_controller.rb
# .....
# ......
no changes added to commit (use "git add" and/or "git commit -a")

我如何解决这个错误,并将所有这些未跟踪的文件从master移动到另一个已经存在的分支?非常感谢。

只需创建一个新分支,然后提交,例如:

git checkout -b my_branch
git commit -am "My commit."

如果下面没有标记为C1、C2等的提交

你的情况很简单;只需使用Henrik N的答案。

如果有跟踪分支

您更新的问题/评论表明您已提交更改和未提交更改,并且您在某个跟踪分支上完成了所有更改,例如跟踪origin/mastermaster或跟踪origin/develdevel,但您尚未推送任何更改。(我假设master,但您可以将每个master更改为下面的功能/开发/任何分支名称。)

如图所示,您的回购的提交树和工作目录/索引现在看起来如下:

M1 -...- M5 -- M6                    <-- origin/master
                 
                  C1 -- C2           <-- master, HEAD=master
                          
                           i, w      <-- "index" and working-tree files

这里,i是索引中的内容(git add dir/file1git rm file2等),git status显示为changes to be committedw是工作目录中的内容,git status显示为changes not staged for commit

以下是您想要的外观:

M1 -...- M5 -- M6                    <-- master, origin/master
                 
                  C1 -- C2           <-- my_branch, HEAD=my_branch
                          
                           i, w      <-- "index" and working-tree files

请记住,分支标签就像便签("黄色便签"或"Post It®便签"等):它们上面写着一个名字,然后粘贴到提交中。因此,您要做的是添加一个新的便签my_branch,指向提交C2,并使HEAD引用新的分支名称:

git checkout -b my_branch

这将使用HEAD的上一个值来命名my_branch粘贴到的提交。由于该提交是C2,因此这里同时有mastermy_branch。然后它重写HEAD以指向名称my_branch。现在你有了:

M1 -...- M5 -- M6                    <-- origin/master
                 
                  C1 -- C2           <-- master, my_branch, HEAD=my_branch
                          
                           i, w      <-- "index" and working-tree files

现在,您需要将标记为master的便签移回origin/master所指向的位置。有两种方法可以做到这一点,使用git reset或使用git branch。使用git reset比较困难,所以让我们使用git branch:

git branch -f master origin/master

-f(强制)标志告诉git branch更改现有的粘性注释,而不是因为它存在而失败,origin/master给出了master应该指向哪个提交:所以git将标签从C2上剥离并粘贴到M6上,这样您就得到了所需的设置(第二张图)。


总结:只有两个命令:

git checkout -b my_branch           # create new branch and change HEAD
git branch -f master origin/master  # restore master to origin/master

现在,您可以像往常一样在分支my_branch上签入更改了。(根据需要git addgit rmgit commit。)这将添加一个新的提交C3:

M1 -...- M5 -- M6                    <-- master, origin/master
                 
                  C1 -- C2 -- C3     <-- my_branch, HEAD=my_branch

如果没有跟踪分支怎么办

好吧,没关系,只是有点难。返回到"现在拥有"one_answers"需要"图表。在这些图中,我标记为M6的提交就是您希望master命名的提交。您现在必须找到M6。委员会有这些永远不会改变的长十六进制数字(SHA-1)"真实名称",例如5e013711f5d6eb3f643ef562d49a131852aa4aa1。(git rev-parse HEAD将显示当前的"真名",即HEAD,提交。

名称有很多选择,但让我们坚持使用git loggit log --oneline中的数字。后者会给你这样的东西:

97206f5 peerish: set socket options earlier
4881af5 add semtest.c
b3f8bea fdm: repair example

其中数字是缩写的SHA-1,文本是提交消息的第一行。由于日志以相反的顺序显示,所以最上面的一行是最近的提交(上例中的C2),然后每一行都是下一行(嗯,合并更复杂,但足够接近)。

假设根据上面的内容,您可以立即判断出我标记为M6的提交是b3f8bea,也就是说,您需要跳过两次提交。只需将该值作为最后一个参数提供给git branch:

git branch -f master b3f8bea

如果你的回购规模庞大且陈旧,或者有很多合并提交,你可能希望你的日志包含更多的"装饰"。我从很久以前的某个地方得到了这些别名:

[alias]
    lol = git log --graph --decorate --oneline
    lola = git log --graph --decorate --oneline --all

以便我可以运行CCD_ 53和CCD_。

或者,如果您确定确实有两个提交,那么master~2(在本例中,在添加my_branchmy_branch~2之后)将获得相同的SHA-1。git rev-parse命令向您精确显示任何给定名称的SHA-1"含义"。在我这里的一个回购中,HEAD~2origin/featureX:相同

$ git rev-parse HEAD~2
0f5a13497dd3da8aff8e452c8f56630f83253e79
$ git rev-parse origin/featureX
0f5a13497dd3da8aff8e452c8f56630f83253e79

但一般来说,git log(或git lol等)会为您提供原始SHA-1,您可以根据需要从中添加标签。

您只需要创建新的分支。

创建分支后,所有更改都将在新分支中。

然后从主上清理你的旧东西

// Checkout new branch
git checkout -b my_branch
// Prepare files for commit
git add .
// Commit changes
git commit -m "Your commit message"
// delete the dirty master
git branch -D master
// Now we are going to clean your changes from the master branch
// the -f is important in case you skipped the previous command to delete your master
git checkout -f master 

最新更新