问题
In Git, I understand that a branch is a pointer to a commit.
How do I make a specific branch point to a specific commit? Say I want to make master
point at 1258f0d0aae...
, how do I do that?
回答1:
You can make master
point at 1258f0d0aae
this way:
git checkout master
git reset --hard 1258f0d0aae
But you have to be careful about doing this. It may well rewrite the history of that branch. That would create problems if you have published it and other people are working on the branch.
Also, the git reset --hard
command will throw away any uncommitted changes (i.e. those just in your working tree or the index).
You can also force an update to a branch with:
git branch -f master 1258f0d0aae
... but git won't let you do that if you're on master
at the time.
回答2:
If you are currently not on branch master, that's super easy:
git branch -f master 1258f0d0aae
This does exactly what you want: It points master
at the given commit, and does nothing else.
If you are currently on master, you need to get into detached head state first. I'd recommend the following two command sequence:
git checkout 1258f0d0aae #detach from master
git branch -f master HEAD #exactly as above
#optionally reattach to master
git checkout master
Be aware, though, that any explicit manipulation of where a branch points has the potential to leave behind commits that are no longer reachable by any branches, and thus become object to garbage collection. So, think before you type git branch -f
!
This method is better than the git reset --hard
approach, as it does not destroy anything in the index or working directory.
回答3:
git reset --hard 1258f0d0aae
But be careful, if the descendant commits between 1258f0d0aae
and HEAD
are not referenced in other branches it'll be tedious (but not impossible) to recover them, so you'd better to create a "backup" branch at current HEAD
, checkout master
, and reset to the commit you want.
Also, be sure that you don't have uncommitted changes before a reset --hard
, they will be truly lost (no way to recover).
回答4:
git branch -f <branchname> <commit>
I go with Mark Longair's solution and comments and recommend anyone reads those before acting, but I'd suggest the emphasis should be on
git branch -f <branchname> <commit>
Here is a scenario where I have needed to do this.
Scenario
Develop on the wrong branch and hence need to reset it.
Start Okay
Cleanly develop and release some software.
Develop on wrong branch
Mistake: Accidentally stay on the release branch while developing further.
Realize the mistake
"OH NO! I accidentally developed on the release branch." The workspace is maybe cluttered with half changed files that represent work-in-progress and we really don't want to touch and mess with. We'd just like git to flip a few pointers to keep track of the current state and put that release branch back how it should be.
Create a branch for the development that is up to date holding the work committed so far and switch to it.
git branch development
git checkout development
Correct the branch
Now we are in the problem situation and need its solution! Rectify the mistake (of taking the release branch forward with the development) and put the release branch back how it should be.
Correct the release branch to point back to the last real release.
git branch -f release release2
The release branch is now correct again, like this ...
What if I pushed the mistake to a remote?
git push -f <remote> <branch>
is well described in another thread, though the word "overwrite" in the title is misleading.
Force "git push" to overwrite remote files
来源:https://stackoverflow.com/questions/7310177/how-do-i-make-a-branch-point-at-a-specific-commit