Git for Beginners

Notes:

  • Upstream = The canonical. The CoreOS live codebase.
  • Origin – My fork. My original fork on GitHub.
  • Remote – tiny local versions
  • [string] – square brackets indicate example strings. These will vary every time. Do not include the brackets in your commands.

For a more thorough guide to the process, see Understanding the GitHub flow.

For not the most descriptive, but a fairly complete list of Git commands, see Git commands in the sequence on GitHubGist.

The process:

Create a fork from upstream

Fork the repository you plan to work on, so that you’re never editing live code (or docs).

In the GitHub browser interface:

  • Navigate to the repo you wish to edit.
  • Click the Fork button in the upper right corner.
  • Select the location for your fork. (Fork to your GitHub account.)
    • Check the top left corner of the GitHub page. It will list your fork, and its origin.

Create a local repo and sync it with CoreOS

Create a directory on your local machine that matches the files included in your fork. This allows you to make changes and work a file for as long as you like, before pushing your work up into GitHub.

In GitHub:

  • Navigate to the fork you wish to clone.
  • Click Clone or download.
  • Select Clone with SSH.
  • Copy the URL to the clipboard.

Create a local directory in which your cloned (working) files will be stored. Open a terminal, and enter:

mkdir -p <directory/to/store/fork<account>>
# Where <account> is your GitHub account name.

Confirm that you’re in the correct directory before cloning the fork. The git clone command will clone into the directory returned by the pwd command. Enter:

pwd  # To “print” the local directory. 
# Should return <directory/to/store/fork<account>> created above.

Clone your fork into this directory:

 git clone <git@github.com:zbwright/tectonic.git>
# Replace <git@github.com:zbwright/tectonic.git> with the string copied from GitHub.
This will clone the branch from GitHub to your local directory.
# Hit Enter, and watch the clone as it happens.

Note: If required, see Adding a new SSH key to your GitHub account for more information.

Tell Git where the upstream directory lives for the master you just cloned.

cd <tectonic> # change directory to the repo just created
git remote add upstream <git@github.com:coreos-inc/tectonic.git>
# Point to the CoreOS directory from which you forked your master.
Enter the string you copied from GitHub when creating the clone,
and replace your forked directory with the directory from which it was forked.
See the upper left corner of the GitHub page for this information. For example,
mine shows zbwright/tectonic forked from coreos-inc/tectonic. Therefore,
in this example, I change the copied string ‘git@github.com:zbwright/tectonic.git’
to ‘git@github.com:coreos-inc/tectonic.git’

To check that you’ve matched it all up correctly, use:

$ git remote -v
origin    https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch)
origin    https://github.com/YOUR_USERNAME/YOUR_FORK.git (push)
upstream  https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch)
upstream  https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push)

Now, you’ve created a fork from upstream for your working master. You’ve cloned your fork to your local directory, creating a master. And you’ve linked your local master directory to its upstream branch origin.

Create a working branch for your work

Before beginning work, create a branch from your master fork, and name it appropriately for the current task. This allows you to work on a feature branch, rather than the master fork.  

  • Go to your GitHub fork page.
  • Click down into the repo you plan to edit.
  • To the left of the repo name, click Branch. Enter a (meaningful) name for your working branch, and click enter.

Or, use the command line to create a working branch.

git checkout master 
# To ensure that you’re starting from your master branch, which does not include
any of your local changes.
git checkout -b <newbranch>
# Creates a new branch with the input name, and switches to that branch.
This allows you to work on a feature branch, rather than the master fork.  

Edit files locally

Edit the cloned files in the file editor of your choice.

Re-sync before beginning work

Always be certain to bring your local copy up to date with any changes that have been made to the master repo before beginning work. This will help mitigate conflicts later on, and ensure that you’re working from the latest version of the file.

In the terminal, enter:

git status 
# Tells you which branch you’re in and shows its status.
git fetch <remote upstream name>
# Fetches a copy of upstream files = your fork in GitHub
git rebase <remote upstream name>/<local branch name>

# Ensures you have all current changes from upstream / master, and reapplies your local work on top of the incoming changes

$ git fetch
$ git rebase <server>/<branch name>
or
$ git reset --hard <server>/<branch name>

do work

$ git commit ..
$ git push <server>/<branch name>

Edit local files

Make sure you’re on the correct branch before editing files:

git checkout branch <working branch name> 

