[TOC]
在错误的分支开发了新功能处理方法
整理自:https://segmentfault.com/a/1190000023924418
1. 新功能还没有在本地commit提交
在这种情况下我们可以在当前分支下使用:
git stash
这个命令表示把我们当前修改的内容暂存起来,然后我们的工作区就恢复到在没有开发新功能之前的样子。
这个时候我们需要切换到正确的工作分支,然后运行命令:
git stash apply
这个命令表示把我们之前暂存的内容,应用到当前分支。这样我们就相当于把修改的内容从一个分支移动到了另一个分支。
2. 新功能已经在本地提交了,但是还没有push
到远程仓库
如果新开发的功能已经在本地提交了,但是我们开发的这个分支是一个错误的分支。这个时候根据情况的不同,可以有两种处理的方式。
2.1 新的功能需要添加在一个新的分支
首先我们需要知道在我们添加新功能之前,当前分支处于哪一个提交。可以运行命令:
git log --oneline
查看当前分支的提交,可以看到有以下内容的输出:
085095f (HEAD -> master) update 5
47e52ae update 3
14fefac update 2
fd01444 add README.md
3c76ad1 init
找到我们添加新功能时,当前分支所处的提交。假如是fd01444
,那么我们接下来要做的操作就是将HEAD
指针指向fd01444
,也就是把我们当前分支已提交的内容重置到我们开发新功能之前的样子。我们需要运行下面的命令:
git reset fd01444 # fd01444是某次提交的hash值
如果没有指明重置的模式的话,默认会使用--mixed
模式,这样的话我们在fd01444
这次提交之后的所有提交都会被重置为没有提交的状态。接下来我们需要把这些新开发的功能迁移到一个新的分支。这时候我们可以使用下面的命令进行操作:
git checkout -b <newbranch>
这样我们就创建了一个新的分支,并且把新添加的功能也都迁移了过去,接下来就是常规的添加和提交操作了。
2.2 新功能需要添加在另一个分支上
如果我们需要把当前添加的新功能迁移到另一个已经存在的分支,那么我们需要做的前几个步骤跟上面的操作是一样的:
git log --oneline # 查找新功能开发之前的提交
git reset <commit hash> # 将当前分支重置到新功能开发之前的提交
接下来我们现在的状态就回到了新功能还没有提交的状态,那么就可以继续使用git stash
相关的命令去操作了。
我们还有另外一个方法也能够将已提交到当前分支的功能添加到另一个分支上,那就是使用git cherry-pick
命令。首先我们还是先用git log --oneline
查找当前已提交的功能的hash值,然后切换到目标分支,运行命令:
git cherry-pick <commit hash>
这样就把我们在另一个分支开发的功能,添加到我们想要的分支了。如果有冲突的话,需要手动处理一下冲突。然后我们回到最初的分支,再次运行git reset <commit hash>
命令,把已提交的内容进行重置,然后运行命令:
git checkout -- .
把当前分支没有添加到暂存区的内容都清除掉,这样也可以达到我们上面所说的,把新功能添加到另一个分支的目的。
3. 新功能已经在本地提交了,且push
到了远程仓库
第三种情况就是,我们已经把新开发的功能push
到远程的仓库了,但是我们忽然发现新功能不应该在这个分支开发,我们这个时候应该怎么办呢?
首先我们应该保持当前的工作区是没有修改的,是一个干净的状态。不然使用撤销命令的时候会提示你需要把当前的文件内容变更先提交或者生成快照。当我们的工作区的状态是干净的时候,我们就可以进行撤销操作了。
首先需要知道我们应该撤销那一次提交的状态。使用git log --oneline
查看要撤销的提交的索引,然后运行下面的命令:
git revert <commit>
这个时候命令运行的终端会进入编辑器模式,让你填写提交的信息。当然你也可以使用参数--no-edit
这样就不会在进行撤销操作的时候打开编辑模式了。
如果需要撤销的提交比较多的话,我们可以使用..
表示一个提交记录的范围。比如c1..c2
就表示c2
的可达提交,且排除c1
的可达提交。所谓可达的提交指的是:提交本身及其祖先链中提交的集合。
我们可以举个例子:
... a - b - c - d - HEAD
如果上面表示的是某个分支的提交记录,那么对于b..d
表示的就是c d
这两个提交,对于a..d
表示的就是b c d
这三个提交。如果大家想了解更多相关的内容,可以在git-rev-list这里深入的学习一下。
所以我们如果想快速的撤销一段范围的提交的话,可以运行类似下面这样的命令:
git revert 54dc134..a72d612 --no-edit
上述命令的54dc134
就表示c1
,a72d612
就表示c2
,--no-edit
表明我们在运行撤销操作的时候不打开编辑模式。
我们如果需要对远程的分支进行撤销的话,首先考虑的就是使用git revert
命令,因为git revert
命令不会修改历史的提交记录,只是在原来的提交基础上添加新的提交,所以不会造成代码的丢失。在多人合作的情况下使用git revert
命令撤销push
到远程的操作还是很有必要的。