├── .gitignore ├── Git ├── 01 Getting Started │ ├── 01 What is Git?.md │ ├── 02 Installing Git.md │ ├── 03 Git vs Github.md │ ├── 04 VScode Setup.md │ ├── 05 First Time Git Setup.md │ ├── 06 Basics.md │ └── images │ │ ├── .DS_Store │ │ ├── 3-stages.png │ │ ├── CVS-vs-DVS.ppm │ │ ├── editor-popularity.png │ │ └── git-config.png ├── 02 Branching │ └── 01 Merge vs Rebase.md ├── 06 Github │ └── PR Commenting.md └── DVC.md ├── README.md ├── [OLD VERSION] ├── 05. Merge.md ├── [OLD] 01. Introduction │ ├── 01. Overview.md │ ├── 02. Introduction.md │ ├── 03. Installation.md │ └── 04. Key Concepts.md ├── [OLD] 02. Getting Started │ └── 01. Setting Up a Repository.md ├── [OLD] 03. Saving Changes │ ├── 01. Add and Commit.md │ ├── 02. Inspecting a Repository.md │ ├── 03. gitignore.md │ └── 04. Branching.md ├── [OLD] 04. Remote Repository │ ├── 01. Remote Repository Setup.md │ └── 02. Configuration.md ├── [OLD] 05. Comparison │ └── 01. Comparing Changes.md ├── [OLD] 06. Undoing Changes │ ├── 0.1 Stashing Your Work.md │ ├── 02. What is Lost?.md │ ├── 03. Undoing a Committed Snapshot.md │ ├── 04. Undoing Uncommitted Changes.md │ └── 05. reset, checkout, revert.md └── images │ ├── 3-stages.png │ ├── after-checkout-branch.png │ ├── after-reset.png │ ├── before-checkout-branch.png │ ├── before-reset.png │ ├── branch.svg │ ├── checkout-branch.png │ ├── checkout-commit.png │ ├── create-branch-pointer.svg │ ├── create-branch.svg │ ├── detached-head.png │ ├── diff-new.png │ ├── diff-no-output.png │ ├── git-add.png │ ├── git-commit.png │ ├── git-directory.png │ ├── git-github.png │ ├── git-init.png │ ├── git-log.png │ ├── git-push.png │ ├── git-stages.png │ ├── git-stash.png │ ├── merge.svg │ └── merge_2.svg ├── files └── text.txt └── images └── logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | .DS_Store 131 | -------------------------------------------------------------------------------- /Git/01 Getting Started/01 What is Git?.md: -------------------------------------------------------------------------------- 1 | Reference: https://git-scm.com/book/en/v2/ 2 | 3 | # About Version Control 4 | ## CVS vs DVS 5 | - Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. 6 | - Version Control Systems 7 | - Centralized Version Control System (CVS) 8 | - Distributed Version Control System (DVS) 9 | 10 | ![CVS-vs-DVS](./images/CVS-vs-DVS.ppm) 11 | 12 | ## Git History 13 | - Linux Kernel VCS 14 | - 1991-2002: Patches and archived files 15 | - 2002-2005: BitKeeper (BitKeeper is a DVCS) 16 | - 2005: Git 17 | - Speed 18 | - Simple Design 19 | - Non-linear Development 20 | - Fully Distributed 21 | - Handle Large Projects 22 | 23 | ## Git Basics 24 | - Snapshots, not differences 25 | - Nearly Every Operation Is Local 26 | - Git Has Integrity 27 | - The mechanism that Git uses for this checksumming is called a SHA-1 hash. 28 | - Git stores everything in its database not by filename but by the hash value of its contents. 29 | - Git Generally Only Adds Data 30 | - The Three States 31 | - Git has three main states that your files can reside in: committed, modified, and staged. 32 | ![3-stages](./images/3-stages.png) 33 | 34 | The basic Git workflow goes something like this: 35 | - You modify files in your working directory. 36 | - You stage the files, adding snapshots of them to your staging area. 37 | - You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory. 38 | -------------------------------------------------------------------------------- /Git/01 Getting Started/02 Installing Git.md: -------------------------------------------------------------------------------- 1 | # Git Installation 2 | To install Git, follow the steps in [Git Installation](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) for your operating system. 3 | 4 | We strongly recomment you to use either MacOS or Linux as your operating system for Git. 5 | -------------------------------------------------------------------------------- /Git/01 Getting Started/03 Git vs Github.md: -------------------------------------------------------------------------------- 1 | # Git vs. Github 2 | Git and GitHub are not the same thing. Git is an open-source, version control tool created in 2005 by developers working on the Linux operating system; GitHub is a company founded in 2008 that makes tools which integrate with git. You do not need GitHub to use git, but you cannot use GitHub without using git. There are many other alternatives to GitHub, such as GitLab, BitBucket, and “host-your-own” solutions such as gogs and gittea. All of these are referred to in git-speak as “remotes”, and all are completely optional. You do not need to use a remote to use git, but it will make sharing your code with others easier. 3 | 4 | Once you are comfortable with Git (or even now before you dive into the contents), create a GitHub account [here](https://github.com/), it's free and easy. However, if you want to know how to work with GitHub, you should first learn Basics of Git. 5 | -------------------------------------------------------------------------------- /Git/01 Getting Started/04 VScode Setup.md: -------------------------------------------------------------------------------- 1 | # VSCode 2 | Visual Studio Code, also commonly referred to as VS Code, is a source-code editor made by Microsoft for Windows, Linux and macOS. Features include support for debugging, syntax highlighting, intelligent code completion, snippets, code refactoring, and embedded Git. Visual Studio Code is a very popular coding editor used by millions of developers around the world. 3 | 4 | The editor has rapidly gained popularity among developers, ranking as the most popular development environment overall in [Stack Overflow’s 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021#most-popular-technologies-new-collab-tools). 5 | 6 | 7 | 8 | ## Installation 9 | ### Windows, Linux, and MacOS 10 | Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows. Download it from [here](https://code.visualstudio.com/download) and install it on your machine. 11 | 12 | ### WSL 13 | To use Visual Studio Code with the Windows Subsystem for Linux, please install Visual Studio Code in Windows and uninstall the Linux version in WSL. You can then use the code command in a WSL terminal just as you would in a normal command prompt. 14 | 15 | ## Extensions 16 | There are literally thousands of extensions in the VS Code marketplace with new ones coming seemingly every single day! Extensions can serve many purposes. From extension-like UI themes to programming language support, debugging, Git integration, and even Spotify players! Extensions are very important because they make the VS Code what it currently is, a very capable piece of software. Without them, VS Code would be not much beyond glorified text editor with good design and basic autocompletion here and there. 17 | 18 | Extensions are really important to customizing your software to suit your personal needs. So please use them! 19 | 20 | For Git we will use the following extensions: 21 | - Git Graph: https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph 22 | - Git Lens: https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens 23 | 24 | We highly recommend you to install the following extensions as well for a better theme (this is a personal preference and completely optional): 25 | - [Material Theme Icons](https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme-icons) 26 | - [Material Theme](https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme) 27 | - [Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme) 28 | - [Dark + Material](https://marketplace.visualstudio.com/items?itemName=vangware.dark-plus-material) 29 | -------------------------------------------------------------------------------- /Git/01 Getting Started/05 First Time Git Setup.md: -------------------------------------------------------------------------------- 1 | # First Time Git Setup 2 | Git comes with a tool called git config that lets you get and set configuration variables that control all aspects of how Git looks and operates. These variables can be stored in three different places: 3 | 4 | - `/etc/gitconfig` file: Contains values for every user on the system and all their repositories. If you pass the option `--system` to `git config`, it reads and writes from this file specifically. 5 | - `~/.gitconfig` or `~/.config/git/config` file: Specific to your user. You can make Git read and write to this file specifically by passing the `--global` option. 6 | - `config` file in the Git directory (that is, `.git/config`) of whatever repository you’re currently using: Specific to that single repository. 7 | 8 | Each level overrides values in the previous level, so values in .`git/config` trump those in `/etc/gitconfig`. 9 | 10 | **Note:** The path to git config file for each level of configuration may be slightly different on your system. To check the path to the config file for global level for example, run `git config --global --edit` and check the opened file path. The same applies for the other levels. 11 | 12 | 13 | 14 | ## Setting Your Username and Email 15 | It’s important to set your user name and email address because every Git commit uses this information, and it’s immutably baked into the commits you start creating: 16 | 17 | ```bash 18 | $ git config --global user.name "John Doe" 19 | $ git config --global user.email 20 | ``` 21 | 22 | ## Checking Your Settings 23 | You can check your settings at any time by running the `git config --list` command: 24 | 25 | ```bash 26 | $ git config --list 27 | user.name=Ali Hejazizo 28 | user.email=hejazizo@ualberta.ca 29 | ``` 30 | 31 | **Note:** 32 | - Your output may include more settings than the ones shown here. The settings shown here are the only settings you need to set up to get started with Git. 33 | - To see the config level of a specific setting, run `git config --show-origin --name-only --get-regexp `. For example, to see the config level of `user.name`, run `git config --show-origin --name-only --get-regexp user.name`. 34 | 35 | 36 | ## Setting Your Default Text Editor 37 | If you want to use a text editor other than Vim/Nano or any other default editor you have on your system, you can set your default text editor with the `core.editor` variable. For example, to set the default text editor to VSCode, you can use: 38 | 39 | ```bash 40 | $ git config --global core.editor "code --wait" 41 | ``` 42 | 43 | **Note:** The `--wait` or `-w` flag is crucial without this git won't know the editing has completed and in turn won't finish executing the git command. 44 | -------------------------------------------------------------------------------- /Git/01 Getting Started/06 Basics.md: -------------------------------------------------------------------------------- 1 | # Gitignore 2 | For a list of patterns that can be used in `.gitignore` files, see [this link](https://git-scm.com/docs/gitignore#_pattern_format) or [Atlassian gitignore guide](https://www.atlassian.com/git/tutorials/saving-changes/gitignore). 3 | 4 | # VScode as difftool 5 | To make VS Code your default “everything”, first you need to ensure you can run VS Code from the command-line. 6 | 7 | Then, run the command `git config --global --edit` to edit the global config, and add the following: 8 | ``` 9 | [core] 10 | editor = code --wait 11 | [diff] 12 | tool = vscode 13 | [difftool "vscode"] 14 | cmd = code --wait --diff $LOCAL $REMOTE 15 | ``` 16 | 17 | If you already have `[core]` section, just add the `[diff]` and `[difftool]` sections to it. 18 | -------------------------------------------------------------------------------- /Git/01 Getting Started/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/Git/01 Getting Started/images/.DS_Store -------------------------------------------------------------------------------- /Git/01 Getting Started/images/3-stages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/Git/01 Getting Started/images/3-stages.png -------------------------------------------------------------------------------- /Git/01 Getting Started/images/CVS-vs-DVS.ppm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/Git/01 Getting Started/images/CVS-vs-DVS.ppm -------------------------------------------------------------------------------- /Git/01 Getting Started/images/editor-popularity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/Git/01 Getting Started/images/editor-popularity.png -------------------------------------------------------------------------------- /Git/01 Getting Started/images/git-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/Git/01 Getting Started/images/git-config.png -------------------------------------------------------------------------------- /Git/02 Branching/01 Merge vs Rebase.md: -------------------------------------------------------------------------------- 1 | # Merge vs Rebase 2 | 3 | - Merge takes all the changes in one branch and merges them into another branch in one commit. 4 | - Rebase says I want the point at which I branched to move to a new starting point 5 | 6 | So when do you use either one? 7 | 8 | ## Merge 9 | Let's say you have created a branch for the purpose of developing a single feature. When you want to bring those changes back to master, you probably want merge. 10 | 11 | ## Rebase 12 | A second scenario would be if you started doing some development and then another developer made an unrelated change. You probably want to pull and then rebase to base your changes from the current version from the repository. 13 | -------------------------------------------------------------------------------- /Git/06 Github/PR Commenting.md: -------------------------------------------------------------------------------- 1 | # How We Encode Code Reviews 2 | 3 | Read about commenting on pull requests in the [GitHub Help](https://help.github.com/articles/commenting-on-a-pull-request/). 4 | -------------------------------------------------------------------------------- /Git/DVC.md: -------------------------------------------------------------------------------- 1 | Read: https://realpython.com/python-data-version-control/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | 4 | logo 5 | 6 | [Pytopia](https://www.pytopia.ai) Git Course Material. Including: 7 | 8 | - Git Basics 9 | - Git Branching 10 | - Git on the Server 11 | - Distributed Git 12 | - GitHub 13 | - Git Tools 14 | - Customizing Git 15 | 16 | We follow **Git Pro textbook by Scott Chacon and Ben Straub** which is available at [here](https://git-scm.com/book/en/v2). 17 | 18 | To register for the course, visit the [Pytopia Website](https://www.pytopia.ai/). 19 | -------------------------------------------------------------------------------- /[OLD VERSION]/05. Merge.md: -------------------------------------------------------------------------------- 1 | # Merge 2 | Merging is Git's way of putting a forked history back together again. The `git merge` command lets you take the independent lines of development created by `git branch` and integrate them into a single branch. 3 | 4 | Note that all of the commands presented below merge into the current branch. The current branch will be updated to reflect the merge, but the target branch will be completely unaffected. Again, this means that `git merge` is often used in conjunction with `git checkout` for selecting the current branch and `git branch -d` for deleting the obsolete target branch. 5 | 6 | ## How it works 7 | 8 | `git merge` will combine multiple sequences of commits into one unified history. In the most frequent use cases, `git merge` is used to combine two branches. The following examples in this document will focus on this branch merging pattern. In these scenarios, `git merge` takes two commit pointers, usually the branch tips, and will find a common base commit between them. Once Git finds a common base commit it will create a new "merge commit" that combines the changes of each queued merge commit sequence. 9 | 10 | Say we have a new branch feature that is based off the `master` branch. We now want to merge this feature branch into `master`. 11 | 12 | git-merge 13 | 14 | Invoking this command will merge the specified branch feature into the current branch, we'll assume master. Git will determine the merge algorithm automatically (discussed below). 15 | 16 | git-merge-2 17 | 18 | Merge commits are unique against other commits in the fact that they have two parent commits. When creating a merge commit Git will attempt to auto magically merge the separate histories for you. If Git encounters a piece of data that is changed in both histories it will be unable to automatically combine them. This scenario is a version control conflict and Git will need user intervention to continue. 19 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 01. Introduction/01. Overview.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | 1. Introduction / Key Concepts 4 | 2. Git Installation and Setup 5 | 3. Quick Start 6 | 4. Basic Commands 7 | 5. Comparing 8 | 6. Branching and Merging 9 | 7. GitHub Introduction 10 | 8. Tools Setup (Text Editor, Compare / Merge Tool) 11 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 01. Introduction/02. Introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | ## What is a Version Control System? 4 | You can think of a version control system (VCS) as a kind of "database". It lets you save a snapshot of your complete project at any time you want. When you later take a look at an older snapshot (let's start calling it "version"), your VCS shows you exactly how it differed from the previous one. 5 | 6 | A Version Control System (VCS) allows you to revert files back to a previous state, revert the entire project back to a previous state, review changes made over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also means that if you screw things up or lose files, you can generally recover easily. And sometimes you just want to know "who wrote this crap", and having access to that information is worthwhile? 7 | 8 | ## Why Source Control 9 | - Backup / Archive 10 | - Versioning / History 11 | - Undo Changes 12 | - Comparing 13 | - Collaboration / Teamwork 14 | - Blame! / Learning Moment 15 | - Isolation of Changes 16 | - Experimentation 17 | - Context Switching 18 | - Code Review 19 | 20 | ## Centralized vs. Distributed VCS 21 | 22 | ### Centralized Version Control 23 | Centralized version control systems are based on the idea that there is a single “central” copy of your project somewhere (probably on a server), and programmers will “commit” their changes to this central copy. 24 | 25 | With Centralized version control, programmers no longer have to keep many copies of files on their hard drives manually, because the version control tool can talk to the central copy and retrieve any version they need on the fly. 26 | 27 | Note: In centralized version control, programmer needs connection to central server for most operations. 28 | 29 | ### Distributed Version Control 30 | 31 | These systems do not necessarily rely on a central server to store all the versions of a project’s files. Instead, every developer “clones” a copy of a repository and has the full history of the project on their own hard drive. This copy (or “clone”) has all of the metadata of the original. 32 | 33 | This method may sound wasteful, but in practice, it’s not a problem. Most programming projects consist mostly of plain text files (and maybe a few images), and disk space is so cheap that storing many copies of a file doesn’t create a noticable dent in a hard drive’s free space. Modern systems also compress the files to use even less space. 34 | 35 | One common misconception about distributed version control systems is that there cannot be a central project repository. This is simply not true – there is nothing stopping you from saying “this copy of the project is the authoritative one.” This means that instead of a central repository being required by the tools you use, it is now optional. 36 | 37 | Note: 38 | - Most operations are local 39 | - Central server is not required 40 | 41 | ## What is Git 42 | By far, the most widely used modern version control system in the world today is Git. Git is a mature, actively maintained open source project originally developed in 2005 by Linus Torvalds, the famous creator of the Linux operating system kernel. 43 | 44 | Having a distributed architecture, Git is an example of a DVCS (hence Distributed Version Control System). Rather than have only one single place for the full version history of the software as is common in once-popular version control systems like CVS or Subversion (also known as SVN), in Git, every developer's working copy of the code is also a repository that can contain the full history of all changes. 45 | 46 | [Read More](https://www.atlassian.com/git/tutorials/what-is-git) -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 01. Introduction/03. Installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | The first two things you'll want to do are install git and create a free GitHub account. 4 | 5 | Follow the instructions [here](https://www.atlassian.com/git/tutorials/install-git) to install git (if it's not already installed). 6 | 7 | Note that for this tutorial we will be using git on the command line only. While there are some great git GUIs (graphical user interfaces), it's easier to learn git using git-specific commands first and then to try out a git GUI once you're more comfortable with the command. 8 | 9 | Once you've done that, create a GitHub account [here](https://github.com/). 10 | 11 | ## Git vs. Github 12 | Git and GitHub are not the same thing. Git is an open-source, version control tool created in 2005 by developers working on the Linux operating system; GitHub is a company founded in 2008 that makes tools which integrate with git. You do not need GitHub to use git, but you cannot use GitHub without using git. There are many other alternatives to GitHub, such as GitLab, BitBucket, and “host-your-own” solutions such as gogs and gittea. All of these are referred to in git-speak as “remotes”, and all are completely optional. You do not need to use a remote to use git, but it will make sharing your code with others easier. -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 01. Introduction/04. Key Concepts.md: -------------------------------------------------------------------------------- 1 | # Key Concepts 2 | 3 | First, in Git, collections of version controlled files are kept together in a repository. The repository also contains the history of changes and any special configuration. Generally speaking, a repository would contain all the files related to a specific project or application. 4 | 5 | ![git-directory](../images/git-directory.png) 6 | 7 | Next, there are three local states related to files being managed by Git: 8 | - The working directory: the directory or folder on your computer that holds all the project or application files. Files within the working directory, may or may not be managed by Git. However, Git is aware of them. 9 | - Staging area: In-between is the Git staging area, often referred to as the Git index, that is a holding area for queueing up changes for the next commit. 10 | - The Git repository or the commit history: The Git repository manages the Git commit history, that is all the changes that are finalized and permanently part of the Git repository. 11 | 12 | ![git-stages](../images/git-stages.png) 13 | 14 | **Note:** Since files in the staging area haven't been committed yet, you can move the files in and out of the staging area without impacting the Git repository, and its history of changes. 15 | 16 | The three states of Git are specific to the local Git repository, but I like to tack on a fourth state, the remote state. Although the remote repository is just another repository with its own three states internally, conceptually, I think of the remote repository as a fourth state; since it is the last step in the basic Git workflow, and since few people use Git without a corresponding remote repository. 17 | 18 | ![git-github](../images/git-github.png) 19 | 20 | While there are several Git hosting services (remote repository) out there, [GitHub](https://www.github.com) is by far the most popular. You can see a comparison of different git hosting services [here](https://bitbucket.org/product/code-repository). 21 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 02. Getting Started/01. Setting Up a Repository.md: -------------------------------------------------------------------------------- 1 | # Setting Up a Repository 2 | 3 | This tutorial provides an overview of how to set up a repository (repo) under Git version control. This resource will walk you through initializing a Git repository for a new or existing project. Included below are workflow examples of repositories both created locally and cloned from remote repositories. This guide assumes a basic familiarity with a command-line interface. 4 | 5 | ## Initialize a New Repository: `git init` 6 | To create a new repo, you'll use the `git init` command. `git init` is a one-time command you use during the initial setup of a new repo. Executing this command will create a new `.git` subdirectory in your current working directory. This will also create a new **main** branch. 7 | 8 | **Note:** All new Git repositories on GitHub will be named "main" instead of "master" starting October 1, 2020. See [here](https://www.zdnet.com/article/github-to-replace-master-with-main-starting-next-month/) 9 | 10 | ![git-init](../images/git-init.png) 11 | 12 | The `git init` command creates a new Git repository. It can be used to convert an existing, unversioned project to a Git repository or initialize a new, empty repository. Most other Git commands are not available outside of an initialized repository, so this is usually the first command you'll run in a new project. 13 | 14 | Executing `git init` creates a `.git` subdirectory in the current working directory, which contains all of the necessary Git metadata for the new repository. This metadata includes subdirectories for objects, refs, and template files. A `HEAD` file is also created which points to the currently checked out commit. 15 | 16 | ### Usage 17 | Git does not require any pre-existing server or admin privileges. All you have to do is cd into your project subdirectory and run `git init`, and you'll have a fully functional Git repository. 18 | 19 | If you've already run `git init` on a project directory and it contains a `.git` subdirectory, you can safely run `git init` again on the same project directory. It will not override an existing `.git` configuration. 20 | 21 | ## Clone an Existing Repository: `git clone` 22 | `git clone` is a Git command line utility which is used to target an existing repository and create a clone, or copy of the target repository. 23 | 24 | If a project has already been set up in a central repository, the `git clone` command is the most common way for users to obtain a development copy. Like `git init`, cloning is generally a one-time operation. Once a developer has obtained a working copy, all version control operations and collaborations are managed through their local repository. 25 | 26 | ### Usage 27 | `git clone` is primarily used to point to an existing repo and make a clone or copy of that repo at in a new directory, at another location. The original repository can be located on the local filesystem or on remote machine accessible supported protocols. The `git clone` command copies an existing Git repository. 28 | 29 | ### Git URLs 30 | Git has its own URL syntax which is used to pass remote repository locations to Git commands 31 | 32 | Git URL protocols: 33 | - **SSH**: Secure Shell (SSH) is a ubiquitous authenticated network protocol that is commonly configured by default on most servers. Because SSH is an authenticated protocol, you'll need to establish credentials with the hosting server before connecting. 34 | 35 | - **HTTP**: Hyper text transfer protocol. The protocol of the web, most commonly used for transferring web page HTML data over the Internet. Git can be configured to communicate over HTTP. 36 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 03. Saving Changes/01. Add and Commit.md: -------------------------------------------------------------------------------- 1 | # Add and Commit 2 | Developing a project revolves around the basic edit/stage/commit pattern. First, you edit your files in the working directory. When you’re ready to save a copy of the current state of the project, you stage changes with git add. After you’re happy with the staged snapshot, you commit it to the project history with `git commit`. 3 | 4 | ## `git add` 5 | When working in Git, or other version control systems, the concept of "saving" is a more nuanced process than saving in a word processor or other traditional file editing applications. The traditional software expression of "saving" is synonymous with the Git term "committing" and Git committing is an operation that acts upon a collection of files and directories. 6 | 7 | The `git add ` command adds a change in the working directory to the staging area. It tells Git that you want to include updates to a particular file in the next commit. However, `git add ` doesn't really affect the repository in any significant way—changes are not actually recorded until you run `git commit`. 8 | 9 | git-add 10 | 11 | The primary function of the `git add` command, is to promote pending changes in the working directory, to the git staging area. The staging area is one of Git's more unique features, and it can take some time to wrap your head around it. The staging area is considered one of the "three trees" of Git, along with, the working directory, and the commit history. 12 | 13 | Instead of committing all of the changes you've made since the last commit, the stage lets you group related changes into highly focused snapshots before actually committing it to the project history. This means you can make all sorts of edits to unrelated files, then go back and split them up into logical commits by adding related changes to the stage and commit them piece-by-piece. As in any revision control system, it’s important to create atomic commits so that it’s easy to track down bugs and revert changes with minimal impact on the rest of the project. 14 | 15 | ## `git commit` 16 | 17 | The `git commit` command captures a snapshot of the project's currently staged changes. Committed snapshots can be thought of as “safe” versions of a project—Git will never change them unless you explicitly ask it to. Prior to the execution of `git commit`, The `git add` command is used to promote or 'stage' changes to the project that will be stored in a commit. These two commands `git commit` and `git add` are two of the most frequently used. 18 | 19 | Instead of making a change and committing it directly to the central repo, Git developers have the opportunity to accumulate commits in their local repo. it makes it easier to split up a feature into atomic commits, keep related commits grouped together, and clean up local history before publishing it to the central repository. It also lets developers work in an isolated environment, deferring integration until they’re at a convenient point to merge with other users. While isolation and deferred integration are individually beneficial, it is in a team's best interest to integrate frequently and in small units. 20 | 21 | **Note:** Git records the entire contents of each file in every commit, not the differences. This makes many Git operations much faster than other version controls such as SVN, since a particular version of a file doesn’t have to be “assembled” from its diffs—the complete revision of each file is immediately available from Git's internal database. 22 | 23 | git-commit 24 | 25 | ### Options 26 | 27 | - `git commit`: Commit the staged snapshot. This will launch a text editor prompting you for a commit message. After you’ve entered a message, save the file and close the editor to create the actual commit. 28 | - `git commit -a`: Commit a snapshot of all changes in the working directory. This only includes modifications to tracked files (those that have been added with `git add` at some point in their history). 29 | - `git commit -m "commit message"`: A shortcut command that immediately creates a commit with a passed commit message. By default, `git commit` will open up the locally configured text editor, and prompt for a commit message to be entered. Passing the -m option will forgo the text editor prompt in-favor of an inline message. 30 | - `git commit -am "commit message"`: A power user shortcut command that combines the `-a` and `-m` options. This combination immediately creates a commit of all the staged changes and takes an inline commit message. 31 | - `git commit --amend`: This option adds another level of functionality to the commit command. Passing this option will modify the last commit. Instead of creating a new commit, staged changes will be added to the previous commit. This command will open up the system's configured text editor and prompt to change the previously specified commit message. 32 | 33 | 34 | **What is a tracked file?** A tracked file is any file that Git is aware of and tracking actively. That would be any file that has already been committed into the Git repository, or any file that has been added to the Git index, or the Git staging area. 35 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 03. Saving Changes/02. Inspecting a Repository.md: -------------------------------------------------------------------------------- 1 | # Inspecting a Repository 2 | 3 | ## `git status` 4 | 5 | The `git status` command displays the state of the working directory and the staging area. It lets you see which changes have been staged, which haven’t, and which files aren’t being tracked by Git. Status output does not show you any information regarding the committed project history. For this, you need to use `git log`. 6 | 7 | `git status` list which files are staged, unstaged, and untracked. 8 | 9 | The `git status` command is a relatively straightforward command. It simply shows you what's been going on with git add and git commit. Status messages also include relevant instructions for staging/unstaging files. 10 | 11 | ### Ignoring Files 12 | 13 | Untracked files typically fall into two categories. 14 | 1. Files that have just been added to the project and haven't been committed yet 15 | 2. Compiled binaries like .pyc, .obj, .exe, etc. 16 | 17 | While it's definitely beneficial to include the former in the `git status` output, the latter can make it hard to see what’s actually going on in your repository. 18 | 19 | For this reason, Git lets you completely ignore files by placing paths in a special file called `.gitignore`. Any files that you'd like to ignore should be included on a separate line, and the * symbol can be used as a wildcard. For example, adding the following to a `.gitignore` file in your project root will prevent compiled Python modules from appearing in `git status`: 20 | 21 | ``` 22 | *.pyc 23 | ``` 24 | 25 | ## `git log` 26 | The git log command displays committed snapshots. It lets you list the project history, filter it, and search for specific changes. While `git status` lets you inspect the working directory and the staging area, git log only operates on the committed history. 27 | 28 | git-log 29 | 30 | Log output can be customized in several ways, from simply filtering commits to displaying them in a completely user-defined format. Some of the most common configurations of `git log` are presented below. 31 | 32 | - `git log`: Display the entire commit history using the default formatting. If the output takes up more than one screen, you can use Space to scroll and `q` to exit. 33 | - `git log -n `: Limit the number of commits to display. For example, `git log -n 3` will display only 3 commits. 34 | - `git log --oneline`: Condense each commit to a single line. This is useful for getting a high-level overview of the project history. 35 | - `git log --stat`: Along with the ordinary git log information, include which files were altered and the relative number of lines that were added or deleted from each of them. 36 | - `git log `: Only display commits that include the specified file. This is an easy way to see the history of a particular file. 37 | - `git log -p`: Display the patch representing each commit. This shows the full diff of each commit, which is the most detailed view you can have of your project history. 38 | - `git log -p `: Display the patch representing for `` 39 | - `git log --author=""`: Search for commits by a particular author. The argument can be a plain string or a regular expression. 40 | - `git log --grep=""`: Search for commits with a commit message that matches, which can be a plain string or a regular expression. 41 | - `git log --graph --decorate`: The --graph flag that will draw a text based graph of the commits on the left hand side of the commit messages. --decorate adds the names of branches or tags of the commits that are shown. 42 | 43 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 03. Saving Changes/03. gitignore.md: -------------------------------------------------------------------------------- 1 | # gitignore 2 | 3 | Git sees every file in your working copy as one of three things: 4 | 5 | 1. Tracked - a file which has been previously staged or committed. 6 | 2. Untracked - a file which has not been staged or committed. 7 | 3. Ignored - a file which Git has been explicitly told to ignore. 8 | 9 | Ignored files are usually build artifacts and machine generated files that can be derived from your repository source or should otherwise not be committed. Some common examples are: 10 | 11 | - Dependency caches, such as the contents of `/node_modules` or `/packages` 12 | - Compiled code, such as `.o`, `.pyc`, and `.class` files 13 | - Build output directories, such as `/bin`, `/out`, or `/target` 14 | - Files generated at runtime, such as `.log`, `.lock`, or `.tmp` 15 | - Hidden system files, such as `.DS_Store` or `Thumbs.db` 16 | - Personal IDE config files, such as `.idea/workspace.xml` 17 | 18 | Ignored files are tracked in a special file named `.gitignore` that is checked in at the root of your repository. There is no explicit git ignore command: instead the `.gitignore` file must be edited and committed by hand when you have new files that you wish to ignore. `.gitignore` files contain patterns that are matched against file names in your repository to determine whether or not they should be ignored. 19 | 20 | ## Git Ignore Patterns 21 | `.gitignore` uses [globbing patterns](http://linux.die.net/man/7/glob) to match against file names. You can construct your patterns using various symbols: 22 | 23 | |Pattern|Example Matches|Explanation*| 24 | |:--|:--|:--| 25 | |`**/logs`|`logs/debug.log`
`logs/monday/foo.bar`
`build/logs/debug.log`|You can prepend a pattern with a double asterisk to match directories anywhere in the repository.| 26 | |`**/logs/debug.log`|`logs/debug.log`
`build/logs/debug.log`
but NOT `logs/build/debug.log`|You can also use a double asterisk to match files based on their name and the name of their parent directory.| 27 | |`*.log`|`debug.log`
`foo.log`
`.log`
`logs/debug.log`|An asterisk is a wildcard that matches zero or more characters.| 28 | |`*.log`
`!important.log`|`debug.log`
`trace.log`
but NOT
`important.log`
`logs/important.log`|Prepending an exclamation mark to a pattern negates it. If a file matches a pattern, but also matches a negating pattern defined later in the file, it will not be ignored.| 29 | |`*.log`
`!important/*.log`
`trace.*`|`debug.log`
`important/trace.log`
but NOT `important/debug.log`|Patterns defined after a negating pattern will re-ignore any previously negated files.| 30 | |`/debug.log`|`debug.log`
but NOT `logs/debug.log`|Prepending a slash matches files only in the repository root.| 31 | |`debug.log`|`debug.log`
`logs/debug.log`|By default, patterns match files in any directory| 32 | |`debug?.log`|`debug0.log`
`debugg.log`
but NOT `debug10.log`|A question mark matches exactly one character.| 33 | |`debug[0-9].log`|`debug0.log`
`debug1.log`
but NOT `debug10.log`|Square brackets can also be used to match a single character from a specified range.| 34 | |`debug[01].log`|`debug0.log`
`debug1.log`
but NOT
`debug2.log`
`debug01.log`|Square brackets match a single character form the specified set.| 35 | |`debug[!01].log`|`debug2.log`
but NOT
`debug0.log`
`debug1.log`
`debug01.log`|An exclamation mark can be used to match any character except one from the specified set.| 36 | |`debug[a-z].log`|`debuga.log`
`debugb.log`
but NOT `debug1.log`|Ranges can be numeric or alphabetic.| 37 | |`logs`|`logs`
`logs/debug.log`
`logs/latest/foo.bar`
`build/logs`
`build/logs/debug.log`|If you don't append a slash, the pattern will match both files and the contents of directories with that name. In the example matches on the left, both directories and files named logs are ignored| 38 | |`logs/`|`logs/debug.log`
`logs/latest/foo.bar`
`build/logs/foo.bar`
`build/logs/latest/debug.log`|Appending a slash indicates the pattern is a directory. The entire contents of any directory in the repository matching that name – including all of its files and subdirectories – will be ignored| 39 | |`logs/`
`!logs/important.log`|`logs/debug.log`
`logs/important.log`|Wait a minute! Shouldn't logs/important.log be negated in the example on the left

