Wilson Mar bio photo

Wilson Mar

Hello. Join me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Google+ Youtube

Github Stackoverflow Pinterest

Here is a quick way to learn Git with GitHub for enterprise use


This page attempts to get those new to Git productive for professional usage, in the minimum time.

Two videos are presented, each followed by text about what was discussed in the video, so you can understand the sequence of commands using Git with GiHub for more “monolithic” systems that need more coordination than what the GitHub workflow provides.

About this presentation

This is for someone with a Git command-line client installed.

We encourage you to actually type out (rather than just read) the commands shown in the narrative below.

In the text are also additional alternatives and comments not shown in the video.

PROTIP: Use two different browsers (Chrome and Firefox) simultaneously.

The Git-client approach

(Click here for full screen)

PROTIP: Print this picture of the video and pin it on a wall for reference.

Older video

Let’s get hands-on typing each of the commands in the sequence presented in the video.

PROTIP: Click “Whoops” links for instructions on un-doing the commands immediately before the link. There is a “Return” link there to get back here and continue.


These steps are covered in my class handout:

  1. Open a Gmail account if you haven’t already.
  2. Create an account on GitHub.com with a name that is available throughout various social media.
  3. Create a GitHub repository, such as a github.io website. The steps for this is covered in my course workbook.


  1. Here we have some stranger’s repository in GitHub which we have no rights to edit.


  2. (Thank you for clicking the Star.)

  3. But if you fork it into your own GitHub account, you would then have rights to change it.

    • For example, if your account is “hotwilson”, your copy of the repo would be:

    [ Whoops ]

    Git client

    To work with repositories on your local machine, install a Git client.

    • The various clients and how to install them are covered in my class handout.

    • This tutorial is called “Git-client based workflow” because it makes use of a Git client on your local machine.

    Git config

  4. Its installation includes adding in your user home folder a dot git folder containing a config file. That file stores git global commands such as username and userid settings for attribution.

    git config --global user.name "Wilson Mar"
    git config --global user.id "wilsonmar@gmail.com"

    [ Whoops ]

Terminal (vs GUI)

Git commands are typed into a Terminal shell window on a Mac, a Git Bash command window on Windows, or a Run command window on Windows. Instructions for this are covered in my class handout.

Most IDEs incorporate commonly used Git client functionality into their software.

In Eclipse, right-click on the project in the left Solution pane, then select Team for the Git menu:
git eclipse menu 518x648

  • Eclipse “Switch To” = git checkout

  • Return to this picture after going through this course to see if you recognize what each GUI item does.

In IntelliJ, right-click on the project in the left Solution pane, then