Navigate to your local directory, and edit away. Git will automatically manage the edits and changes, ‘saving’ them to the checked out branch. Use git to change branches, and the content displayed in your text editor will reflect the state of the active branch.

Check your work:

git status # Lists the current status of the branch. 
git diff # Compares changes in your feature branch to originals in your master fork.

Commit your feature branch changes to your fork on GitHub

Commit pushes any changes you’ve saved from your feature branch to your master branch on GitHub.

Best practice is to have as few commits in a Pull Request as necessary. Be certain to review and preview your work before making a commit.

Cycle through the following commands as you make updates to your files, and want to push them to your fork:

git diff # lists differences between your local files and those in your branch
git status # shows the changed files
git add <filename>
# stages changes made to the listed file to be added to your branch
# Use git add <filename> <filename> <filename> to add multiple files as
part of a single commit.
git commit
# saves changes to the branch, and opens a text editor in which you must
add a commit message. (This command will vary slightly by OS. On Mac,
you have to enter ‘git commit -m’ to enter a text editor. On Linux,
you don’t need the ‘-m’.)
Message should take the format repo:message (ex: docs: Fixing format issues.)
Add the message, then esc :wq to exit the editor, and return to the terminal
git remote -v #  check your upstream and origin repositories
git push origin <branch name>
# Pushes the committed changes to your master branch on GitHub.
# If you haven’t yet defined your remote for the branch, Git is good enough to tell you exactly how to do it.

Go to GitHub to check your work, anc create a Pull Request.

Create a Pull Request

Create Pull Requests to tell the upstream manager that you have changes you would like pulled into the main trunk, and to begin the review process. When your working changes are complete and committed to your fork, create a Pull Request from your fork.

  • In GitHub, navigate to the origin repo for your commit.
  • Your push will be displayed at the top of the page, with a Create Pull Request button.
  • Click the button to begin the PR. Check the list of files, and the changes made to them, to confirm that the PR is as you expected it to be.
  • Edit the commit message, and add supporting info, if necessary.
  • Click Create Pull Request to begin the review process.

When it’s all done and good, click Merge to merge to upstream. Note: CoreOS, and most software best practices, recommends against merging your own work.

Delete Working Branch

After your work is done, and the new things are merged, delete your working branch both locally and in GitHub. (GitHub will automatically generate an email when your PR is merged, and will include a note that your branch may be deleted.)

Delete local branch

$ git branch # to list available branches
$ git status # you must be on a branch other than the one you wish to delete
$ git branch -d <old_branch>

Delete remote branch

git push --delete origin <old_branch>

Sync your fork with upstream

Now, make both your fork on GitHub, and your local copy, match the upstream canonical.

(https://help.github.com/articles/syncing-a-fork/)

Fetch the branches and their respective commits from the upstream repository. Commits to master will be stored in a local branch, upstream/master.

git fetch upstream

Check out your fork’s local master branch.

git checkout master

Merge the changes from upstream/master into your local master branch. This brings your fork’s master branch into sync with the upstream repository, without losing your local changes.

git merge upstream/master

Then push your local (now sync’d) branch to your online repo on GitHub.

git push origin master

The git push command takes two arguments:

  • A remote name, for example, origin
  • A branch name, for example, master

Other things

Work from a second machine

To work from more than one location, simply repeat the setup for your first machine, and be certain to sync local work to the GitHub repo every single time you touch a file.

Work from multiple machines.

  • Always sync your work before and after editing files.
  • Follow the instructions to “Create a local repo and sync it with CoreOS.
  • Pull the current working files from your fork to your local file system.
git fetch origin
git branch -v -a # lists all open branches for that origin

Find the branch you want in the list

git checkout <branch name> # to move to your remote branch

Open a file in the text editor of your choice, and check that it worked.

Squash Commits

Use rebase to squash commits.

In the interactive phase, save the top listed (oldest) commit, and squash subsequent commits into it. If necessary, you can reorder the list to pick and choose the commits you wish to squash.

Delete unused files

Say you want to clean up the img folder, which contains outdated and unused image files. Use rm to remove them from the repo.

git branch -b <branch-name> # Create a branch
git checkout <branch-name> # make sure you’re on that branch

Delete all applicable files in your local directories.

git status # to list all deleted files
       deleted:  <file-name>

Then, use git rm to stage the file’s removal:

git rm <file-name>
git status # to check your work again
       deleted:  <file-name>

Then, do the standard git commit / git push sequence to push your changes to your master fork.

Reset to last commit

You don’t know what’s going on locally, but you do know that the last commit was good, and you want to get back to it.

git reset --hard origin/<branch>

Clean Break

So, you’ve really mucked everything up. Your fork is whacked. Your branch is wacked. There are way too many commits in your PR. How do you fix that?

First, copy your changed file(s) to another location. You’re about to wipe all your work.

git checkout <branch> 

# then open a text editor, and confirm that you’re looking at the work you wish to save before copying it elsewhere.

Copy / paste the edited files from the repo to another location locally.

then:

git fetch --all
git rebase <upstream remote>/<target branch> # for coreos, this is ‘upstream/master’
git push -f <your remote> <your branch> # for coreos, ‘upstream master’

Then, create a new branch, make changes, add, commit, push, PR.

Or, to reset your fork to its upstream origin:

git remote add upstream </url/to/original/repo> 
git fetch upstream
git checkout master
git reset --hard upstream/master
git push origin master --force

Use SSH to clone repos

To clone repos using SSH rather than HTTPS you must first create an SSH keypair locally, then copy the public key to your GitHub account.

If you don’t want to reenter your passphrase every time you use your SSH key, add your key to the SSH agent, which manages your SSH keys and remembers your passphrase.

(passphrases may NOT be discovered once forgotten. Magic security by design. If the passphrase is forgotten before the keys are added to your GitHub account, simply create a new key, and start over.)

Create the key

https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/

  1. Open Terminal.
  2. Paste the text below, substituting in your GitHub email address.
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

This creates a new ssh key, using the provided email as a label.

Generating public/private rsa key pair.
  1. When you’re prompted to “Enter a file in which to save the key,” press Enter. This accepts the default file location.
Enter a file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]