Nope! Due to a performance-related quirk in Git, you can not negate a file that is ignored due to a pattern matching a directory| 40 | |`logs/**/debug.log`|`logs/debug.log`
`logs/monday/debug.log`
`logs/monday/pm/debug.log`|A double asterisk matches zero or more directories.| 41 | |`logs/*day/debug.log`|`logs/monday/debug.log`
`logs/tuesday/debug.log`
but NOT
`logs/latest/debug.log`|Wildcards can be used in directory names as well.| 42 | |`logs/debug.log`|`logs/debug.log`
but NOT
`debug.log`
`build/logs/debug.log`|Patterns specifying a file in a particular directory are relative to the repository root. (You can prepend a slash if you like, but it doesn't do anything special.)| 43 | 44 | **Note:** These explanations assume your `.gitignore` file is in the top level directory of your repository, as is the convention. If your repository has multiple `.gitignore` files, simply mentally replace "repository root" with "directory containing the `.gitignore` file" (and consider unifying them, for the sanity of your team). 45 | 46 | In addition to these characters, you can use # to include comments in your .gitignore file: 47 | 48 | ``` 49 | # ignore all logs *.log 50 | ``` 51 | 52 | You can use `\` to escape `.gitignore` pattern characters if you have files or directories containing them: 53 | 54 | ``` 55 | # ignore the file literally named foo[01].txt foo\[01\].txt 56 | ``` 57 | 58 | ## Shared `.gitignore` files in your repository 59 | Git ignore rules are usually defined in a `.gitignore` file at the root of your repository. However, you can choose to define multiple `.gitignore` files in different directories in your repository. Each pattern in a particular `.gitignore` file is tested relative to the directory containing that file. However the convention, and simplest approach, is to define a single `.gitignore` file in the root. As your `.gitignore` file is checked in, it is versioned like any other file in your repository and shared with your teammates when you push. Typically you should only include patterns in `.gitignore` that will benefit other users of the repository. 60 | 61 | ## Personal `.gitignore` rules 62 | You can also define personal ignore patterns for a particular repository in a special file at `.git/info/exclude`. These are not versioned, and not distributed with your repository, so it's an appropriate place to include patterns that will likely only benefit you. For example if you have a custom logging setup, or special development tools that produce files in your repository's working directory, you could consider adding them to `.git/info/exclude` to prevent them from being accidentally committed to your repository. 63 | 64 | ## Global `.gitignore` rules 65 | In addition, you can define global Git ignore patterns for all repositories on your local system by setting the Git core.excludesFile property. You'll have to create this file yourself. If you're unsure where to put your global `.gitignore` file, your home directory isn't a bad choice (and makes it easy to find later). Once you've created the file, you'll need to configure its location with git config: 66 | 67 | ```bash 68 | $ touch ~/.gitignore 69 | $ git config --global core.excludesFile ~/.gitignore 70 | ``` 71 | 72 | You should be careful what patterns you choose to globally ignore, as different file types are relevant for different projects. Special operating system files (e.g. .DS_Store and thumbs.db) or temporary files created by some developer tools are typical candidates for ignoring globally. 73 | 74 | ## Ignoring a Previously Committed File 75 | 76 | If you want to ignore a file that you've committed in the past, you'll need to delete the file from your repository and then add a `.gitignore` rule for it. Using the `--cached` option with `git rm` means that the file will be deleted from your repository, but will remain in your working directory as an ignored file. 77 | 78 | ``` 79 | $ echo debug.log >> .gitignore 80 | $ git rm --cached debug.log 81 | $ git commit -m "Start ignoring debug.log" 82 | ``` 83 | 84 | You can omit the `--cached` option if you want to delete the file from both the repository and your local file system. 85 | 86 | ## Committing an Ignored File 87 | 88 | It is possible to force an ignored file to be committed to the repository using the `-f` (or `--force`) option with `git add`: 89 | 90 | ```bash 91 | $ git add -f debug.log 92 | $ git commit -m "Force adding debug.log" 93 | ``` 94 | 95 | You might consider doing this if you have a general pattern (like `*.log`) defined, but you want to commit a specific file. However a better solution is to define an exception to the general rule: 96 | 97 | ```bash 98 | $ echo !debug.log >> .gitignore 99 | $ git add debug.log 100 | $ git commit -m "Adding debug.log" 101 | ``` 102 | 103 | This approach is more obvious, and less confusing, for your teammates. 104 | 105 | ## Debugging `.gitignore` Files 106 | If you have complicated `.gitignore` patterns, or patterns spread over multiple `.gitignore` files, it can be difficult to track down why a particular file is being ignored. You can use the git check-ignore command with the `-v` (or `--verbose`) option to determine which pattern is causing a particular file to be ignored: 107 | 108 | ```bash 109 | git check-ignore -v debug.log 110 | ``` 111 | 112 | You can pass multiple file names to git check-ignore if you like, and the names themselves don't even have to correspond to files that exist in your repository. 113 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 03. Saving Changes/04. Branching.md: -------------------------------------------------------------------------------- 1 | # Branching 2 | 3 | Branching is a feature available in most modern version control systems. 4 | 5 | In Git, branches are a part of your everyday development process. Git branches are effectively a pointer to a snapshot of your changes. When you want to add a new feature or fix a bug—no matter how big or how small—you spawn a new branch to encapsulate your changes. This makes it harder for unstable code to get merged into the main code base, and it gives you the chance to clean up your feature's history before merging it into the main branch. 6 | 7 | git-log 8 | 9 | The diagram above visualizes a repository with two isolated lines of development, one for a little feature, and one for a longer-running feature. By developing them in branches, it’s not only possible to work on both of them in parallel, but it also keeps the main `master` branch free from questionable code. 10 | 11 | The implementation behind Git branches is much more lightweight than other version control system models. Instead of copying files from directory to directory, Git stores a branch as a reference to a commit. In this sense, a branch represents the tip of a series of commits—it's not a container for commits. The history for a branch is extrapolated through the commit relationships. 12 | 13 | ## How it works 14 | A branch represents an independent line of development. Branches serve as an abstraction for the edit/stage/commit process. You can think of them as a way to request a brand new working directory, staging area, and project history. New commits are recorded in the history for the current branch, which results in a fork in the history of the project. 15 | 16 | The git branch command lets you create, list, rename, and delete branches. It doesn’t let you switch between branches or put a forked history back together again. For this reason, `git branch` is tightly integrated with the `git checkout` and `git merge` commands. 17 | 18 | ## Command Options 19 | |Command|Description| 20 | |:--|:--| 21 | |`git branch`|List all of the branches in your repository. This is synonymous with `git branch --list`.| 22 | |`git branch `|Create a new branch called `<branch>`. This does not check out the new branch.| 23 | |`git branch -d `|Delete the specified branch. This is a “safe” operation in that Git prevents you from deleting the branch if it has unmerged changes.| 24 | |`git branch -D `|Force delete the specified branch, even if it has unmerged changes. This is the command to use if you want to permanently throw away all of the commits associated with a particular line of development.| 25 | |`git branch -m `|Rename the current branch to `<branch>`.| 26 | |`git branch -a`|List all remote branches. | 27 | 28 | ## Creating Branches 29 | It's important to understand that branches are just pointers to commits. When you create a branch, all Git needs to do is create a new pointer, it doesn’t change the repository in any other way. If you start with a repository that looks like this: 30 | 31 | create-branch 32 | 33 | Then, you create a branch using the following command: 34 | ``` 35 | git branch crazy-experiment 36 | ``` 37 | The repository history remains unchanged. All you get is a new pointer to the current commit: 38 | 39 | create-branch-pointer 40 | 41 | Note that this only creates the new branch. To start adding commits to it, you need to select it with `git checkout`, and then use the standard `git add` and `git commit` commands. 42 | 43 | ## Deleting Branches 44 | Once you’ve finished working on a branch and have merged it into the main code base, you’re free to delete the branch without losing any history: 45 | ``` 46 | git branch -d crazy-experiment 47 | ``` 48 | However, if the branch hasn’t been merged, the above command will output an error message: 49 | ``` 50 | error: The branch 'crazy-experiment' is not fully merged. If you are sure you want to delete it, run 'git branch -D crazy-experiment'. 51 | ``` 52 | 53 | This protects you from losing access to that entire line of development. If you really want to delete the branch (e.g., it’s a failed experiment), you can use the capital `-D` flag: 54 | ``` 55 | git branch -D crazy-experiment 56 | ``` 57 | 58 | This deletes the branch regardless of its status and without warnings, so use it judiciously. 59 | 60 | # Checkout Between Branches 61 | 62 | This page is an examination of the `git checkout` command. It will cover usage examples and edge cases. In Git terms, a "checkout" is the act of switching between different versions of a target entity 63 | 64 | ## Checking out Branches 65 | The `git checkout` command lets you navigate between the branches created by git branch. Checking out a branch updates the files in the working directory to match the version stored in that branch, and it tells Git to record all new commits on that branch. Think of it as a way to select which line of development you’re working on. 66 | 67 | ## Usage: Existing branches 68 | Assuming the repo you're working in contains pre-existing branches, you can switch between these branches using `git checkout`. To find out what branches are available and what the current branch name is, execute `git branch`. 69 | 70 | ``` 71 | $ git branch 72 | main 73 | feature_inprogress_branch 74 | $ git checkout feature_inprogress_branch 75 | ``` 76 | The above example demonstrates how to view a list of available branches by executing the git branch command, and switch to a specified branch, in this case, the `feature_inprogress_branch`. 77 | 78 | ## New Branches 79 | `git checkout` works hand-in-hand with `git branch`. The `git branch` command can be used to create a new branch. When you want to start a new feature, you create a new branch off master using `git branch` `new_branch`. Once created you can then use `git checkout new_branch` to switch to that branch. Additionally, The `git checkout` command accepts a `-b` argument that acts as a convenience method which will create the new branch and immediately switch to it. You can work on multiple features in a single repository by switching between them with `git checkout`. 80 | ``` 81 | git checkout -b 82 | ``` 83 | The above example simultaneously creates and checks out . The `-b` option is a convenience flag that tells Git to run `git branch` before running `git checkout`. -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 04. Remote Repository/01. Remote Repository Setup.md: -------------------------------------------------------------------------------- 1 | # Remote Repository Setup 2 | 3 | You’ve now got a local git repository. You can use git locally, like that, if you want. But if you want the thing to have a home on github, do the following. 4 | 5 | 1. Go to github. 6 | 2. Log in to your account. 7 | 3. Click the **new repository** button in the top-right. 8 | 4. Choose a proper name for the remote repository. Add a description (optional). 9 | 5. You may select **Private** if you choose who can see and commit to this repository or **Public** so that anyone on the internet can see this repository and you choose who can commit. 10 | 6. You’ll have an option there to initialize the repository with a `README` file, a `.gitignore` template file, and a license. 11 | 7. Click the **Create repository** button. 12 | 13 | You now have a remote repository. 14 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 04. Remote Repository/02. Configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | Once you have a remote repo setup, you will need to add a remote repo url to your local git config, and set an upstream branch for your local branches. The git remote command offers such utility: 4 | - `git remote add ` 5 | 6 | This command will map remote repository at to a ref in your local repo under. Once you have mapped the remote repo you can push local branches to it: 7 | - `git push -u ` 8 | 9 | This command will push the local repo branch under `` to the remote repo at ``. 10 | 11 | **Note:** If you clone a repo, your remote is already set up. You can see the list of remotes by running `git remote -v`. 12 | 13 | ## Git Config Levels 14 | In addition to configuring a remote repo URL, you may also need to set global Git configuration options such as username, or email. The `git config` command lets you configure your Git installation (or an individual repository) from the command line. This command can define everything from user info, to preferences, to the behavior of a repository. Several common configuration options are listed below. 15 | 16 | Git stores configuration options in three separate files, which lets you scope options to individual repositories (local), user (Global), or the entire system (system): 17 | - Local: `/.git/config` – **Repository-specific** settings. 18 | 19 | By default, `git config` will write to a local level if no configuration option is passed. Local level configuration is applied to the context repository `git config` gets invoked in. Local configuration values are stored in a file that can be found in the repo's .git directory: .git/config 20 | 21 | - Global: `/.gitconfig` – **User-specific** settings. This is where options set with the --global flag are stored. 22 | 23 | Global level configuration is user-specific, meaning it is applied to an operating system user. Global configuration values are stored in a file that is located in a user's home directory. `~/.gitconfig` on unix systems and `C:\Users\\.gitconfig on windows 24 | 25 | - System: `$(prefix)/etc/gitconfig` – **System-wide** settings. 26 | 27 | System-level configuration is applied across an entire machine. This covers all users on an operating system and all repos. The system level configuration file lives in a gitconfig file off the system root path. `$(prefix)/etc/gitconfig` on unix systems. On windows this file can be found at `C:\Documents and Settings\All Users\Application Data\Git\config` on Windows XP, and in `C:\ProgramData\Git\config` on Windows Vista and newer. 28 | 29 | Thus the order of priority for configuration levels is: local, global, system. This means when looking for a configuration value, Git will start at the local level and bubble up to the system level. 30 | 31 | ## Writing a Value 32 | Expanding on what we already know about `git config`, let's look at a few example in which we write a value: 33 | 34 | Define the author name to be used for all commits in the current repository. Typically, you’ll want to use the --global flag to set configuration options for the current user. 35 | 36 | Define the author name to be used for all commits by the current user. 37 | ``` 38 | git config --global user.name 39 | ``` 40 | 41 | Adding the `--local` option or not passing a config level option at all, will set the user.name for the current local repository. 42 | ``` 43 | git config --local user.email 44 | ``` 45 | 46 | Create a **shortcut** (**alias**) for a Git command. This is a powerful utility to create custom shortcuts for commonly used git commands. A simplistic example would be: 47 | 48 | ```bash 49 | git config --global alias.hist "log --oneline" 50 | ``` 51 | This creates a `git hist` command that you can execute as a shortcut to `git log --oneline`. 52 | 53 | To open the local/global/system wide configuration file in a text editor for manual editing: 54 | ``` 55 | git config --global --edit 56 | ``` 57 | ## Git Editor 58 | Many Git commands will launch a text editor to prompt for further input. One of the most common use cases for `git config` is configuring which editor Git should use. Listed below is a table of popular editors and matching `git config` commands: 59 | 60 | 61 | |Editor|Config Command| 62 | |:--|:--| 63 | |Atom|`git config --global core.editor "atom --wait"`} 64 | |emacs|`git config --global core.editor "emacs"`| 65 | |nano|`git config --global core.editor "nano -w"`| 66 | |vim|`git config --global core.editor "vim"`| 67 | |Sublime Text (Mac)|`git config --global core.editor "subl -n -w"`| 68 | |Sublime Text (Win, 32-bit install)|`git config --global core.editor "'c:/program files (x86)/sublime text 3/sublimetext.exe' -w"`| 69 | |Sublime Text (Win, 64-bit install)|`git config --global core.editor "'c:/program files/sublime text 3/sublimetext.exe' -w"`| 70 | |Textmate|`git config --global core.editor "mate -w"`| -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 05. Comparison/01. Comparing Changes.md: -------------------------------------------------------------------------------- 1 | # Comparing Changes 2 | 3 | Diffing is a function that takes two input data sets and outputs the changes between them. `git diff` is a multi-use Git command that when executed runs a `diff` function on Git data sources. These data sources can be commits, branches, files and more. 4 | 5 | This section will discuss common invocations of `git diff` and diffing work flow patterns. The `git diff` command is often used along with git status and git log to analyze the current state of a Git repo. 6 | 7 | ## Reading `diff` Output 8 | 9 | ### Raw output format 10 | If we execute `git diff` when there are no changes, there will be no output. This is expected behavior as there are no changes in the repo to `diff`. 11 | 12 | git-diff 13 | 14 | Once the repo is created and we've added some changes, such as adding `diff_test.txt` file, we can change the contents of the file to start experimenting with diff output. 15 | 16 | diff-new 17 | 18 | Let us now examine a more detailed breakdown of the diff output. 19 | 20 | 1. Comparison Input 21 | ``` 22 | diff --git a/diff_test.txt b/diff_test.txt 23 | ``` 24 | 25 | This line displays the input sources of the diff. We can see that `a/diff_test.txt` and `b/diff_test.txt` have been passed to the diff. 26 | 27 | 2. Meta Data 28 | ``` 29 | index 3b18e51..1ca31a6 100644 30 | ``` 31 | This line displays some internal Git metadata. You will most likely not need this information. The numbers in this output correspond to Git object version hash identifiers. 32 | 33 | 3. Markers for Changes 34 | ``` 35 | --- a/diff_test.txt 36 | +++ b/diff_test.txt 37 | ``` 38 | These lines are a legend that assigns symbols to each diff input source. In this case, changes from `a/diff_test.txt` are marked with a `---` and the changes from `b/diff_test.txt` are marked with the `+++` symbol. 39 | 40 | 4. Diff Chunks 41 | The remaining `diff` output is a list of `diff` 'chunks'. A `diff` only displays the sections of the file that have changes. In our current example, we only have one chunk as we are working with a simple scenario. Chunks have their own granular output semantics. 42 | 43 | ``` 44 | @@ -1 +1,2 @@ 45 | hello world 46 | +this line is NEW 47 | ``` 48 | The first line is the chunk header, or hunk. Each chunk is prepended by a header inclosed within `@@` symbols. The content of the header is a summary of changes made to the file. In our simplified example, we have -1 +1 meaning line one had changes. In a more realistic `diff`, you would see a header like: 49 | 50 | ``` 51 | @@ -34,6 +34,8 @@ 52 | ``` 53 | In this header example, 6 lines have been extracted starting from line number 34. Additionally, 8 lines have been added starting at line number 34. 54 | 55 | The remaining content of the diff chunk displays the recent changes. Each changed line is prepended with a `+` or `-` symbol indicating which version of the diff input the changes come from. As we previously discussed, `-` indicates changes from the `a/diff_test.txt` and `+` indicates changes from `b/diff_test.txt`. 56 | 57 | ## Comparing files: `git diff file` 58 | 59 | The `git diff` command can be passed an explicit file path option. When a file path is passed to `git diff` the diff operation will be scoped to the specified file. The below examples demonstrate this usage. 60 | 61 | ```bash 62 | git diff HEAD ./path/to/file 63 | ``` 64 | 65 | The `HEAD` in Git is the pointer to the current branch reference, which is in turn a pointer to the last commit you made or the last commit that was checked out into your working directory. That also means it will be the parent of the next commit you do. It's generally simplest to think of it as `HEAD` is the snapshot of your last commit. 66 | 67 | Git makes note of this current branch in a file located inside the Git repository, in `.git/HEAD`. (This is an internal file, so it should not be manually manipulated!) 68 | If you wonder what exactly this file contains, you can simply have its contents printed on the command line: 69 | 70 | ```bash 71 | $ cat .git/HEAD 72 | ref: refs/heads/main 73 | ``` 74 | In this example case, a local branch named "main" is the current `HEAD`. 75 | 76 | **Note:** It is possible for `HEAD` to refer to a specific revision that is not associated with a branch name. This situation is called a detached `HEAD`. 77 | 78 | By default, `git diff` is to view the changes you made relative to the index (staging area for the next commit). In other words, the differences are what you could tell Git to further add to the index but you still haven’t. You can stage these changes by using `git add`. 79 | 80 | When `git diff` is invoked with the `--cached` option the diff will compare the staged changes with the local repository. The `--cached` option is synonymous with `--staged`. 81 | ```bash 82 | git diff --cached ./path/to/file 83 | git diff --staged ./path/to/file 84 | ``` 85 | 86 | ## Comparing all changes 87 | Invoking `git diff` without a file path will compare changes across the entire repository. The above, file specific examples, can be invoked without the `./path/to/file` argument and have the same output results across all files in the local repo. 88 | 89 | ### Changes since last commit 90 | By default `git diff` will show you any uncommitted changes (and not staged) since the last commit. 91 | ```bash 92 | git diff 93 | ``` 94 | 95 | ### Comparing files between two different commits 96 | 97 | `git diff` can be passed Git refs to commits to diff. Some example refs are, **HEAD**, **tags**, and **branch names**. Every commit in Git has a commit `ID` which you can get when you execute `git log`. You can also pass this commit ID to `git diff`. 98 | 99 | ```bash 100 | git diff 6de8e2c 2cb6699 101 | ``` 102 | 103 | ### Comparing Branches 104 | Branches are compared like all other ref inputs to `git diff`: 105 | ```bash 106 | git diff branch_1 branch_2 107 | ``` 108 | 109 | ### Comparing files from two branches 110 | To compare a specific file across branches, pass in the path of the file as the third argument to `git diff`: 111 | ```bash 112 | git diff main new_branch ./file.txt 113 | ``` 114 | 115 | ## Summary 116 | 117 | |Command|Description| 118 | |:--|:--| 119 | |`git diff`|Comparisong of unsta| 120 | |`git diff `|All unstaged changes of `` and ``| 121 | |`git diff --cached`|All changes of staging area.| 122 | |`git diff --cached `|All changes of staging area for `` and ``.| 123 | |`git diff `|All changes with respect to reference.| 124 | |`git diff `|All changes of `` and `` with respect to reference.| 125 | |`git diff branch_1 branch_2`|Comparison between `branch_` and `branch_2`| 126 | |`git diff branch_1 branch_2 `|Comparison between `branch_` and `branch_2` for `` and ``.| 127 | 128 | **Note:** 129 | - Examples of reference are: `HEAD`, ``, tag, etc. -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 06. Undoing Changes/0.1 Stashing Your Work.md: -------------------------------------------------------------------------------- 1 | # Stashing Your Work 2 | 3 | The `git stash` command takes your uncommitted changes (both staged and unstaged), saves them away for later use, and then reverts them from your working copy. For example: 4 | 5 | ```bash 6 | $ git status 7 | On branch master 8 | Changes to be committed: 9 | 10 | new file: style.css 11 | 12 | Changes not staged for commit: 13 | 14 | modified: index.html 15 | 16 | $ git stash 17 | Saved working directory and index state WIP on master: 5002d47 our new homepage 18 | HEAD is now at 5002d47 our new homepage 19 | 20 | $ git status 21 | On branch master 22 | nothing to commit, working tree clean 23 | ``` 24 | 25 | At this point you're free to make changes, create new commits, switch branches, and perform any other Git operations; then come back and re-apply your stash when you're ready. 26 | 27 | Note that the stash is local to your Git repository; stashes are not transferred to the server when you push. 28 | 29 | ## Re-applying your stashed changes 30 | You can reapply previously stashed changes with `git stash pop`: 31 | ```bash 32 | git stash pop 33 | ``` 34 | 35 | Popping your stash removes the changes from your stash and reapplies them to your working copy. 36 | 37 | Alternatively, you can reapply the changes to your working copy and keep them in your stash with `git stash apply`: 38 | ```bash 39 | git stash apply 40 | ``` 41 | 42 | This is useful if you want to apply the same stashed changes to multiple branches. 43 | 44 | Now that you know the basics of stashing, there is one caveat with `git stas`h you need to be aware of: by default Git won't stash changes made to **untracked** or **ignored files**. 45 | 46 | ## Stashing untracked or ignored files 47 | By default, running `git stash` will stash: 48 | 49 | - changes that have been added to your index (staged changes) 50 | - changes made to files that are currently tracked by Git (unstaged changes) 51 | 52 | But it will **not** stash: 53 | - New files in your working copy that have not yet been staged 54 | - files that have been ignored 55 | 56 | So if we add a third file to our example above, but don't stage it (i.e. we don't run `git add`), `git stash` won't stash it. 57 | 58 | Adding the `-u` option (or `--include-untracked`) tells `git stash` to also stash your untracked files: 59 | ```bash 60 | git stash -u 61 | ``` 62 | 63 | You can include changes to ignored files as well by passing the `-a` option (or `--all`) when running `git stash`. 64 | 65 | git-stash 66 | 67 | ## Managing multiple stashes 68 | 69 | You aren't limited to a single stash. You can run `git stash` several times to create multiple stashes, and then use `git stash list` to view them. By default, stashes are identified simply as a **WIP** – work in progress – on top of the branch and commit that you created the stash from. After a while it can be difficult to remember what each stash contains: 70 | 71 | ```bash 72 | $ git stash list 73 | stash@{0}: WIP on master: 5002d47 our new homepage 74 | stash@{1}: WIP on master: 5002d47 our new homepage 75 | stash@{2}: WIP on master: 5002d47 our new homepage 76 | ``` 77 | 78 | To provide a bit more context, it's good practice to annotate your stashes with a description, using `git stash save "message"`: 79 | 80 | ```bash 81 | $ git stash save "add style to our site" 82 | Saved working directory and index state On master: add style to our site 83 | HEAD is now at 5002d47 our new homepage 84 | 85 | $ git stash list 86 | stash@{0}: On master: add style to our site 87 | stash@{1}: WIP on master: 5002d47 our new homepage 88 | stash@{2}: WIP on master: 5002d47 our new homepage 89 | ``` 90 | 91 | By default, git stash pop will re-apply the most recently created stash: `stash@{0}` 92 | 93 | You can choose which stash to re-apply by passing its identifier as the last argument, for example: 94 | 95 | ```bash 96 | git stash pop stash@{2} 97 | ``` 98 | 99 | ## Viewing stash diffs 100 | You can view a summary of a stash with `git stash show`: 101 | ```bash 102 | $ git stash show 103 | index.html | 1 + 104 | style.css | 3 +++ 105 | 2 files changed, 4 insertions(+) 106 | ``` 107 | 108 | Or pass the `-p` option (or `--patch`) to view the full diff of a stash: 109 | ```bash 110 | git stash show -p 111 | ``` 112 | 113 | ## Partial stashes 114 | You can also choose to stash just a single file, a collection of files, or individual changes from within files. If you pass the `-p` option (or `--patch`) to `git stash`, it will iterate through each changed "hunk" in your working copy and ask whether you wish to stash it: 115 | ```bash 116 | git stash -p 117 | ``` 118 | 119 | You can hit `?` for a full list of hunk commands. Commonly useful ones are: 120 | 121 | |Command|Description| 122 | |:--|:--| 123 | |`/`|search for a hunk by regex| 124 | |`?`|help| 125 | |`n`|don't stash this hunk| 126 | |`q`|quit (any hunks that have already been selected will be stashed)| 127 | |`s`|split this hunk into smaller hunks| 128 | |`y`|stash this hunk| 129 | 130 | There is no explicit "abort" command, but hitting `CTRL-C` will abort the stash process. 131 | 132 | ## Cleaning up your stash 133 | If you decide you no longer need a particular stash, you can delete it with `git stash drop`: 134 | 135 | ```bash 136 | git stash drop stash@{0} 137 | ``` 138 | 139 | Or you can delete all of your stashes with: 140 | ```bash 141 | git stash clear 142 | ``` 143 | 144 | ## Summary 145 | - Stash your work (any will do) 146 | ```bash 147 | $ git stash save 148 | $ git stash 149 | ``` 150 | 151 | - See what you got 152 | ```bash 153 | $ git stash list 154 | ``` 155 | 156 | - Apply 157 | ```bash 158 | $ git stash apply stash@{0} 159 | ``` 160 | 161 | - Clean up (any will do) 162 | ```bash 163 | $ git stash drop stash@{0} 164 | $ git stash pop 165 | $ git stash clear 166 | ``` 167 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 06. Undoing Changes/02. What is Lost?.md: -------------------------------------------------------------------------------- 1 | # Undoing Commits and Changes 2 | 3 | In this section, we will discuss the available 'undo' Git strategies and commands. It is first important to note that Git does not have a traditional 'undo' system like those found in a word processing application. It will be beneficial to refrain from mapping Git operations to any traditional 'undo' mental model. Additionally, Git has its own nomenclature for 'undo' operations that it is best to leverage in a discussion. This nomenclature includes terms like `reset`, `revert`, `checkout`, `clean`, and more. 4 | 5 | A fun metaphor is to think of Git as a timeline management utility. Commits are snapshots of a point in time or points of interest along the timeline of a project's history. Additionally, multiple timelines can be managed through the use of branches. When 'undoing' in Git, you are usually moving back in time, or to another timeline where mistakes didn't happen. 6 | 7 | This section provides all of the necessary skills to work with previous revisions of a software project. First, it shows you how to explore old commits, then it explains the difference between reverting public commits in the project history vs. resetting unpublished changes on your local machine. 8 | 9 | ## Finding what is lost: Reviewing old commits 10 | The whole idea behind any version control system is to store “safe” copies of a project so that you never have to worry about irreparably breaking your code base. Once you’ve built up a project history of commits, you can review and revisit any commit in the history. One of the best utilities for reviewing the history of a Git repository is the `git log` command. In the example below, we use `git log` to get a list of the latest commits to a popular open-source graphics library. 11 | 12 | Each commit has a unique SHA-1 identifying hash. These IDs are used to travel through the committed timeline and revisit commits. By default, `git log` will only show commits for the currently selected branch. It is entirely possible that the commit you're looking for is on another branch. You can view all commits across all branches by executing `git log --branches=*`. The command `git branch` is used to view and visit other branches. Invoking the command, `git branch -a` will return a list of all known branch names. One of these branch names can then be logged using `git log`. 13 | 14 | When you have found a commit reference to the point in history you want to visit, you can utilize the git checkout command to visit that commit. Git checkout is an easy way to “load” any of these saved snapshots onto your development machine. During the normal course of development, the `HEAD` usually points to master or some other local branch, but when you check out a previous commit, `HEAD` no longer points to a branch—it points directly to a commit. This is called a **detached HEAD** state, and it can be visualized as the following: 15 | 16 | detached-head 17 | 18 | Checking out an old file does not move the `HEAD` pointer. It remains on the same branch and same commit, avoiding a 'detached head' state. You can then commit the old version of the file in a new snapshot as you would any other changes. So, in effect, this usage of git checkout on a file, serves as a way to revert back to an old version of an individual file. 19 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 06. Undoing Changes/03. Undoing a Committed Snapshot.md: -------------------------------------------------------------------------------- 1 | 2 | # Undoing a committed snapshot 3 | There are technically several different strategies to 'undo' a commit. The following examples will assume we have a commit history that looks like: 4 | 5 | ``` 6 | git log --oneline 7 | 872fa7e Try something crazy 8 | a1e8fb5 Make some important changes to hello.txt 9 | 435b61d Create hello.txt 10 | 9773e52 Initial import 11 | ``` 12 | We will focus on undoing the `872fa7e` Try something crazy commit. Maybe things got a little too crazy. 13 | 14 | ## How to undo a commit with `git checkout` 15 | Using the git checkout command we can checkout the previous commit, `a1e8fb5`, putting the repository in a state before the crazy commit happened. Checking out a specific commit will put the repo in a "detached HEAD" state. This means you are no longer working on any branch. In a detached state, any new commits you make will be orphaned when you change branches back to an established branch. Orphaned commits are up for deletion by Git's garbage collector. The garbage collector runs on a configured interval and permanently destroys orphaned commits. To prevent orphaned commits from being garbage collected, we need to ensure we are on a branch. 16 | 17 | From the detached `HEAD` state, we can execute `git checkout -b new_branch_without_crazy_commit`. This will create a new branch named `new_branch_without_crazy_commit` and switch to that state. The repo is now on a new history timeline in which the `872fa7e` commit no longer exists. At this point, we can continue work on this new branch in which the `872fa7e` commit no longer exists and consider it 'undone'. Unfortunately, if you need the previous branch, maybe it was your master branch, this undo strategy is not appropriate. Let's look at some other 'undo' strategies. 18 | 19 | ## How to undo a public commit with `git revert` 20 | Let's assume we are back to our original commit history example. The history that includes the `872fa7e` commit. This time let's try a revert 'undo'. If we execute `git revert HEAD`, Git will create a new commit with the inverse of the last commit. This adds a new commit to the current branch history and now makes it look like: 21 | 22 | At this point, we have again technically 'undone' the `872fa7e` commit. Although `872fa7e` still exists in the history, the new `e2f9a78` commit is an inverse of the changes in `872fa7e`. Unlike our previous checkout strategy, we can continue using the same branch. This solution is a satisfactory undo. This is the ideal 'undo' method for working with public shared repositories. If you have requirements of keeping a curated and minimal Git history this strategy may not be satisfactory. 23 | 24 | ## Undoing the last commit with `git commit --amend` 25 | In the previous section, we discussed different strategies for undoing commits. These strategies are all applicable to the most recent commit as well. In some cases though, you might not need to remove or reset the last commit. Maybe it was just made prematurely. In this case you can amend the most recent commit. Once you have made more changes in the working directory and staged them for commit by using `git add`, you can execute `git commit --amend`. This will have Git open the configured system editor and let you modify the last commit message. The new changes will be added to the amended commit. 26 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 06. Undoing Changes/04. Undoing Uncommitted Changes.md: -------------------------------------------------------------------------------- 1 | # Undoing Uncommitted Changes 2 | Before changes are committed to the repository history, they live in the staging index and the working directory. You may need to undo changes within these two areas. The staging index and working directory are internal Git state management mechanisms. 3 | 4 | ## The Working Directory 5 | 6 | The working directory is generally in sync with the local file system. To undo changes in the working directory you can edit files like you normally would using your favorite editor. Git has a couple utilities that help manage the working directory. There is the git clean command which is a convenience utility for undoing changes to the working directory. Additionally, git reset can be invoked with the --mixed or --hard options and will apply a reset to the working directory. 7 | 8 | -------------------------------------------------------------------------------- /[OLD VERSION]/[OLD] 06. Undoing Changes/05. reset, checkout, revert.md: -------------------------------------------------------------------------------- 1 | # Resetting, Checking Out & Reverting 2 | Because they’re so similar, it’s very easy to mix up which command should be used in any given development scenario. In this section, we’ll compare the most common configurations of `git reset`, `git checkout`, and `git revert`. 3 | 4 | 3-stages 5 | 6 | A checkout is an operation that moves the `HEAD` ref pointer to a specified commit. 7 | 8 | A revert is an operation that takes a specified commit and creates a new commit which inverses the specified commit. git revert can only be run at a commit level scope and has no file level functionality. 9 | 10 | A reset is an operation that takes a specified commit and resets the "three trees" to match the state of the repository at that specified commit. A reset can be invoked in three different modes which correspond to the three trees. These trees are the Commit History (HEAD), the Staging Index, and the Working Directory. 11 | 12 | Checkout and reset are generally used for making local or private 'undos'. They modify the history of a repository that can cause conflicts when pushing to remote shared repositories. Revert is considered a safe operation for 'public undos' as it creates new history which can be shared remotely and doesn't overwrite history remote team members may be dependent on. 13 | 14 | The table below sums up the most common use cases for all of these commands. Be sure to keep this reference handy, as you’ll undoubtedly need to use at least some of them during your Git career. 15 | 16 | |Command|Scope|Common use cases| 17 | |:--|:--|:--| 18 | |git reset|Commit-level|Discard commits in a private branch or throw away uncommited changes| 19 | |git reset|File-level|Unstage a file| 20 | |git checkout|Commit-level|Switch between branches or inspect old snapshots| 21 | |git checkout|File-level|Discard changes in the working directory| 22 | |git revert|Commit-level|Undo commits in a public branch| 23 | |git revert|File-level|(N/A)| 24 | 25 | ## Commit Level Operations 26 | The parameters that you pass to git reset and git checkout determine their scope. When you don’t include a file path as a parameter, they operate on whole commits. That’s what we’ll be exploring in this section. Note that git revert has no file-level counterpart. 27 | 28 | ### Reset A Specific Commit 29 | On the commit-level, resetting is a way to move the tip of a branch to a different commit. This can be used to remove commits from the current branch. For example, the following command moves the `hotfix` branch backwards by two commits. 30 | 31 | ``` 32 | git checkout hotfix 33 | git reset HEAD~2 34 | ``` 35 | 36 | The two commits that were on the end of hotfix are now dangling, or orphaned commits. This means they will be deleted the next time Git performs a garbage collection. In other words, you’re saying that you want to throw away these commits. This can be visualized as the following: 37 | 38 | before-reset 39 | 40 | after-reset 41 | 42 | This usage of git reset is a simple way to undo changes that haven’t been shared with anyone else. It’s your go-to command when you’ve started working on a feature and find yourself thinking, “Oh crap, what am I doing? I should just start over.” 43 | 44 | In addition to moving the current branch, you can also get `git reset` to alter the staged snapshot and/or the working directory by passing it one of the following flags: 45 | 46 | - `--soft` – The staged snapshot and working directory are not altered in any way. 47 | - `--mixed` – The staged snapshot is updated to match the specified commit, but the working directory is not affected. This is the default option. 48 | - `--hard` – The staged snapshot and the working directory are both updated to match the specified commit. 49 | 50 | ### Checkout old commits 51 | The `git checkout` command is used to update the state of the repository to a specific point in the projects history. When passed with a branch name, it lets you switch between branches. 52 | 53 | ``` 54 | git checkout hotfix 55 | ``` 56 | 57 | Internally, all the above command does is move `HEAD` to a different branch and update the working directory to match. Since this has the potential to overwrite local changes, Git forces you to commit or stash any changes in the working directory that will be lost during the checkout operation. Unlike `git reset`, `git checkout` doesn’t move any branches around. 58 | 59 | before-checkout-branch 60 | 61 | after-checkout-branch 62 | 63 | You can also check out arbitrary commits by passing the commit reference instead of a branch. This does the exact same thing as checking out a branch: it moves the `HEAD` reference to the specified commit. For example, the following command will check out the grandparent of the current commit: 64 | 65 | ``` 66 | git checkout HEAD~2 67 | ``` 68 | 69 | checkout-commit 70 | 71 | This is useful for quickly inspecting an old version of your project. However, since there is no branch reference to the current `HEAD`, this puts you in a detached `HEAD` state. This can be dangerous if you start adding new commits because there will be no way to get back to them after you switch to another branch. For this reason, you should always create a new branch before adding commits to a detached `HEAD`. 72 | 73 | ### Undo Public Commits with Revert 74 | Reverting undoes a commit by creating a new commit. This is a safe way to undo changes, as it has no chance of re-writing the commit history. For example, the following command will figure out the changes contained in the 2nd to last commit, create a new commit undoing those changes, and tack the new commit onto the existing project. 75 | 76 | ``` 77 | git checkout hotfix 78 | git revert HEAD~2 79 | ``` 80 | Contrast this with `git reset`, which does alter the existing commit history. For this reason, `git revert` should be used to undo changes on a public branch, and `git reset` should be reserved for undoing changes on a private branch. 81 | 82 | You can also think of `git revert` as a tool for undoing committed changes, while `git reset HEAD` is for undoing uncommitted changes. 83 | 84 | Like `git checkout`, `git revert` has the potential to overwrite files in the working directory, so it will ask you to commit or stash changes that would be lost during the revert operation. 85 | 86 | ## File-level Operations 87 | -------------------------------------------------------------------------------- /[OLD VERSION]/images/3-stages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/3-stages.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/after-checkout-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/after-checkout-branch.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/after-reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/after-reset.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/before-checkout-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/before-checkout-branch.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/before-reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/before-reset.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/branch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /[OLD VERSION]/images/checkout-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/checkout-branch.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/checkout-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/checkout-commit.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/create-branch-pointer.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /[OLD VERSION]/images/create-branch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /[OLD VERSION]/images/detached-head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/detached-head.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/diff-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/diff-new.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/diff-no-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/diff-no-output.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-add.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-commit.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-directory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-directory.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-github.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-init.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-log.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-push.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-push.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-stages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-stages.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/git-stash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/git-stash.png -------------------------------------------------------------------------------- /[OLD VERSION]/images/merge.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/merge.svg -------------------------------------------------------------------------------- /[OLD VERSION]/images/merge_2.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/[OLD VERSION]/images/merge_2.svg -------------------------------------------------------------------------------- /files/text.txt: -------------------------------------------------------------------------------- 1 | asdfasdf -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pytopia/Git/a178c63cf55cb8dc48528a6281d90505e959ce8e/images/logo.png --------------------------------------------------------------------------------