Wilson Mar bio photo

Wilson Mar


Email me Calendar Skype call

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

Get tips about the most common git commands (including stash, checkout, etc.) executed in a script so you can experiment on your own

US (English)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Estonian   اَلْعَرَبِيَّةُ (Egypt Arabic)   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


This tutorial shows you a basic (typical) workflow for using Git.

To save you time and the potential for typos, we’ve created a Bash script that you can run on your Mac or within a Git Bash terminal on your Windows machine. The script performs a set of commands to establish a specific condition of untracked files and entries in the Git stage and commit history.

Having a repeatable script enables you to experiment on commands. When example commands are not coming back correctly, a script also provide you a way to say “it was working before” rather than blaming yourself for not typing commands correctly.

BTW I’ve viewed every video and book on this topic and I haven’t seen this approach. So such an approach is a unique innovation of just this website.

Steps in the script includes how to travel back in time (using git checkout) and what you can do if you’re in the middle of working on a file eligible for commit but you need to immediately edit and commit other files right away, but don’t want to lose the current set of changes.

The script includes git stash commands which uses a “hidden compartment” where you can temporarily store files so they won’t be included in the next commit. For detailed information about the stash, see the official documentation at:

Preparations (Optional)

  1. In a browser view the git-basics script at:


    This is the script you run to perform the tutorial below.

    PROTIP: It’s wise to examine any script before running it to check if there are potentially malicious commands. The script does not pull in other scripts.

  2. Click the “Star” to give us some cred. Thanks!

  3. If you cannot run scripts, view the results anyway by viewing captured from a run:


    Live run

  4. If you Fork the repo to your own account, remember to rename the account name in the URLs in this tutorial.

  5. Highlight the entire command below by clicking on it until the whole line is highlighted.

    sh -c "$(curl -fsSL https://raw.githubusercontent.com/wilsonmar/git-utilities/master/git-basics.sh)"
  6. On a Mac, press command+C to copy it into your Clipboard.

    On Windows, press Ctrl+C to copy it into your Clipboard.

  7. On a Mac, open a Terminal by moving your cursor to the upper-right corner and clicking the magnifying glass search icon. Type “Ter” to click “Terminal.app” when it appears.

    On Windows, click the Windows icon and type “bash” to click “git bash” when it appears.

  8. On a Mac, click under the prompt and press command+V to paste the command.

    On Windows, right-click under the prompt and press command+V to paste the command.

  9. Press Enter to invoke the command.

Commentary on command output

This diagram illustrates the rough relationship among commands:


