我有一个Git仓库,看起来像这样:
A <- B <- C <- D <- HEAD
我希望将分支的头指向A,也就是说,我想让B、C、D和HEAD消失,并且我想让head成为A的同义词。
听起来我可以尝试revert(不适用,因为我已经在中间推送了更改),或者回滚。但是如何回滚多个提交?我一次一个还是一起回滚?顺序重要吗?
我有一个Git仓库,看起来像这样:
A <- B <- C <- D <- HEAD
我希望将分支的头指向A,也就是说,我想让B、C、D和HEAD消失,并且我想让head成为A的同义词。
听起来我可以尝试revert(不适用,因为我已经在中间推送了更改),或者回滚。但是如何回滚多个提交?我一次一个还是一起回滚?顺序重要吗?
git checkout -f A
git symbolic-ref HEAD refs/heads/master
git commit
git checkout master; git reset --hard A
是一样的吗?如果不是,你能否解释一下它的作用? - M.M这些方法都对我无效,所以我需要撤销三次提交(也就是最近的三次提交),于是我执行了以下操作:
git revert HEAD
git revert HEAD~2
git revert HEAD~4
git rebase -i HEAD~3 # pick, squash, squash
运作得非常好 :)
这里提供的方法可能不如其他方法优雅,但我一直使用get reset --hard HEAD~N
来撤销多个提交,其中N
是您要回退的提交数。
如果不确定确切的提交数,只需多次运行git reset --hard HEAD^
(回退一个提交),直到达到所需的状态即可。
我发现自己需要撤销一系列的提交,然后再次撤销它们,以帮助团队提交一个清晰的拉取请求,而不必强制推送到他们的目标分支(该分支是直接提交的)。
# checkout the branch that should be targeted
git checkout $branch_target
# revert the commits in $branch_target to some $count where
# $count is the number of commits to revert
# cut is used to slice just the commit hash field from each line of output
# xargs runs the command once for each line of input, reversing the commits!
git log --oneline -n $count | cut -d' ' -f1 | xargs git revert
# check out the branch which should be the source of the pull request
git checkout -b $branch_for_pull
# revert the revert commits
# $count is that same number of commits being reverted (again)
git log --oneline -n $count | cut -d' ' -f1 | xargs git revert
# push branches up and go off to create PR in whatever web UI
git push --set-upstream origin $branch_for_pull # it's new!
git checkout $branch_target
git push # if this branch wasn't pushed, just fix the issue locally instead..
因为这会按相反的顺序回滚所有从HEAD
到git log -n $count
的提交,所以它可以很好且干净地处理任意数量的提交。
在此状态下查看$branch_target
的视图
% git log --oneline origin/$branch_target
ffff006 (origin/$branch_target, $branch_target) Revert "first commit"
ffff005 Revert "second commit"
ffff004 Revert "third commit"
ffff003 third commit
ffff002 second commit
ffff001 first commit
查看此状态下的$branch_for_pull
分支
% git log --oneline origin/$branch_for_pull
ffff009 (origin/$branch_for_pull, $branch_for_pull) Revert "Revert "third commit""
ffff008 Revert "Revert "second commit""
ffff007 Revert "Revert "first commit""
ffff006 (origin/$branch_target, $branch_target) Revert "first commit"
ffff005 Revert "second commit"
ffff004 Revert "third commit"
ffff003 third commit
ffff002 second commit
ffff001 first commit
git reset --soft HEAD~(number of commits you'd like to revert)
git commit -m "The stuff you didn't like."
git log
# copy the hash of your last commit
git revert <hash of your last (squashed) commit>
当您想要推送更改时,请记得使用-f
标志,因为您已修改了历史记录。
git push <your fork> <your branch> -f
我真的希望避免硬重置,这就是我想出来的方法。
A -> B -> C -> D -> HEAD
git pull # Get latest changes
git reset --soft HEAD~4 # Set back 4 steps
git stash # Stash the reset
git pull # Go back to head
git stash pop # Pop the reset
git commit -m "Revert" # Commit the changes
git reset --hard commitID
git push -f branchname
git log --pretty=oneline | grep 'feature_name' | cut -d ' ' -f1 | xargs -n1 git revert --no-edit
git push -f HEAD~4:master
(假设远程分支是master)。是的,您可以像这样推送任何提交。 - u0b34a0f6aegit revert
命令撤销这些更改。请注意,这不会删除错误代码,而是创建一个新的提交来撤销它们。 - Jakub Narębskigit revert
将在history
中保留介入的工作。使用git checkout
和git reset --hard
来清除历史记录:请参见答案https://dev59.com/8HM_5IYBdhLWcg3wPAjU#38317763。 - WestCoastProjects