### Account folder

  1. PROTIP: Create a folder to hold all your various repositories.

    cd ~
    mkdir gits
    cd gits

    This would hold utilities applicable to all Git work.

  2. PROTIP: Create an account folder to hold all your own repositories. Cloning a repo does not include:

    mkdir hotwilson
    cd hotwilson

    CAUTION: Some repos have a 20 character limit on the prefix before the repo name. The character count includes slashes:


    Clone in account folder

  3. Be in that folder when you clone a repository from GitHub.

    • To obtain the URL from a browser at your repository, by clicking the green “Clone or Download”:

    git-flow hotwilson url-453x198-33kb.png

    • Alternately, substitute your own account (instead of “hotwilson”) as your type:
    git clone https://github.com/hotwilson/git-utilities --depth=1
    • Add parameter --depth=1 to only clone the latest version, to save disk space locally by not having previous version history on your machine.

    • Add parameter --recursive to pull in sub-modules (repositories stored within the repository).

    Git clone creates that repo’s folder and within it a folder named dot git to hold objects that track changes to the repository.

    During cloning, Git automatically extracts files from objects out to the repository’s folder, as if you typed a git checkout master being the default branch.

    [ Whoops ]

  4. Remember to cd into the repository folder:

    cd git-utilities

    PROTIP: Forgetting to cd into a newly cloned folder is a common mistake.

    Branch list

  5. A git branch command shows us the branches defined in the repository in a read-only operation:

    git branch -avv

    The -avv parameter provides more detail. Dash a specifies remote tracking branches to appear as well.

    Alternately, shortcut:


    An example of the response:

           * master                6110cb1 [origin/master] Update ...
      remotes/origin/master 6110cb1 Update ...
    • The asterisk (*) marks the current branch

    • The default remote is origin with default branch master.

    • then close the Terminal and open up a new Terminal shell window.

    • Alternatively, identify just the current remote and branch using this command:

    git symbolic-ref --short HEAD
    • A Git alternative to the Bash “pwd” (present working directory) command is:
    git rev-parse --show-toplevel

    PROTIP: Git defaults to the master branch. But many organizations protect that name for production use, and instead create a “development” or “dev” branch for developers to work with.

    git checkout

    The git checkout command controls what Git extracts out from the repository database to the repository’s folder.

    • If you add a file after the git checkout command, Git will replace the file in the working folder with the version in the committed repository.

    [ Whoops ]

    New branch with commit

    There are two ways to create a new branch.

    The standard way is:

    git branch feat1

    “feat1” would be different for you.

    Those who want to add additional information (metadata) about a branch use this command:

    git branch --edit-description  feat1

    This will result in an editor window for you to enter metadata about the branch.

    PROTIP: In real life, the example here – “feat1” (feature1) would instead begin with an issue number or some reference to the need for the branch.

    Alternately, those who don’t need to add metadata may prefer specifying a new branch name after a dash b (-g) with as part of a git checkout such as “feat1” (feature1), to associate new changes:

    git checkout -b feat1
    • PROTIP: Atlassian defines its branches* with a type (feature, bugfix, hotfix, etc.), a slash, an issue number, then a short description.

    git atlassian branch naming 650x222

    • The advantage of creating a branch is that parallel development can occur without risking the master branch.

    • Unlike Subversion, all files are available for change with a Git branch.

    [ Whoops ]

    New branch metadata

    git --edit-description


    Now we can edit the file named README.md. The md designates markdown format. Such a file GitHub creates with this specific name to describe each repository.

    We can use vim or another text editor (such as nano, atom, etc.) to change contents inside files.

    vim README.md
    • If you use vim, press the I key to begin insertion and press Esc to end insertion mode. When out of insertion mode, type : to enter command mode, then wq to write and quit the program or then q! to quit without changes.

    We can use vim or another text editor (such as nano, atom, etc.) to change contents inside files.

  6. Make a change, then save the file.


    To detail the status of changes to the repo:

    git status

    Alternately, this command is used so often that Mac users create a shortcut in ~/.bash_profile:


    PROTIP: To have git status not display a particular file:

    git update-index .DS_Store

    PROTIP: Changes to files that should not be pushed up, such as the secrets.sh file, should be marked:

    git update-index --no-skip-worktree secrets.sh

    NOTE: Pulls of changes upstream in GitHub updates the local file.

    If both the local and upstream file are changed, Git outputs a conflict message.

    Skipped files are flagged with a “S” in this list command:

    git ls-files -v|grep '^S'

    Add to Staging

  7. You can change several files, but only the files you add to Git’s staging area will be pushed to GitHub.

    git add . -A

    The dot selects all files changed, recursively inside sub-folders as well.

    The dash capital A parameter specifies that deleted files be processed.

    PROTIP: Many prefer to specifically add individual files to go into each particular commit, which works on all files added to staging. Instead of the dot, several files can be specified on the same command.

    Alternately, to add all the files modified (not new files created and untracked):

    git add -u

    [ Whoops ]


  8. The commit supplies a message describing changes, which applies to all files added.

    git commit -m"Update for show"
    • A space is not needed between the m and the left quote of the message.

    • If you don’t specify the dash m, Git will display a file containing comments as a prompt.

    Any line beginning with the # comment character will be ignored and not be part of the message.

    • If a GitHub account user name prefixed by an at sign (such as “@wilsonmar”) is specified in the message, GitHub automatically sends an email.

    [ Whoops ]


  9. lists actions that have occurred on the local machine.

    git reflog -5

    Example output:

    9349be6 HEAD@{1}: commit: double quote removed for confusion
    9eb57bc HEAD@{2}: commit: mention gs shortcut 
    • Entries are pruned (removed) automatically after 90 days (by default).

    Rebase to squash locally

    Before pushing to GitHub, some prefer to squash some commits so that only one commit message appears for several commits made locally.

    • Rebasing cleans up intermediate commits that is unwanted noise to the rest of the team. The extra commits complicates the history, and makes back-out of code more difficult.

    • Yes, this changes history, which is why we do it. But it’s only on your local versions.

    Study http://wilsonmar.github.io/git-rebase for step-by-step instructions. Then return here.


    The git push command sends to a remote what has been committed for a specific branch. If you didn’t paste your public key into GitHub, you would get an error now.

    git push

    [ Whoops ]

    Alternately, Bash users who have setup an alias can use this which includes a git add and commit:

    gas “JIRA #1234”

    This alias adds all changes and commits them all with a static “update” in message:


    The two aliases above include a git push for maximum convenience.

    Push tags

  10. When a commit is known good as the one to release, most organizations tag that specific commit with semantic versioning text.

    git tag v1.3.4
  11. Tags require an additional git push command to be pushed to GitHub.

    git push --tags

    [ Whoops ]

    Delete branch

  12. Because branches are just markers within Git, once a feature branch is in GitHub, that branch can be deleted from the local repo

    git branch -d feat1
  13. and from GitHub (by specifying that colon in front of the branch name).

    git push origin :feat1

    NOTE: The colon is the secret special sauce. There is no “delete” command with this.

    Pull Request

    Unless you have been designated a committer in the upstream repository, you can’t push changes to it. But you can request their committers to pull changes from your forked repo. When a committer of that repo merges (or in other words, accepts) your PR, you’ll get an email from GitHub.

    Upstream Remote

    Next, let’s look at what happens if, over time, changes occur in the upstream repo.

    The git remote –verification command tells us that the origin remote was created, as usual, with the repo.

  14. To enable dowload by Git, we add the upstream remote.

    git remote add upstream https://github.com/wilsonmar/git-utilities
    • The URL is the one owned by someone else.

    [ Whoops ]

    To obtain changes locally, many would rather NOT issue a git pull upstream command, which blindly fetches and automatically merges changes. Differences in the same line within the same file, Git is forced into automatic conflict resolution mode.

    • “Unintentional” merge commits are what some call “evil”.
    git pull --rebase
    • To set it up so every branch you ever create on any repository is set to pull with rebase, set this global configuration:
    git config --global pull.rebase true

    Prior to version 1.7, it was:

    git config --global branch.autosetuprebase always


    So many prefer to take it one step at a time –

  15. first a

    git fetch upstream
  16. then a

    git checkout master

    [ gfu is the shortcut ]

    gitk for diff

    Now we can use a utility such as gitk to see what changes came in.

    • Click the commit listed at the top of the list, which is the most recent commit.

    • Alternately, there is also utilities vimdiff, meld, difftool, etc.

    • For Linux: https://wiki.gnome.org/Apps/Gitg/

    • To see the difference between what is in last commit vs. what’s in the working folder:

    git difftool
    • To see the difference between what is in last commit vs. what’s added in the index cache:
    git difftool --cached
    • You can make a default command such as this to explicitly specify some file to compare:
    git diff HEAD HEAD^ -- file1

    git merge

  17. If they don’t affect you:

    git merge upstream/master

    Notice the slash separator between the upstream remote and the upstream branch (master).

    CAUTION: Once you start a merge, nothing else can be done until you reconcile ALL conflicts. One cannot save a partially-resolved merge. There is no way yet of testing a partially merged tree. You can’t go back if you make a mistake.

    [ Whoops ]

  18. Use a cat or less command to verify file contents after merging:

    cat README.md

    git push origin master

  19. git push to update origin master on our forked repository.

    There are variations to these commands, but this is the typical workflow.

    [ Whoops ]


  20. To make specific commits easier to find, add a tag to the latest commit so that it travels with that commit:

    git tag -a v1.2.3

    The example here is called a semantic tag described in the website http://semver.org

  21. Tags are pushed using its own separate command:

    git push --tags

    File a pull request from git command line

  22. Request the pull from the upstream repo. For example:

    git request-pull v1.0 https://github.com/upstream/sisters  master
    • The URL must be specified (rather than a remote designator such as “upstream”).

    • This feature is described at: http://git-scm.com/docs/git-request-pull which says “this will produce a request to the upstream, summarizing the changes between the v1.0 release and your master, to pull it from your public repository.”

    See https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/

    Changes in my repo

  23. In GitHub, on a repo you can change, create a new branch named “sample1”, create a new file, click the pencil to edit the file. Save it. For example, create a new file and change something.

    Even if you are not working with a repo that others update, you yourself may update files on GitHub.

    Fetch my changes

  24. Locally, when a team creates branches of the master, everything that the team is working on can be seen with one command:

    git fetch --dry-run

    A sample response is this from Scott Chacon:

    remote: Counting objects: 3032, done.
    remote: Compressing objects: 100% (947/947), done.
    remote: Total 2672 (delta 1993), reused 2328 (delta 1689)
    Receiving objects: 100% (2672/2672), 16.45 MiB | 1.04 MiB/s, done.
    Resolving deltas: 100% (1993/1993), completed with 213 local objects.
    From github.com:github/github
            * [new branch]      charlock-linguist -> origin/charlock-linguist
            * [new branch]      enterprise-non-config -> origin/enterprise-non-config
            * [new branch]      fi-signup  -> origin/fi-signup
    2647a42..4d6d2c2  git-http-server -> origin/git-http-server
            * [new branch]      knyle-style-commits -> origin/knyle-style-commits
    157d2b0..d33e00d  master     -> origin/master
            * [new branch]      menu-behavior-act-i -> origin/menu-behavior-act-i
    ea1c5e2..dfd315a  no-inline-js-config -> origin/no-inline-js-config
            * [new branch]      svg-tests  -> origin/svg-tests
    87bb870..9da23f3  view-modes -> origin/view-modes
            * [new branch]      wild-renaming -> origin/wild-renaming

    PROTIP: Branches such as “origin/wild-renaming” in the sample above is a remote tracking branch. File in your working folders are not updated by git fetch, which is the reason why we use it rather than git pull. Local branches don’t have the remote prefix and slash.

    [ Whoops ]

    Compare tracking branch

  25. Before you fetch/pull, display incoming changes from remote origin master branch :

    git log ^master origin/master

    Nothing is returned if no changes were found.

  26. To see the difference introduced by fetch:

    gitk origin/master..master

    Alterntely, some others prefer using 3rd-party merge utilities.

  27. To display outgoing changes before you push:

    git log master ^origin/master

    Pull rebase

  28. Use the Git utlity which resolves conflicts: It tries to find out which commits are really your local ones, and which had come from upstream in an earlier fetch.

    git pull --rebase --autostash

    As noted here, this finds the starting point for rebase by looking at the reflog of the remote tracking branch (the tips of successive git fetch operations on origin).

    • https://coderwall.com/p/7aymfa/please-oh-please-use-git-pull-rebase

    --autostash (introduced in git 2.9 of June 2016) automatically performs stash commands before the pull so that pull works even on “dirty” trees. The automatic commands are git stash save before the pull, and then when done git stash pop. This added logic which solved a trap in automation via aliases such as:

    git stash && git pull --rebase && git stash pop

    If there’s nothing to stash, the first command will do nothing, but then stash pop will unstash some random stuff from before.

    CAUTION: There still may be changes introduced which cause a conflict when the stash pops after a successful rebase. An example:

    Created autostash: 094ad5c
    HEAD is now at d39c25c repo1 - readme
    First, rewinding head to replay your work on top of it...
    Fast-forwarded master to 6b6e1d4262fd5bc8d2b974f81222003a6c67fea6.
    Applying autostash resulted in conflicts.
    Your changes are safe in the stash.
    You can run "git stash pop" or "git stash drop" at any time.
  29. If you like the above approach enough to use it a lot, create a Mac or Git alias.

    On a Mac, you can type only 3 letters (gup) by defining in your ~/.bash_profile:

    alias gup='git -c rebase.autoStash=true pull --rebase'

    Alternately, on any system, define this command:

    git config --global alias.up '!git pull --rebase --autostash'


    git config --global alias.up '!git fetch && git rebase --autostash FETCH_HEAD'

    This would enable you to type only this (reminescant of Subversion):

    git up

    The above alias definitions obsoletes git-up and the Python port on Windows as well as previous suggestion to define a global default (saved in the global .gitconfig file) which automatically inserts --rebase parameter onto git pull commands:

    git config branch.autosetuprebase always

    [ Whoops ]

