codeofhk / git-basics

Some examples of how to do some core things in Git

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Table of contents

Basic Git Configuration

It is very helpful to have a .gitconfig file. You can have a global one that sets defaults on all git repositories (~/.gitconfig) and then repository specific .gitconfig files as well.

To start with, make sure that you have a global .gitconfig that sets your username, email, and your editor of choice for writing commit messages.

git config --global user.name "Firstname LastName"
git config --global user.email "yourEmail@email.com"
git config --global core.editor "yourFavoriteTextEditor"

To check the settings of your .gitconfig you can either just list it out

cat ~/.gitconfig

or you can query it for specific commands

git config user.name

Helpful aliases

I would also recommend setting up the following aliases

git config --global alias.pl 'pull --rebase'
git config --global alias.glog 'log --graph --oneline --decorate --all'
git config --global alias.fstatus '!git fetch -p && git status'
git config --global alias.ftag '!git tag -d $(git tag) > /dev/null 2>&1 && git fetch --tags > /dev/null 2>&1 && git tag'
git config --global alias.incoming '!f() { git fetch && git log ..origin/$(git rev-parse --abbrev-ref HEAD); }; f'
git config --global alias.outgoing '!f() { git fetch && git log origin/$(git rev-parse --abbrev-ref HEAD)..; }; f'
git config --global alias.last-files '!f() { git show --name-only $(git rev-parse HEAD); }; f'

For more high-powered Git aliases I'd recommend Tim Pettersen's Git Merge 2017 talk.

This is a walkthrough of how to do some basic things in Git

On GitHub/GitLab make a new repo called my-repo. Use the web GUI to copy the URL to your clipboard and then clone it to your local machine

git clone <the URL you copied>
cd my-repo
GitHub GitLab
copy URL GitHub copy URL GitLab

Create a README and license for your repo

touch README.md
# edit README as desired
touch LICENSE
# edit LICENSE as desired

Add and commit the files

git add README.md
git add LICENSE
git commit -m "add README and LICENSE"
# have the changes be tracked
git push -u origin master

Toy example of a workflow

Create a development branch to do work in

git checkout -b dev
#git push -u origin dev

Make an edit to the README such as

This is a local edit to the README!

commit the change

git add README.md
git commit -m "Edit the README locally"

We're going to purposely make a merge conflict later by going to GitHub/GitLab and making an edit to the README on the master branch on there

This is an upstream edit to the README from the web!
GitHub GitLab
upstream edit GitHub upstream edit GitHub

On your local machine switch to master branch

git checkout master

merge1 the changes made in dev onto master

git merge dev

Before pushing changes make sure that there were no changes already made, so fetch and merge

git fetch
git merge origin/master
  • N.B.: What is happening here is we pulled down the current state of the entire remote repo (origin) with fetch and then merged the changes that exist in the remote branch (origin/master) onto the branch we currently have checked out (master)

which will result in the following merge conflict:

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Edit the README to resolve the conflict:

<<<<<<< HEAD
This is a local edit to the README!
=======
This is an upstream edit to the README from the web!
>>>>>>> origin/master

to

This is a local edit to the README followed by an upstream edit to the README from the web!

Then commit and push

git add README.md
git commit -m "Resolve merge conflict"
git push origin master

Edits, Diffs, and Resets

Suppose we make several commits to the README

echo "This is an edit" >> README.md
git add README.md
git commit -m "Edit 1"
echo "This is another edit" >> README.md
git add README.md
git commit -m "Edit 2"

The README has just been put in a commit, so if we ask the repo what is different from the current state to the repo state

git diff README.md

it returns nothing. The current state of the files are the same as the last commit to the repo. However, if we now do

echo "What has changed" >> README.md
git diff README.md

we see at the bottom the addition

 This is an edit
 This is another edit
+What has changed

If we now ask what has changed between this current state and the second to last commit

git diff HEAD^ -- README.md

we get

 This is an edit
+This is another edit
+What has changed

and the third

git diff HEAD^^ -- README.md

gives

+This is an edit
+This is another edit
+What has changed

If we decide that we don't like the edits that we've made and we want to revert back to how the state the repo was in after the last commit then we can just checkout the HEAD

git checkout HEAD -- README.md

and we can see we are back at the last commit

git diff

If we decide we want to go back to the state before we made our three consecutive commits then we can just do

git checkout HEAD^^ -- README.md

and git diff or cat README.md will reveal have recovered the state of the README before we made the edits.

  • N.B.: We have recovered the state of the README but we have not undone our commits. Simply checking git log shows us this.

    Example of Matthew's daily workflow

Every directory on my local computer that has code in it is a Git repo. A typical snapshot of what that looks like is

git branch
* YYYY-MM-DD
  dev
  master

though if this repo has a remote then going to look at it will only show you master and dev.

Why?

The idea here is that master should always be production ready and dev should be where the new feature that I'm working on it being tested. However, each day I don't want to possibly contaminate dev. So everyday when I start work I (from the dev branch) do

git checkout -b YYYY-MM-DD

and then do all my work for the day in the YYYY-MM-DD branch. Then at the end of the day I simply

git checkout dev
git merge YYYY-MM-DD
git branch -d YYYY-MM-DD

so dev reflects the day's improvements and as YYYY-MM-DD has served its purpose it is removed.

If everything has become a raging dumpster fire (it is 2016 when I'm writing this, so there should really be a raging dumpster fire emoji2 🗑 🔥) I can instead do

git checkout dev
git branch -d YYYY-MM-DD

and walk away with no damages to try again tomorrow. :)


1) Please though, never DR;JM

2) Courtesy of Meghan Kane, 2017

About

Some examples of how to do some core things in Git

License:MIT License