class: center, middle # Git and GitHub Enabling distributed cooperation on software projects. --- # Agenda 1. [Introductions](#introductions) 2. [Three-Tier Model](#tiers) 3. [Git Terminology](#terminology) 4. [Creating a Local Repository](#local-repository) 5. [Tracking Changes with the Local Repository](#tracking) 6. [Committing Changes to the Local Repository](#committing) 7. [Sharing Changes with Other Developers](#sharing) 8. [Conflicts](#conflicts) 9. [Configuration](#configuration) 10. [Conclusions](#conclusions) --- name: introductions # Introductions -- ## Git The world's most popular open source [version control system](../version-control-systems). -- - **Distributed** - all developers maintain and share the code in their own local repositories, with no single central authority. -- - **Repository versioning** - a new version number is issued for the repository as a whole, even when only one file has changed. -- - Created by **Linus Torvalds** to help Linux kernel developers collaborate --- template: introductions ## GitHub A web app used for hosting remote Git repositories. -- - Free hosting of public open-source projects -- - Free hosting of private projects for students (or so I hear) -- - Acquired by Microsoft for \$7.5 billion in 2018 --- name: tiers # Three-Tier Model --- template: tiers Git version control depends upon three tiers, or three places where files are stored. - Working copy - Staging index - Repository ![Git tiers](../images/git_tiers.png) --- template: tiers ## Working copy The copy of the files that a developer works on. -- - Not tracked by git. -- - Your 'normal' files you are familiar with. -- ![Working tree](../images/git_working_tree.png) --- template: tiers name: staging-index ## Staging index A holding area for changes that _might_ be included in the project's official history. -- - Allows developers pick and choose which changed files to include in the next commit to the repository -- - [Read more](https://gitolite.com/uses-of-index.html) about some benefits of this -- ![Staging index](../images/git_staging_index.png) --- template: staging-index ```bash # add any changed files within the working directory to the staging index git add . ``` -- ```bash # add only one file to the staging index git add my_staging_index_slide.md ``` --- template: tiers name: repository ## Repository The official history of the project, including the history of all committed files. -- - With each commit, changed files in the staging index are moved to the repository -- - A short message describes the chanes included in each commit -- ![Repository](../images/git_repository.png) --- template: repository ```bash # commit any files in the staging index to the repository git commit -m "Updating slide about git repositories" ``` --- name: terminology # Git Terminology -- A few terms we must familiarize ourselves with. - Clone - Fork - Main - Branch - Remote - Pull - Push - Merge - Fetch --- template: terminology name: clone ## Clone A new repository made by copying files from an existing repository. -- - Typically involves creating a new local repository that is a copy of an existing remote repository. -- - The new repository automatically keeps a link to the `origin` remote repository from which it came. -- ```bash # clone a remote repository onto the local machine git clone https://github.com/your-github-handle/your-repository-name.git ``` --- template: clone ![Clone](../images/git_clone.png) --- template: terminology name: fork ## Fork Not a Git term, but rather a term used by remote repository hosting providers such as GitHub. -- - A fancy word for creating a remote [clone](#clone) of a remote repository. -- - A fork of a GitHub repository creates a clone of that repository in the active user's own GitHub account --- template: fork ![Fork](../images/git_fork.png) --- template: terminology name: main ## Main The Git term for the `trunk` line of code. -- - The default line of code that all commits are placed into unless other branch lines are created. -- - PS: in earlier versions of `git`, the trunk was called `master`. You will still see this name used in many places. -- ![Main branch](../images/git_main.png) --- template: terminology name: branch ## Branch The term for an offshoot of the `trunk` or `main` line of code. -- - creating a branch allows developers to work on new code in isolation with no effect on the main `trunk` line. -- - code in a branch can be `merged` into the trunk branch at any time, if desired -- ![Feature branch](../images/git_branch.png) --- template: branch ```bash # see a list of all branches in the local repository git branch ``` -- ```bash # create a new branch git branch experiment1 ``` -- ```bash # switch to the new branch git checkout experiment1 ``` -- ```bash # switch back to the main branch git checkout main ``` --- template: terminology name: remote ## Remote A term used to mean a remote repository that the local repository is linked to. -- - Typically, this refers to the remote repository from which a local repository was cloned. -- - The nickname `origin` is usually used to refer to the original remote repository from which the local repository was cloned. -- - The nickname `upstream` is also sometimes used to refer to a remote repository from which the `origin` repository was originally forked. --- template: remote ```bash # view a list of all currently known remotes git remote -v ``` -- ```bash # inform git of a remote and give it the nickname 'origin' git remote add origin https://github.com/your-github-handle/your-repository-name.git ``` -- ```bash # inform git of a remote and give it the nickname 'upstream' git remote add upstream https://github.com/some-other-github-handle/some-other-repository-name.git ``` --- template: terminology name: pull ## Pull Download and merge any changes _in the current branch_ from a remote repository to the local repository. -- - It's good practice to `pull` before you `push`. -- ![Pull](../images/git_pull.png) --- template: pull ```bash # download and merge any changes in the main branch from the 'origin' remote repository to the local repository git pull origin main ``` -- ```bash # download and merge any changes in the main branch from the 'upstream' remote repository to the local repository git pull upstream main ``` --- template: terminology name: push ## Push Upload changes from the local repository to a remote repository. -- ![Push](../images/git_push.png) --- template: push ```bash # Upload any changs in the main branch from the local repository to the 'origin' remote repository git push origin main ``` -- ```bash # Upload any changs in the main branch from the local repository to the 'upstream' remote repository git push upstream main ``` --- template: terminology name: fetch ## Fetch Download but do not automatically merge any changes _in the current branch_ from a remote repository to the local repository. -- - This is similar to `git pull`, but `pull` automatically merges any changes into the current branch, while `fetch` does not. -- ```bash # fetch any changes from the remote repository git fetch origin ``` -- ```bash # fetch any changes from the 'upstream' remote repository git fetch upstream ``` --- template: terminology name: merge ## Merge Take the changes from one branch or repository and incorporate them into another branch or repository. -- - If both branches include recent changes to the same lines of code, `git` will inform you of a conflict. -- - Any such merge conflicts must be manually resolved using your preferred editor. -- ![Merge](../images/git_merge.png) --- template: merge - A typical workflow: ```bash git pull origin main # get latest code for the current branch from the remote origin repository git checkout some-branch-name # switch to a branch where you will make changes in isolation... either first create this branch with `git branch some-branch-name` or do `git checkout -b some-branch-name` to create it and check it out at once # make some chages to the code in this branch, if desired using your preferred editor # stage and commit your changes, i.e. `git add .`, `git commit -m "some message."` git checkout main # switch back to the main branch to prepare to merge git pull origin main # download any recent changes from the origin server git merge some-branch-name # incorporaate your changes in the branch into the code in the main branch git branch -d some-branch-name # delete the branch now that we're done with it git push origin main # upload your changes to the remote origin repository ``` --- name: local-repository # Creating a Local Repository -- A local repository can be created in one of two ways. -- ## From scratch ```bash mkdir project0 cd project0 git init ``` -- If you later decide to link a local repository to a remote repository: ```bash git remote add origin firstname.lastname@example.org:YOUR-USERNAME/YOUR-REPOSITORY.git ``` -- ## As a clone of another repository ```bash git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY.git ``` --- name: tracking # Tracking Changes with the Local Repository -- Changes in the Working Copy (adding, modifying, or deleting files) are not tracked. Files must be added to the staging index in order to be tracked. -- ## Add files to the staging index Make any changes you desire. Then add all the modified files in working copy to the staging index: ```bash git add . ``` --- name: committing # Committing Changes to the Local Repository -- The staging index does not maintain the history of all changes. Changes must be moved to the repository in order to be fully archived. -- ```bash git commit -m 'resolving bug #23' ``` --- name: sharing # Sharing Changes with Other Developers -- Any changes to the local repository must usually be shared with other developers. For this reason, they should frequently be uploaded to a shared remote repository. --- template: sharing ## Pushing changes to the remote repository Push the code in the current branch from the local repository to the branch named 'main' on the remote repository called 'origin': ```bash git pull git push origin main ``` Optionally, you can set `origin` as the default place to push by running this command once: ```bash git push --set-upstream origin main ``` From then on, you can use just `git push` to push changes to `origin`. --- name: conflicts # Merge Conflicts -- Conflicts may occur in a number of scenarios: - When `pulling` code from a remote repository to a local repository. - When `pushing` code from a local repository to a remote repository. - When merging code from one branch into another. - When merging code from one repository into another. -- Git will merge code automatically, if possible, and ask the developer to do it themselves, if not. --- name: configuration # Configuration -- Several important configurations that must be completed prior to versioning: - `git` username and email address - GitHub name - `.gitignore` --- template: configuration ## Git username and email address Username and email in Git must match exactly any username and email set up on GitHub: ```bash git config --global user.name "Mona Lisa" git config --global user.email "email@example.com" ``` --- template: configuration ## GitHub name Leave blank the `Name` field in your GitHub account settings to be sure that your username is used instead for all commits. ![GitHub username settings](../assets/git-github/github-username-settings.png) --- template: configuration ## .gitignore A file in the project directory named `.gitignore` instructs Git to ignore certain files or directories. -- This _absolutely must_ include instructions to ignore any platform code and 3rd party modules. -- View an [example](https://gist.github.com/bloombar/1bbca4aafb267920ac220864d99d6c8f) --- name: conclusions # Conclusions -- You now know the basics of using Git and its relationship to GitHub. -- - Thank you. Bye.