I created a new file (with quite a bit of code and hard work) and committed it to the master branch of my git repo. A moment later I realized that I probably should’ve created a branch for the file. I thought I could revoke the commit from master and commit again on a branch, but I think I did things in a silly order. For some reason I created the branch first, then went to revoke the commit, using is it possible to revoke commits? as a guide.
Here’s essentially what I did:
echo "Lots of code and hard work" > newfile.txt
git commit -m "thoughtless commit" newfile.txt
# Oh wait, I should've branched!
git branch thoughtful
git checkout thoughtful
# Hmm, I didn't mean for that last commit to be in master
git checkout master
# get the previous commit's hash
oldhead=$(git log | awk 'BEGIN{commitcount=0; } /^commit/{ if (commitcount++ == 1) { print $2 }; }')
git reset --hard "$oldhead"
git checkout thoughtful
So now I’ve apparently trashed a commit on master (indeed, ‘newfile.txt’ no longer exists on master), but it still exists in thoughtful (and I guess reflog).
Would someone be so kind as to explain what I did here, and why no commit on thoughtful is required?
When you created your branch
thoughtful, it started from the current state ofmaster, which already contained the commit. From that point onwards, the two branches are unrelated. Whatever you do tomaster, it won’t affectthoughtful. The commit that introduces the file will still be part ofthoughtfulregardless.You should try
git log thoughtfulandgit log masterto review the history of commits. Onthoughtfulyou’ll still see the commit you tried to remove from master.A more complete breakdown follows
Assuming we’re currently on
master…You’ve created a commit on
master, containingnewfile.txt.You’ve created a branch
thoughtful, which is at the current statemaster, but is otherwise completely unrelated to master. The branch’s starting point ismaster, because you didn’t explicitly specify a starting point andmasteris currently checked out.Now you’re on
thoughtful; you don’t have tocheckoutnew branches to make them real, this step has absolutely no effect since you do the following:Now you’re on
master.You’ve jumped through a ton of hoops to get the previous commit, when you could have just used
master~orHEAD~. That is how you get the "previous" commit, not by inspectinggit log. In the future, to undo the last commit, please usegit reset --hard HEAD~.You’ve changed the commit
masterpoints to. Now it’s whatever commit the above command discovered, presumably the commit beforenewfile.txtwas introduced. Using--hardcauses Git to update the working directory as well, sonewfile.txtgoes away; had you omitted--hard,newfile.txtwould still be in the directory, but listed as a new file ingit status.You’ve gone back to
thoughtful, which containsnewfile.txt, updating your working directory and reintroducingnewfile.txt.