Recap diagram

(Click here for full screen and printing)

Other videos and articles

Hub add-in

This describes installation and use of a simple wrapper around Git’s CLI so you can do it all from the command line rather than switching to GitHub’s web page:


git-flow software

Saeed Noursalehi says at Microsoft * “hotfixes happen in topic branches off a release branch. All topic branches are merged using a pull request.”.

Those who DO have permissions to update can use an approach described in a popular blog, which identified different types of updates at:

Each of these are a different type of branch:

  • Hotfix (from master and back to master)
  • Bugfix
  • Release - for next release development
  • Feature
  • Support

These branches are used more in corporate rather than open source software.


  1. [3:30] Install it on a Mac:

    brew install git-flow
    • http://github.com/nvie/gitflow/wiki/Mac-OS-X
    • http://github.com/nvie/gitflow/wiki/Windows
    • http://github.com/nvie/gitflow/wiki/Linux
  2. Create content in a folder (such as “davebock_www”) and [4:01] initialize Git:

    git init
  3. Customize .gitignore file:

    git init
  4. Add to Git and commit (Git commit commands are still necessary):

    git add .
    git commit -m"initial commit"
  5. Push to GitHub:

    git remote add origin git@github.com:CodeSherpas/da...
    git push origin master
  6. View the branches:

    git branch -avv

    Atlassian presents their take on the different branches in this video:

    github branches atlassian 650x260
    (click for full screen and to print)

  7. Set the upstream tracking branch:

    git branch --set-upstream develop origin/master
  8. Activate:

    git flow init -d
  9. Answer the series of questions:

    Which branch should be used for bringing forth production releases?
    - master
    Branch name for production releases: [master] 
    Branch name for "next release" development: [develop] 
    How to name your supporting branch prefixes?
    Feature branches? [feature/] 
    Release branches? [release/] 
    Hotfix branches? [hotfix/] 
    Support branches? [support/] 
    Version tag prefix? [] 
  10. View menu:

    git flow
    usage: git flow 
    Available subcommands are:
    init      Initialize a new git repo with support for the branching model.
    feature   Manage your feature branches.
    release   Manage your release branches.
    hotfix    Manage your hotfix branches.
    support   Manage your support branches.
    version   Shows version information.
    Try 'git flow <subcommand> help' for details.
  11. Instead of native git commands the “git flow” command is issued with a new branch name:

    • git flow hotfix start branchx
    • git flow bugfix start branchx
    • git flow release start branchx
    • git flow feature start branchx
    • git flow support start branchx

    A sample of the response:

    Switched to a new branch 'feature/controller'
    Summary of actions:
           - A new branch 'feature/branchx' was created, based on 'develop'
           - You are now on branch 'feature/branchx'
    Now, start committing on your feature. When done, use:
      git flow feature finish branchx
  12. Edit files (such as generate controller).

  13. List branches:

    git-flow feature
  14. Publish:

    git flow feature publish branchx

    The response:

    Summary of actions:
           - A new remote branch 'feature/branchx' was created
           - The local branch 'feature/branchx' was configured to track the remote branch
           - You are now on branch 'feature/branchx'   
  15. Instead of native git commands the “git flow” command is issued with a git flow branch name and whether you want to finish (git merge):

    • git flow hotfix finish branchx
    • git flow bugfix finish branchx
    • git flow release finish branchx
    • git flow feature finish branchx
    • git flow support finish branchx

    The response:

    Switched to branch 'develop'
    Already up-to-date.
    Deleted branch feature/branchx (was 31a9657).
    Summary of actions:
           - The feature branch 'feature/branchx' was merged into 'develop'
           - Feature branch 'feature/branchx' has been removed
           - You are now on branch 'develop'   

    To Master

  16. List Git Flow commands available [12:14]:

    git flow release start initial deploy
  17. You are automatically prompted for a tag message (because it’s master).

    This also occurs with Hotfix.

