Wilson Mar bio photo

Wilson Mar

Hello. Hire 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


Overview

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

git-flow-20170526-650x369.png
(Click here for full screen and printing)

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 to go back and continue.

GitHub

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.

Fork

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

    https://github.com/wilsonmar/git-utilities

  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:
    https://github.com/hotwilson/git-utilities



    [ 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 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.

    • For example, in Eclipse, right-click on the project, 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.

    Account folder

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

    cd ~
    mkdir gits
    cd gits
    

    This would hold utilities applicable to all Git work.

  6. 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:

    /gits/hotwilson/ —-+—-1—-+—-2

    Clone in account folder

  7. 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 ]

  8. 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

  9. 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 gb ]

    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.

    • PROTIP: On a Mac, create an operating-system alias “gb” by vim ~/.bash_profile then add this line:

    alias gb='git branch -avv'
    • 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 is:

    git branch feat1
    

    PROTIP: 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
    

    Editing

    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.

  10. Make a change, then save the file.

    Status

    To detail the status of changes to the repo:

    git status 
    
    * This command is used so often that many create an operating system level alias such as "gs" in ~/.bash_profile:
    
    
    alias gs="git status"
    ### Add to Staging
  11. 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 insideg sub-folders as well.

    The dash capital A parameter specifies that deleted files be processed. But many prefer to specifically add individual files to go into each particular commit, which works on all files added to staging.

    • Alternately, “git add -u” adds all the files modified (not new files created and untracked).

    • Some prefer using the single dash to avoid needing to press the Shift key to get the double quote.

    [ Whoops ]

    Commit

  12. 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 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 comment.

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

    [ Whoops ]
    [ gas “JIRA #1234” ]
    [ gbs (static “update” in message) ]

    Log

  13. The git log command provides a history of all commits. It has lots of options, so to avoid typing all the parameters desired, most people define an alias of the command in git’s config file.

    
    git log --graph
    
    • Add -3 to display only the last 3 commits.

    • If a colon appears at the bottom of the screen, press q to quit.

    • To skip the colon, add --no-pager.

    • List a count of changes in each file in the commit (for example, abcdef1) with

    git log --stat abcdef1

    .

    [ gl ]

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

    git reflog
    • Each entry is pruned after 90 days (by default).

    Rebasing

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

    • 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 version.

    • See http://wilsonmar.github.io/git-rebase for step-by-step instructions.

    Push

    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 ]

    Push tags

  15. 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
  16. Tags require an additional git push command to be pushed to GitHub.

    git push --tags

    [ Whoops ]

    Delete branch

  17. 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
  18. 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.

  19. 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

    Fetch

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

  20. first a

    git fetch upstream
    
  21. 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

  22. 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 ]

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

    cat README.md
    

    git push origin master

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

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

    [ Whoops ]

    Tag

  25. 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

  26. Tags are pushed using its own separate command:

    git push --tags

    File a pull request from git command line

  27. 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

  28. 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

  29. 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

  30. 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.

  31. To see the difference introduced by fetch:

    gitk origin/master..master
    

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

  32. To display outgoing changes before you push:

    git log master ^origin/master
    

    Pull rebase

  33. 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.
    
  34. 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'
    

    or

    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

git-flow-20170526-650x369.png
(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:

https://hub.github.com


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:
http://nvie.com/posts/a-successful-git-branching-model

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.

Video:

  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.
    </pre>
    
    
  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:

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

Resources

More

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

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

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

  13. GitHub data security

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