Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Git

git.livemd

Git

Mix.install([
  {:kino, github: "livebook-dev/kino", override: true},
  {:kino_lab, "~> 0.1.0-dev", github: "jonatanklosko/kino_lab"},
  {:vega_lite, "~> 0.1.4"},
  {:kino_vega_lite, "~> 0.1.1"},
  {:benchee, "~> 0.1"},
  {:ecto, "~> 3.7"},
  {:math, "~> 0.7.0"},
  {:faker, "~> 0.17.0"},
  {:utils, path: "#{__DIR__}/../utils"}
])

Navigation

Return Home Report An Issue

Setup

Ensure you type the ea keyboard shortcut to evaluate all Elixir cells before starting. Alternatively, you can evaluate the Elixir cells as you read.

Source Control

Source control allows us to maintain several different versions of a codebase. Source control makes it easier to share and collaborate on code.

Projects share a main branch. Then developers working on the project can submit changes to the main branch. These changes are called a commit.

Source control also provides a history of the changes made to a project along with associated descriptions of the change.

There are many source control tools. The industry standard is Git and GitHub.

Git

Git is a locally installed program on your computer. If you installed GitHub Desktop you should already have Git installed on your computer.

Enter the following into the command line to confirm you have Git installed. You should see a similar output.

$ git --version
git version 2.25.1

You can use Github Desktop, the command line, or a source control extension in your code editor for interacting with Git.

GitHub

GitHub hosts your git projects and provides tools for easier collaboration with Git.

For example, this entire project is on GitHub. It is a public repository meaning that anyone can view the code and request to make a pull request. However, only contributors with valid permission can approve those changes.

public repositories are generally called open-source projects if they accept changes from other developers.

Alternatively private repositories can only be seen and modified by authorized users.

Raising An Issue

Anyone can raise an issue on a public GitHub project. For example, you can raise an issue by going to the issues tab on the GitHub Page of this curriculum and clicking New Issue.

Please raise an issue if you encounter a problem with the curriculum.

Initializing A Local Repository

Git uses a .git folder that stores the necessary folders and files to manage the project’s source control. We call this git-managed folder a repository.

Using the command line, you can initialize Git in your current working directory by running:

git init

Your Turn

Use the command line to create a new Git managed project called git_example.

You can use git status from the command line from the git_example folder to verify that Git manages the folder. Like so:

$ git init
Initialized empty Git repository in ~/github_example/.git/
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Saving Changes

Git allows you to save your changes in a commit. Changes go from untracked to staged to committed.

flowchart LR
  Untracked --git add--> Staged --git commit--> Committed

You’ll use some common commands for saving changes in Git.

  • git status: Display Git information and see the untracked and staged changes.
  • git add: Stage current changes.
  • git commit: Save staged changes into a commit.

We can use git add from the command line to stage changes. We can stage a single file with git add or all of the files and folders in the current working directory with git add ..

Then we can use git commit from the command line to commit all staged changes.

Your Turn

In the github_example create an empty file named finished.txt.

Use git status to see that the file is untracked.

$ git status
On branch master

No commits yet

Untracked files:
  (use "git add ..." to include in what will be committed)
        finished.txt

nothing added to commit but untracked files present (use "git add" to track)

Now, stage finished.txt to prepare it to be committed.

$ git add finished.txt

Use git status again and see the file is staged.

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached ..." to unstage)
        new file:   finished.txt

Now we’ll use git commit to commit the staged changes. We use the -m flag and provide a message in quotations. "example commit message" can be any description you want.

$ git commit -m "example commit message"

Pushing Changes

You’ve so far used Git locally. Now to share code and collaborate with other developers, we push code to a remote Git repository on GitHub.

flowchart LR
  Local --git push--> Remote

We use git push to push changes to the remote repository.

Your Turn

Run git push now, and you’ll notice the following error:

$ git push
fatal: No configured push destination.
Either specify the URL from the command line or configure a remote repository using

    git remote add  

and then push using the remote name

    git push 

We need to tell our local git repository where the remote git repository is. First, let’s create one on GitHub.

Provide a Repository name and an optional description. You can choose for this project to be public or private.

Do not initialize the project with any of the optional files. Click New repository to create the remote repository.

Now the remote repository is created, we need to tell our local Git repository how to find it. Follow the instructions for push an existing repository from the command line.

  • git remote add origin Tell your local Git project where to find the remote Git repository.
  • git branch -M main Rename the default branch to main.
  • git push -u origin main Push local commits to the remote repository. This command sets the default remote repository, so only git push is necessary for future commits.

You are done! You can now add, commit, and push any further changes. This will be your typical developer process with Git.

$ git add .
$ git commit -m "add example changes"
$ git push

Cloning Repositories

You can clone remote repositories to create a local Git project on your computer.

flowchart LR
Remote --git clone--> Local

There are many methods for cloning a remote repository onto your computer.

GitHub Desktop

GitHub Desktop is the most straightforward way to clone a repository.

On a GitHub repository, click the Code button to see your options for cloning.

Click the Open with Github Desktop button, enter a valid Local path and click Clone.

Now you should be able to follow these steps with any GitHub repository to clone the project to your computer.

Cloning With the Command Line

Many developers prefer using the command line rather than the GitHub desktop. You can use HTTPS, SSH, or the Github CLI.

You can find instructions for each method on GitHub:

HTTPS

HTTPS (Hypertext Transfer Protocol Secure) is a method of transferring data. In this case, we use it to copy files from the GitHub remote repository onto our local computer.

More practically, it’s the easiest method for the command line however the downside is it’s less secure and requires you to enter your GitHub credentials every time you use a git command.

We use git clone with the URL provided by GitHub to clone the repo with HTTPS.

$ git clone https://github.com/BrooklinJazz/github_example.git