More Videos

YOUTUBE: from GitHub Education Professional Guides: Workflow Strategies has video illustrations

https://github.com/zacksiri @zacksiri

  1. Git Flow Introduction
  2. Git Flow Feature Branch and Pushing to GitHub [11:16] 6 Dec 2015
  3. Git Flow and Github Pull Request [6:53] 1 Jan 2016

git-flow software is described by this video and blog from 2013 by @KBasarab and at:

  • http://datasift.github.com/gitflow

  • https://blog.axosoft.com/gitflow/
  • https://leanpub.com/git-flow/read
  • https://www.git-tower.com/learn/git/ebook/en/desktop-gui/advanced-topics/git-flow

Hubflow fork software

Datasift people created an upgrade to GitFlow to work with GitHub, which they call HubFlow

git clone https://github.com/datasift/gitflow
cd gitflow
sudo ./install.sh
sudo git hf upgrade

The flow of hf git commands are explained here



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 command shortcuts

  5. Git-client based workflows
  6. Git whoops (correct mistakes)
  7. Git rebase
  8. Git interactive merge (imerge)
  9. Git HEAD (Commitish references)
  10. Git commits with a Tag and Signature

  11. Git custom commands
  12. Git utilities
  13. Git hooks

  14. GitHub data security

  15. TFS vs GitHub
  16. GitHub REST API
  17. GitHub GraphQL API
  18. GitHub PowerShell API Programming
  19. GitHub GraphQL PowerShell Module