title: Git: How do you replace your current working directory with a previous commit without branching or git revert?
body: <p>Is there an easy way to the following with git?</p>
  
  <p><a href="https://i.stack.imgur.com/Vdypb.png" rel="noreferrer"><img src="https://i.stack.imgur.com/Vdypb.png" alt="commit copy paste diagram"></a></p>
  
  <p>Basically I want to create a new commit at the top of my commit history that is equivalent to a previous commit from my history (e.g. to restore a project to a previous state).</p>
  
  <p>I don’t want to use branches because I’m teaching this to people who have never used git before, and I want to keep things as “linear” as possible. (Most of my audience just needs to back stuff up, review project history, and restore a project to a previous state if necessary, but nothing else remotely fancy.)</p>
  
  <p>I don’t want to use <code>git revert --no-commit 49a732c..HEAD</code> because this gives an error message if there does happen to be a merge after <code>49a732c</code> (which I admit is unlikely in my audience, but it does sometimes happen through frantic attempts to make error messages go away).</p>
  
  <p>I also don’t want to delete/rewrite history.</p>
  
  <p>Essentially, is there a simpler way to do this?</p>
  
  <pre><code># make sure on master and working directory clean
  me@laptop:~/Desktop/proj$ git status
  On branch master
  nothing to commit, working directory clean
  
  # check out commit to restore
  me@laptop:~/Desktop/proj$ git checkout 49a732c
  Note: checking out '49a732c'.
  
  You are in 'detached HEAD' state. You can look around, make experimental
  changes and commit them, and you can discard any commits you make in this
  state without impacting any branches by performing another checkout.
  
  If you want to create a new branch to retain commits you create, you may
  do so (now or later) by using -b with the checkout command again. Example:
  
    git checkout -b &lt;new-branch-name&gt;
  
  HEAD is now at 49a732c... Fix bugs.
  
  # copy project checked out at 49a732c to temp folder
  me@laptop:~/Desktop/proj$ cp -r . ../temp
  
  # check out master again
  me@laptop:~/Desktop/proj$ git checkout master
  Previous HEAD position was 49a732c... Fix bugs.
  Switched to branch 'master'
  
  # remove everything except .git
  me@laptop:~/Desktop/proj$ rm -rfv !(".git")
  rm: refusing to remove '.' or '..' directory: skipping '.'
  rm: refusing to remove '.' or '..' directory: skipping '..'
  removed 'file_1.py'
  removed 'file_2.py'
  
  # copy everything except .git from temp (checked out at 49a732c) into working directory
  # (so working directory is identical to project at commit 49a732c)
  me@laptop:~/Desktop/proj$ cp -nr ../temp/* ./
  
  # make new commit identical to project state at 49a732c
  me@laptop:~/Desktop/proj$ git add *
  me@laptop:~/Desktop/proj$ git add -u
  me@laptop:~/Desktop/proj$ git commit -m “Restore project to commit 49a732c.”
  [master 2b6416c] Restore project to commit 49a732c.
   3 files changed, 18 deletions(-)
  
  # remove temp
  me@laptop:~/Desktop/proj$ rm -rf ../temp
  
  # new commit 2b6416c is now identical to 49a732c
  </code></pre>
  
  <p>Alternatively, if branching is the best way to do this, is there a sequence of commands that will always work and won't yield any merge conflicts or tell you to use git stash (assuming current working directory is clean)?</p>