However, you’ll need to enter credentials every time you use git push or any other git command that interacts with a remote repository.

$ git push
Username for 'https://github.com':
Password for 'https://a@github.com':

It’s pretty tedious for projects that you use regularly.

SSH

SSH is more secure than HTTPS and doesn’t require a username or password for authentication. Instead it uses an SSH Key stored locally on your computer.

However, it’s more complex to setup. If you wish to use SSH, follow the instructions to connect to github with ssh.

You’ll want to follow the instructions for:

Then you can use the git clone with the SSH URL provided.

$ git clone git@github.com:BrooklinJazz/github_example.git

GitHub CLI

The GitHub CLI provides some conveniences for working with Git and GitHub. It allows you to use the command line to accomplish tasks that would normally require GitHub.

It’s beyond the scope of this course, but you can learn more here.

Your Turn

Clone your github_example project onto your computer under a new name github_example2.

To clone a project under a new name, either select a new location in the GitHub desktop UI or provide a new name to git clone.

$ git clone  github_example2

Trunk Based Development

Source control allows us to store different versions of the project. Typically there is a main branch for the latest version of the project.

The most straightforward source control strategy only uses a main branch. Developers can push and pull from the main branch to get the latest changes.

sequenceDiagram
    actor D1 as Developer 1
    participant R as Main
    actor D2 as Developer 2
    D1->> R: pushes changes
    R->> D2: pull changes
    D2->> R: push changes
    R->> D1: pulls changes

It’s convenient and fast. However, it lacks any review system for code changes. Therefore it’s potentially excellent for small projects with highly trusted team members, but less effective for large projects requiring code review.

Pulling Changes

The GitHub remote repository can get out of sync with a user’s local repository. We have to manually pull changes from the remote repository onto our local repository.

GitHub Desktop allows you to pull changes through the UI.

Alternatively, you can use the command line with git pull from the project folder.

$ git pull

Your Turn

We’re going to simulate pulling changes on your github_example project.

Create a new file called pull.txt in your github_example2 project. Not your github_example project.

Stage, commit and push the pull.txt file from github_example2.

$ git add pull.txt
$ git commit -m "add pull.txt"
$ git push

Now pull the change from your github_example project.

$ git pull

You should see pull.txt is now part of the github_example project.

Branching Strategies

You can use branching strategies for your Git workflow as an alternative to trunk-based development.

You create a branch for a feature from the main branch and then make a pull request which is reviewed and merged back into the main branch.

These strategies vary in complexity. For example, you could simply make a pull request for a feature and then merge those changes directly into the main branch.

sequenceDiagram
    actor D1 as Developer 1
    participant B as Feature Branch
    participant M as Main
    actor D2 as Developer 2
    D1 ->> D1: creates local branch
    D1 ->> D1: commits changes on local branch
    D1 ->> B: pushes new branch
    B ->> M: create pull request to "main"
    M ->> M: accept pull request
    M ->> D2: pull changes
    M ->> D1: pull changes

Alternatively, many Git branching strategies have a pipeline for changes to be reviewed and tested.

There is no universal strategy. Each project may have a different pipeline. However, some common steps include:

  • Feature Branch: A branch containing one specific change.
  • Development: Developer testing and integration branch.
  • Quality Assurance (QA): Quality Assurance testing branch.
  • Staging: Approved changes ready for production but not yet deployed.
  • Main: The latest available version of the project.
flowchart LR
  F[Feature Branch]
  D[Development]
  Q[QA]
  S[Staging]
  M[Main]
  F --> D --> Q --> S --> M

Your Turn

We will create a new branch on your github_example project.

On the command line run:

$ git checkout -b 

Where ` is the name of the branch with no spaces. Each branch must have a name with no spaces. For example, you could create a branch calledmy-branch. ```sh $ git checkout -b my-branch ```git checkoutallows you to set the current branch.git checkout -bcreates a new branch and sets it as the current branch. Any commits we make are saved on the current branch. Next, create, stage and commit a new filebranch.txt. ```sh $ git add branch.txt $ git commit -m "add branch.txt" ``` You'll need to create a remotemy-branchand push the changes. You can visit the link provided to create a PR. ```sh $ git push -u origin my-branch ... remote: Create a pull request for 'my-branch' on GitHub by visiting: remote: https://github.com/BrooklinJazz/github_example/pull/new/my-branch ... ``` Now you can optionally provide a description of the PR and click the **Create pull request** button. ![](images/create_pr_github.png) You can review a pull request's changes under the **Files changed** tab. Click the **Merge pull request** button to merge the changed files into main. ![](images/merge_pull_request.png) Now themainbranch of the remote repository has the changes from the pull request, however your localmainbranch needs to be updated. Usegit pullwhile on themainbranch of your localgithub_exampleproject. You may need to usegit checkout mainif you are not already on themainbranch. ```sh $ git checkout main $ git pull ``` ## Merge Conflicts Source control allows us to develop our own version of the project isolated to our local version. However, if two developers edit the same file, it's possible to have conflicts. These conflicts need to be manually resolved. It's often easiest to [resolve conflicts using GitHub Desktop](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-on-github) or with Visual Studio Code. ![](images/resolve_conflicts_vsc.png) ### Your Turn You're going to create a merge conflict. On yourgithub_exampleandgithub_example2projects, edit thefinished.txtfile. Both should have conflicting content. i.e. ```sh github_example version of finished.txt ``` and forgithub_example2: ```sh conflicting github_example2 version of finished.txt ``` Stage and commit both versions of the project. By having two versions, you are simulating two developers working on the same project. Pushgithub_exampleand attempt to pull fromgithub_example2`. You should see that there are merge conflicts. Use Visual Studio Code to resolve the conflicts by accepting both changes. Stage, commit, and push your resolved changes.