Specific points in the script are referenced by the squence numbers below:

  1. git init (within /Users/wilsonmar/git_repo, which is the location of the folder created by the script).

    On your machine, you would see your user id instead of “wilsonmar”.

  2. To mute warnings on Windows machines such as “LF will be replaced by CRLF”:

    git config --global core.safecrlf false
  3. Create README.md & .gitignore files using echo piping commands:

    echo "#git-basics.sh">README.md
    echo "amy">.gitignore

    PROTIP: The git stash command ignores files specified in the .gitignore file which specifies files which should not be pushed up to GitHub or GitLab.

  4. File amy is the file that is specified in .gitignore.

  5. File bob is created but remains as untracked in all git status commands.

    PROTIP: Since untracked files are not included in commits, they are not processed by stash or most other git commands, by default.

  6. File chris is created and added to the Git “index”, also called the “stage” with a
    git add command which does not provide a response unless there is an error.

  7. File don is added and commited once and not edited again, so it remains in history and does not appear in git status commands.

    PROTIP: Since a commit was not made after chris was added, when don is commited, chris got committed with it since both were in the stage/index.

  8. File ed is committed, but appears in modified status after another line is added to the file.

  9. File finn is committed then modified with a second line, but a git add is performed without a git commit on the change.

  10. File george is committed twice.

  11. File harry is created, but not added nor committed by git.

    QUIZ: Which of the above will show up in a git status command.

  12. A file listing shows that all the files created are visible.

    PROTIP: A git checkout command later will change the files and their contents.

  13. The extra attributes in git status -s -b displays a compressed list.

    PROTIP: This command is so frequently used that many define an alias for it by editing the ~/.bash_profile file, and add gsl. See my Git Shortcuts tutorial.

    An alias is also frequently added for git log command because so many tags are usually needed to make the log more concise.

  14. To make it more plain in this example, an ordinal number was added to commits.

  15. The git reflog command lists reference codes that you will use later to specify the specific point in time you want to return to.

  16. We use git checkout HEAD@{4} to return to the working directory as it was after the 2nd commit of Don.

    QUIZ: Why did the command abort and did not complete?

    PROTIP: The “M” next to file ed means Modified and thus being tracked by Git. Being tracked by Git means it must be specifically added or stashed before git can commit.

  17. So we stash the file ed.

  18. PROTIP: We do not recommend using the plain git stash command because the automatically generated stash message is not memorable. It does not give a clue about what it contains in the stash list.

  19. The git stash show command provides more details about what’s in the stash.

    PROTIP: Untracked files get stashed only when –untracked is specified on git stash. If you use it, we recommend using a separate stash command.

  20. Notice that file ed no longer shows in git status because it has been stashed away.

    Untracked files still appear there on the sidelines even though they are not processed by Git.

  21. Here is when we travel back in time using the git checkout command.

    PROTIP: Don’t be scared off by the statement about ‘detached HEAD’.

    Notice the last statement returned from git checkout, such as:

    # HEAD is now at 744646a 3rd commit - 7. I’m Ed. But I’ll soon be modified.

    Scroll back to look at the git reflog to see that this is one commit before the HEAD@{4} location specified in the git checkout command.

  22. Displaying the contents of file ed (using the cat command) reveals that only the first line is there.

    QUIZ: Why isn’t the second line there?

    Because it has been stashed away.

  23. In the list of files after a checkout back in time, why are latter commits not included?

    Files finn and george were added after the point in time from the checkout at HEAD@{4}.

  24. Nevertheless, commits for Finn and George are seen in git reflog because that command is the overlord of all actions by Git and live outside of specific times.

  25. A file can be modified while in a “HEADLESS” state.

  26. We can see that the file is modified from a git status command.

  27. We go back to the original master branch HEAD

  28. A listing of files in the working directory shows the whole gang back together.

  29. A display of the contents of the file changed while back in time appears to be carried forward.

    QUIZ: Why can changes be made when previously changes to ed has to be stashed?

    That’s because changes to ed were made under the master branch.

    This is how a “gh_pages” branch to contain documentation on GitHub can exist detached but in parallel with the master branch.

  30. To get that extra line back from stash, git stash pop and cat (display) the file:

    The “drop” response means that once a file is retrieved from stash, it is deleted from the stash stack.

  31. A git status shows ed as having been modified.

  32. Now see that the second line re-emerges.

  33. A git stash command would return nothing if all stashed have poped out.

  34. A git reflog command would chronicle this.

  35. An alternative to stash is to create a branch and commit to it, as shown for the file harry.


Can GUI Git apps do the same?

The Tower Git client provides a Stash button:


Alt users

PROTIP: Some people use stash as a way to move files between branches. If you’re on “branch-A” and want changes to apply to “branch-B”, checkout branch-B and then stash.

Git Aliases


  stsh = stash --keep-index
  staash = stash --include-untracked
  staaash = stash --all
  sa=stash apply
  sx=stash drop
  sl=stash list
  sd=stash show --patch --stat
  sp=stash pop
  ss=stash save
  ssu=stash save --include-untracked

Git Basics tutorials


More about Git & GitHub

This is one of a series on Git and GitHub:

  1. Git and GitHub videos

  2. Why Git? (file-based backups vs Git clone)
  3. Git Markdown text

  4. Git basics (script)
  5. Git whoops (correct mistakes)
  6. Git messages (in commits)

  7. Git command shortcuts
  8. Git custom commands

  9. Git-client based workflows

  10. Git HEAD (Commitish references)

  11. Git interactive merge (imerge)
  12. Git patch
  13. Git rebase

  14. Git utilities
  15. Git-signing

  16. Git hooks
  17. GitHub data security
  18. TFS vs GitHub

  19. GitHub actions for automation JavaScript
  20. GitHub REST API
  21. GitHub GraphQL API
  22. GitHub PowerShell API Programming
  23. GitHub GraphQL PowerShell Module