Git

What is Git and how to use it.

What is Git?

  • Git is a popular open-source version control tool commonly used for code but can be used with all types of files

  • More information about Git can be found on its website

Install

  • Git is typically installed by default on Linux distributions and MacOS however it will need to be installed on Windows

    • Windows: winget install git.git

    • Linux: sudo apt install git

    • MacOS: brew install git

Pushing Local Code to a Remote Repository

  • With an empty remote repository, we can add local code to it

# set the origin to the remote repo
git remote add origin <repoUrl>

# push local code to the remote main branch
git push -u origin main

Cloning Repositories Locally

  • We can download a repository locally if we have permission

# via HTTPS
git clone <URL> 

# via SSH
git clone <sshLink>

Merging Code

  • When you want to merge your changes to a repo

  • GitLab - Merge Request (MR)

  • GitHub - Pull Request (PR)

Merge Conflicts

  • This can occur during a merge when your file is different than an existing file and git is unable to determine which changes should be committed.

  • The error may look like this after running git push origin <branchName>

! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'http://gitlab.com/tyler/myproject.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
  • To fix, run git pull origin <branchName> (the conflicting branch) and identify the problem file(s) in the output.

[snip]
CONFLICT (add/add): Merge conflict in file.txt
Auto-merging file.txt
Automatic merge failed; fix conflicts and then commit the result.
  • Open the file (GUI, IDE, etc.) and select the data to keep removing all the git added stuff and leaving only the data you want.

# file.txt

<<<<<<< HEAD # your changes
My changes are here!
=======
The data in the branch!
>>>>>>> 2lk3lm23lrl2k3ml2m3l2n3ln2l3lsdkglsadg # the commit hash on the remote branch
# file.txt

My changes are here!

Fork

  • Someone with READ access can download your repo/code, make changes, and then open a Merge Request for you to approve

Rebasing

  • When the branch you're working on is behind commits from others

Merging

  • Running this command from your branch brings changes from others into your branch and keeps the git commit history intact

git merge main

Rebasing

  • Running this command moves your branch on top of the updated branch, changing the git commit hashes from others.

  • Not a big deal but your coworkers may not like this due to the commit history changing

git rebase main

Squashing Commits

  • When you have multiple commits and want to squash them into one

  • The final commit will be Addng new feature

# view commit history
git log

# squash the last 3 commits into one
git rebase -i HEAD~3

# replace `pick` with `squash`
pick 3h3ih Adding new feature
squash 4j69j Fixing typo
squash 6k49g Adding change

Cherry Picking

  • When you want to incorporate a particular commit from another branch into your branch

git cherry-pick <commitHash>

Reverting Commits

  • You've committed some changes and now want to undo them

Keeping Commit History

  • Removing the commit shows the file(s) as deleted in the commit history

git revert <commitHash>

Undoing Commit

  • This undoes your commit

  • Use --soft to undo the commit but keep your modified file(s)

  • Use --hard to undo the commit and delete your modified file(s)

# remove last commit ~1
git reset --soft HEAD~1
git status

    On branch featureA
    Changes to be committed:
        added:    file.txt
    

# remove last commit ~1
git reset --hard HEAD~1
git status

    On branch featureA
    Nothing to commit

Stashing

  • Storing your code when you don't want to commit it yet but need to hop to another branch and don't want your modified code to come with you

# stash code
git stash

# list code kept in stash
git stash list

    stash@{0}: WIP on main: added new feature X (1 hour ago)
    stash@{1}: Bugfix for issue#123 (2 days ago)
    stash@{2}: Update README.md (yesterday)


# show contents of stash
git stash show stash@{0}

    diff --git a/new_feature.py b/new_feature.py
    new file
    +++ b/new_feature.py
    

# remove stashed item
git stash pop stash@{1}

Reflog

  • Shows the state of the repository and enables you to undo mistakes e.g., you deleted a file

# show changes
git reflog

    34o4on43mf0sd  HEAD@{0}: checkout: moving from main to feature (HEAD@{0})
    has34o4omf0sd  HEAD@{1}: commit: added feature X (2 hours ago)
    64osafdamf0sd  HEAD@{2}: commit: initial commit (yesterday)
    78o4sdsdh330s  ORIG_HEAD@{0}: commit: initial commit (yesterday)
    

# undo a change
git reset --hard <commitHash>

Useful Commands

General

# get help
git --help
man git

# download/clone repo
git clone <repositoryLink>

# view changes made since last commit or initial download 
git status

# queue files for commit
git add <fileName>
git add *

# commit files
git commit -m "description of change"

# push files to branch
git push
git push -u origin <branchName>
git push --set-upstream origin <branchName> 

# view git log
git log
git log -p <commitHash>

# checkout a commit
git checkout <commitHash>

Branches

# view all local branches
git branch

# view all remote branches
git branch -r

# view all local and remote branches
git branch -a

# create new branch and switch to it
git checkout -b <newBranchName>

# switch branch
git branch <branchName>

# rename branch
git branch -m <oldBranchName> <newBranchName>

Modify Terminal to show current git branch

  • Update your shell's configuration file e.g., ~/.zshrc or ~/.bashrc

  • Save and then reload your shell for the changes to take effect source ~/.zshrc

parse_git_branch() {
    git branch 2> /dev/null | sed -n -e 's/^\* \(.*\)/[\1]/p'
}
# color #s found here: https://misc.flogisoft.com/bash/tip_colors_and_formatting
COLOR_DEF='%f'
COLOR_USR='%F{243}'
COLOR_DIR='%F{197}'
COLOR_GIT='%F{39}'
NEWLINE=$'\n'
setopt PROMPT_SUBST
export PROMPT='${COLOR_USR}%n@%M ${COLOR_DIR}%d ${COLOR_GIT}$(parse_git_branch)${COLOR_DEF}${NEWLINE}%% '

Last updated