How can I change which commit master points to in git?
GitGit Problem Overview
In git, I've been making commits onto the master branch, when really I should have been working on a feature branch. I want to change this so that master is back to where it started, and what was on master is now on a new branch. Basically, my commit history looks like this:
A -- B -- C -- D -- E
| |
| master
origin/master
And I want it to look like this:
master
|
A -- B -- C -- D -- E
| |
| new_branch
origin/master
How can I change where master points?
Git Solutions
Solution 1 - Git
- Stash your uncommitted changes:
git stash
- Create a new branch:
git branch new_branch
- Reset master to origin/master:
git reset --hard origin/master
- Check out the new branch again:
git checkout new_branch
- Unstash your changes:
git stash pop
Stash/unstash is not necessary if your working tree is clean. Just make sure there are no changes in your working tree, because those will be removed when you reset --hard
Another possibility (faster, and without the need to stash and reset):
- Check out a new branch:
git checkout -b new_branch master
- Create a 'new' master branch and point it to origin/master's commit:
git branch -f master origin/master
Solution 2 - Git
$ git checkout master
$ git reset --hard <commit-id-for-master-to-sit-at>
for example try this
$ mkdir example; cd example
$ git init
$ vi testFile.txt
(now add "test commit 1" to line 1 of file)
$ git add *
$ git commit
(add message "(+) 1st commit" to git commit)
$ vi testFile.txt
(now add "test commit 2" to line 1 of file)
$ git add *
$ git commit
(add message "(+) 2nd commit" to git commit)
$ vi testFile.txt
(now add "test commit 3" to line 1 of file)
$ git add *
$ git commit
(add message "(+) 3rd commit" to git commit)
$ git tag final_head
$ git reset --hard HEAD~1
this example shows moving the master to a different commit. Note here that the tag allows us to save the old master, in case :)
Solution 3 - Git
Checkout a new branch where branch main
is, then delete branch main
, then create branch main
anew where main
was intended to be (e.g., at origin/main
):
git checkout -b new_branch_where_main_was
git branch -d main
git branch main origin/main
Note that this does not change anything in the working directory: HEAD
remains unchanged, uncommitted changes remain where they are. No stashing needed, no checkouts needed, no resets needed.
Solution 4 - Git
Go to .git/refs/heads/master which has the hash of master and change that to whatever you want. I use gitg to quickly find the hash of master and afterwards to verify that the move was successful.
Solution 5 - Git
Create a new branch new_branch
at the current HEAD (assuming HEAD = master), reset master to C and switch to new_branch
again (speaking in terms of SmartGit).
Solution 6 - Git
Note that at any given time you can change where a branch points to by using git update-ref refs/heads/branch id
, but before you do this, you must give a name to the tip of the tree, otherwise your work will unaccessible. So these two commands may do the job
git update-ref refs/heads/newfeature HEAD
git update-ref refs/heads/master XXYYY
But make sure that you do not have any uncommited changes otherwise all hell will break loose