At the prompt, type a secure passphrase. For more information, see “Working with SSH key passphrases”.

Enter passphrase (empty for no passphrase): [Type a passphrase]
Enter same passphrase again: [Type passphrase again]

Add your SSH key to the ssh-agent locally

When adding your SSH key to the agent, use the default macOS ssh-add command, and not an application installed by macports, homebrew, or some other external source.

  1. Start the ssh-agent in the background.
eval "$(ssh-agent -s)"
Agent pid 59566
  1. If you’re using macOS Sierra 10.12.2 or later, you will need to modify your ~/.ssh/config file to automatically load keys into the ssh-agent and store passphrases in your keychain.
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
  1. Add your SSH private key to the ssh-agent and store your passphrase in the keychain. If you created your key with a different name, or if you are adding an existing key that has a different name, replace id_rsa in the command with the name of your private key file.
ssh-add -K ~/.ssh/id_rsa

Note: The -K option is Apple’s standard version of ssh-add, which stores the passphrase in your keychain for you when you add an ssh key to the ssh-agent.

If you don’t have Apple’s standard version installed, you may receive an error. For more information on resolving this error, see “Error: ssh-add: illegal option — K.”

  1. Add the SSH key to your GitHub account.

Add to GitHub account

  • Log into your GitHub account
  • Go to My account > Settings > SSH and GPG keys
  • Click New SSH key
  • Give the key a meaningful Title
  • Copy and paste the key from your id_rsa.pub file into the Key field, and click Add SSH key.

Then, when you get this error:

beth-wright:beth.wright beth.wright$ git clone git@github.com:checkr/docs.git
Cloning into 'docs'...
ERROR: The `checkr' organization has enabled or enforced SAML SSO.
To access this repository, you must use the HTTPS remote with a personal
access token or SSH with an SSH key and passphrase that has been whitelisted
for this organization.
Visit https://help.github.com/articles/authenticating-to-a-github-organization-with-saml-single-sign-on/
for more information.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.
beth-wright:beth.wright beth.wright$

Authorize the SSH key for use with a SAML org

https://help.github.com/articles/authorizing-an-ssh-key-for-use-with-a-saml-single-sign-on-organization/

To use an SSH key with an organization that uses SAML single sign-on, you must first authorize the key.

  • Log into GitHub, then go to My Account > Settings > SSH and GPG keys
  • Next to the SSH key you’d like to authorize, click Enable SSO > Authorize.
  • Click through the authorization process

 

Install Yarn on Mac & get a preview

From any directory:

sudo npm install --global yarn 

From within the GitLab directory you wish to preview:

yarn install

From the same directory:

yarn dev too show the site at http://localhost:8000