Skip to content

Instantly share code, notes, and snippets.

@adgoncal
Last active March 10, 2021 22:01
Show Gist options
  • Save adgoncal/87e27a45872074b6076b9a42fafb54a8 to your computer and use it in GitHub Desktop.
Save adgoncal/87e27a45872074b6076b9a42fafb54a8 to your computer and use it in GitHub Desktop.
Introduction to Git

Introduction to Git

Table of Contents

  • What is Git?
    • What is Source Control?
    • Why use Source Control?
    • What is the difference between Git and GitHub
  • Getting started
    • Overview
    • Git Config
  • Collaboration
    • git merge
    • git rebase
    • resolving conflicts
    • git reflog
    • git reset
    • Fork & Push Workflow
    • git fetch
    • git pull
    • git push
    • git remote
    • Setting up gitHub SSH key
  • Tools
    • git stash
    • git tag
    • git grep
    • git blame
    • git bisect
  • Automation
    • Git Hooks
  • Free Books
  • Useful Links

What is Git?

What is Source Control and why should I use it?

Git is a Source Control (aka version control) tool: it allows you keep a history of changes to a set of files, and makes it easy to retrieve a different revision of the file at any point in time. This revision history gives you the freedom to experiment without fear of losing work you have done previously. At any point in time, you can review your changes and revert to a previous version if needed.

What is the difference between Git and GitHub?

Git is a Source Control tool. There are other Source Control tools, such as SVN and Mercurial.

GitHub is a web service that hosts your Git repository, making it easier to collaborate with other people. There are other similar web services, such as GitLab and BitBucket.

Getting Started

The general idea is to create a branch of a base branch (aka: trunk) and work on your branch until it is ready to be merged onto the trunk. Each commit is a set of related changes saved to the local branch, and you pull the latest changes from the trunk to keep up to date.

git help takes a parameter and opens the local git documentation for the given parameter.

ie: git help help

Overview

git init sets the current working directory to be tracked by Git's source control.

git clone clones an existing repository to your local machine. It can be used to clone another local repository, as well as a remote repository.

git branch allows you to view your existing local and remote branches, as well as create a new branch.

git checkout switches your repository to track the given branch.

git status displays all of your local, uncommited changes, as well as merge conflicts. Uncommited changes can be classified as staged and not staged. Staged changes are ready to be commited.

git diff displays your unstaged changes. Once changes are staged, you can see them with git diff --cached

git log displays the history of commits on the current branch

git add stages a file so that it can be commited.

git rm removes a file and stages the deletion so that it can be commited.

git mv moves a file and stages the move so that it can be commited. This is useful for renaming files as well.

git commit saves your staged changes to your history with a given comment.

git revert creates a new commit reverting the changes specified by their hash, listed in the history log.

Git config

Git allows you to create a configuration file, where you can store your preferences such as editor and difftool, create aliases for commonly used commands, set up your identity to be used on git commits, etc.

Here is a sample .gitconfig:

[user]
	name = Allan Goncalves
	email = adgoncal@users.noreply.github.com
[color]
	ui = true
[log]
	# Better date formats in logs
	date = rfc
[core]
	# Set default editor for git commits
	editor = vim
	
	# let the system figure out the correct line-ending to use
	autocrlf = input

	# Use custom `.gitignore`
	excludesfile = ~/.gitignore
[push]
	default = simple

[alias]
	st = status

It is a good practice to create your own .gitconfig in your home directory (~/ on unix)

Collaboration

In order to collaborate with other people, each person will branch off of a base branch, and create a Pull Request to merge changes when ready. It is common for a conflict to arise when merging changes if the base branch has changed since you branched off. A good practice is to fetch the latest changes to the base branch and merge them into your branch often, and always do it before creating a PR.

git fetch will fetch the changes, and git merge will merge them. This is such a common use case that there exists a command git pull that does both fetch and merge.

An alternative to merging is rebasing, which allows you to modify the history of your branch so that your commits appear after the commits from the base branch. This can be done with git rebase. It is a good idea to use the -i flag for interactive rebase. Be careful modifying history, as it can and will cause conflicts. It is best practice to only rebase while working on a local branch, and always merge if your branch is accessible to other contributors. This is also important if you create a PR and need to make changes after the code review. If you modify the history, it is much harder for the code reviewers to track what has changed since the last code review.

When merging or rebasing, you may face merging conflicts. The basic way to solve a conflict is to edit the file contents between the following markers >>>>>>>>>>>>>> ============== <<<<<<<<<<<<<<

Once the conflict is resolved, you can either commit the changes, or in the case of a rebase, stage the changes and run git rebase --continue. If you want to give up on the rebase and go back to what you had before, you can use git rebase --abort.

Should you ever find yourself wishing you had not rebased after the rebase is completed successfully, you can use the git reflog show command to view your git command history and use git reset <hash> where <hash> is the hash for the change you want to go back to.

The git reset command does a soft reset by default, so you still have a chance to review the changes before they are final. If you know you want to reset and do not need to review the changes, you can use the --hard flag (git reset --hard <hash>).

A common git collaboration workflow is known as "Fork & Push". It requires each collaborator to fork the original repo and push changes to their forks, which then allows them to create a Pull Request against the origin repository. This workflow prevents unintentional updates to the origin repository, as every update must first go through a Pull Request and Code Review. GitHub allows you to protect the origin repository from direct changes as well.

When using this workflow, you will need to set up multiple repositories (origin + you fork aka upstream). You always fetch/pull from upstream before creating a branch, and before rebasing or merging. Additionally, you never push to upstream. Always push to origin instead.

It is a good idea to setup an SSH key to interact with GitHub, you can follow the instructions to set that up:

Tools

Git offers much more than that... Here are some useful tools:

git stash allows you to quickly store your changes in case you need to switch to another branch in the middle of your work. The -u flag will also stash unstaged changes. git stash list will list all of your stashed changes, and git stash pop will attempt to apply the top of the queue to the current branch.

git tag allows to vesion the current commit in a tag, for easy access later on.

git grep allows you to search all files in your branch for a given string or regexp. You can limit the search to a specific file type. ie: git grep "search" -- **/*.txt will search for "search" in txt files

git blame gives you the history of a file, line by line, including who made the change and when it happened.

git bisect is a binary search through your commits. You define a good state and a bad state and git will run a binary search to pinpoint where the issue was introduced.

Automation

Git hooks allow you to automatically run scripts before or after certain actions. eg: This can be useful for linting your files or formatting them before commiting.

Free Books

Useful Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment