Here is a quick way to learn Git with GitHub for enterprise use
- About this presentation
- The Git-client approach
- Git client
- Git config
- Terminal (vs GUI)
- Clone in account folder
- Branch list
- git checkout
- New branch with commit
- Add to Staging
- Push tags
- Delete branch
- Pull Request
- Upstream Remote
- gitk for diff
- git merge
- git push origin master
- File a pull request from git command line
- Fetch my changes
- Compare tracking branch
- Pull rebase
- Recap diagram
- Other videos and articles
- Hub add-in
- git-flow software
This presents a couple of videos 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.
The first video explains use of native Git commands to obtain data from a repository you have permissions to update and an “upstream” repository you do not have permission to update.
This provides you the basis for understanding the value described in the second video.
The second video shows how additional “helper” software called “Git Flow” can work with different types of branches.
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.
The Git-client approach
PROTIP: Print this picture of the video and pin it on a wall for reference.
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.
These steps are covered in my class handout:
- Open a Gmail account if you haven’t already.
- Create a GitHub account with a name that is available throughout various social media.
- Create a GitHub repository, such as a github.io website.
Here we have some stranger’s repository in GitHub which we have no rights to edit.
(Thank you for clicking the Star.)
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:
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.
- For example, if your account is “hotwilson”, your copy of the repo would be:
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 "firstname.lastname@example.org"
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:
Eclipse “Switch To” = git checkout
Return to this picture after going through this course to see if you recognize what each GUI item does.
Clone in account folder
PROTIP: Create a folder to hold all your various repositories.
cd ~ mkdir gits cd gits
This would hold utilities applicable to all Git work.
PROTIP: Create an account folder to hold all your own repositories.
mkdir hotwilson cd hotwilson
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”:
- Alternately, substitute your own account (instead of “hotwilson”) as your type:
git clone https://github.com/hotwilson/git-utilities --depth=1
--depth=1to only clone the latest version, to save disk space locally by not having previous version history on your machine.
--recursiveto 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 masterbeing the default branch.
Remember to cd into the repository folder:
PROTIP: Forgetting to cd into a newly cloned folder is a common mistake.
A git branch command shows us the branches defined in the repository in a read-only operation:
git branch -avv
-avvparameter provides more detail. Dash a specifies remote tracking branches to appear as well.
An example of the response:
* master 6110cb1 [origin/master] Update ... remotes/origin/master 6110cb1 Update ...
The default remote is origin with default branch master.
PROTIP: Create an operating-system alias “gb” by
vim ~/.bash_profilethen add this line:
alias gb='git branch -avv'
- then close the Terminal and open up a new Terminal shell window.
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.
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.
New branch with commit
The dash b specifies creation of a new branch, 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.
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.
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.
- 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.
The git status command details the status of changes to the repo.
- 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
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.
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.
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
lists actions that have occurred on the local machine.
- Each entry is pruned after 90 days (by default).
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.
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.
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
Tags require an additional git push command to be pushed to GitHub.
git push --tags
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
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.
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.
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.
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.
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 –
- The URL is the one owned by someone else.
git fetch upstream
git checkout master
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:
- 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
If they don’t affect you:
Notice the slash separator. Use a cat or less command to verify file contents.
git push origin master
git push to update origin master on our forked repository.
There are variations to these commands, but this is the typical workflow.
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
Tags are pushed using its own separate command:
git push --tags
File a pull request from git command line
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.”
### Changes in my repo
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
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.
Compare tracking branch
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.
To see the difference introduced by fetch:
Alterntely, some others prefer using 3rd-party merge utilities.
To display outgoing changes before you push:
git log master ^origin/master
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).
--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 savebefore 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.
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):
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
git config branch.autosetuprebase always
Other videos and articles
Syncing Your GitHub Fork [4:26] May 3, 2014 by Data School at jackiekazil using justmarkham
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:
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)
- Release - for next release development
These branches are used more in corporate rather than open source software.
[3:30] Install it on a Mac:
brew install git-flow
Create content in a folder (such as “davebock_www”) and [4:01] initialize Git:
Customize .gitignore file:
Add to Git and commit (Git commit commands are still necessary):
git add . git commit -m"initial commit"
Push to GitHub:
git remote add origin email@example.com:CodeSherpas/da... git push origin master
View the branches:
git branch -avv
Atlassian presents their take on the different branches in this video:
Set the upstream tracking branch:
git branch --set-upstream develop origin/master
git flow init -d
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? 
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>
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
Edit files (such as generate controller).
git flow feature publish branchx
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'
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
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'
List Git Flow commands available [12:14]:
git flow release start initial deploy
You are automatically prompted for a tag message (because it’s master).
This also occurs with Hotfix.
YOUTUBE: from GitHub Education Professional Guides: Workflow Strategies has video illustrations
- Git Flow Introduction
- Git Flow Feature Branch and Pushing to GitHub [11:16] 6 Dec 2015
- Git Flow and Github Pull Request [6:53] 1 Jan 2016
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
Introduction to GitLab Workflow [49:14] Mar 11, 2016
This is one of a series on Git and GitHub:
- Why Git? (file-based backups vs Git clone)
- Git-client based workflows
- Git whoops (correct mistakes)
- Git rebase
- Git commits with a Tag and Signature
- Git HEAD (Commitish references)
- Git custom commands
- Git utilities
- TFS vs GitHub
- GitHub REST API
- GitHub GraphQL API
- GitHub PowerShell API Programming
- GitHub GraphQL PowerShell Module