Skip to content

Latest commit

 

History

History
394 lines (250 loc) · 11.2 KB

File metadata and controls

394 lines (250 loc) · 11.2 KB
id git
aliases
tags

Git

95% of my git workflow

What is going on?

git status

git diff

Add all files that are already tracked by the repo that have changes, commit and push to GitHub:

git add -u

git commit -m 'message'

git push origin master

Using git add -u only works when files have already been committed to the repo.

We can instead add files by name:

$ touch README.md
$ git add README.md

Or add all files in the current directory:

$ git add .

Or add all files:

$ git add *

Or only add patch:

`git add -u -p`

Structure of a Git Repository

Working copy

  • the files on your machine

The index / staging area / cache

  • after add, before commit

The checked out branch

  • branch that you tried the match the contents with

Cloning an existing repo

To clone a repo, simply use the website for the repo on github - don't download and unzip!

For example, to clone this repo:

git clone https://github.com/ADGEfficiency/programming-resources

Initializing a repo

To start from the start, lets:

  • make an empty directory
  • make a file
  • initialize the repo
  • add all files
  • commit the changes
mkdir practice-repo

cd practice-repo

git init

touch README.md

git add *

git commit -m 'initial commit'

git log

Note that we don't push this anywhere - the git repo can happily live and track changes to our code locally.

Working with GitHub

Git is a version tracking system that can happily run locally. GitHub will host your git repo and adds additional functionality.

Lets add our practice repo to GitHub (this is done on the GitHub website) - https://github.com/new

We can now push our repo up to Github.

git push -u origin master

Working on someone else's repo

A common workflow is where you want to work on someone elses repo and send your changes back to them. One way to do this is to:

  • fork their repo to your GitHub
  • commit your changes to your forked repo
  • open a pull request on GitHub (you can't use the command line for this!)

User beware

Git works because it remembers everything - if you commit 10 GB of images it will always be there.

Commands like checkout, reset can overwrite your work - this will happen to you when you are learning.

checkout will reset in your working copy to be equivalent with what’s in your index

git checkout -- <filename>

The best practice is small, regular commits - commit early and often.

gitignore

There are lots of types of files we don't want in our repos - we can tell git to ignore these using a .gitignore

We can also have global gitignores:

#  set a global gitignore
git config --global core.excludesfile '~/.gitignore'

#  show global gitignore
git config --get core.excludesfile

Dev branches

Branching is not required on all projects. Sometimes it can be nice to have a stable master branch and to experiment in another branch.

git checkout -b dev

touch dev.py

git add dev.py

git commit -m 'dev work'

Now if I want these changes in my master branch:

git checkout master

git merge dev

Introductory

How to Learn Git

A beginner's guide to Git version control

Git Techniques at Risk Ledger

Learn the workings of Git, not just the commands

Confusing git terminology

Git For the Modern Data Scientist: 9 Git Concepts You Can’t Ignore

  • repository,
  • tracked & untracked,
  • commit,
  • staging area,
  • hashes & tags,
  • branch,
  • HEAD,
  • merge,
  • stash,
  • GitHub.

Resources

Git Reference Documentation:

Beej's Guide to Git

Learn Git Branching - the most visual and interactive way to learn Git on the web.

The Essential Git Handbook - blog post.

Things I wish Git had: Commit groups

  • merge commits vs. squash & merge vs. rebase & merge

THIS IS HOW I GIT Git workflow from the developer of curl.

Oh My Git! - downloadable game.

Learn Git Branching JS - interactive tutorial website to practice working with Git in your browser.

Oh Shit, Git!?! - how to get out of sticky situations in Git.

git reflog shows a log of changes to the local repository's HEAD and branch heads

$ git reflog
e9494c5 (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: commit: feat: keeping on up
602a6e4 HEAD@{1}: commit: feat: ups
aa972dc HEAD@{2}: commit: feat: ups
fea6e49 HEAD@{3}: commit: feat: ups
8b12a3c HEAD@{4}: commit: feat: ups ups ups :tada:
d4156df HEAD@{5}: clone: from github.com:ADGEfficiency/programming-resources

$ git reset HEAD@{index}

Amend previous commit:

$ git commit --amend --no-edit
$ git commit --amend --no-edit

How Core Git Developers Configure Git

# clearly makes git better

[column]
        ui = auto
[branch]
        sort = -committerdate
[tag]
        sort = version:refname
[init]
        defaultBranch = main
[diff]
        algorithm = histogram
        colorMoved = plain
        mnemonicPrefix = true
        renames = true
[push]
        default = simple
        autoSetupRemote = true
        followTags = true
[fetch]
        prune = true
        pruneTags = true
        all = true

# why the hell not?

[help]
        autocorrect = prompt
[commit]
        verbose = true
[rerere]
        enabled = true
        autoupdate = true
[core]
        excludesfile = ~/.gitignore
[rebase]
        autoSquash = true
        autoStash = true
        updateRefs = true

Branching Strategies

Gitflow Workflow

Legacy workflow - fallen in popularity in favour of trunk based.

Trunk Based Development

Trunk = main = master. Developers never work on release branches.

Git Techniques at Risk Ledger

Master, dev, feature. Squash onto dev.

See also Git techniques | Hacker News for disagreement with the Risk Ledger approach.

Ship / Show / Ask

Pull requests are categorized as either:

  • Ship (merge into mainline without review),
  • Show (open a pull request for review, but merge into mainline immediately),
  • Ask (open a pull request for discussion before merging).

Code review, or “Approval”, should not be a requirement for a Pull Request to be merged.

Our branches should not live long, and we should rebase them on the mainline often.

PRs should not replace other ways of having a conversation.

Advanced

The Perfect Commit

Popular git config options

Modern Git Commands and Features You Should Be Using

Cuddly, Octo-Palm Tree: The elements of git

Why git repos would struggle with large binary files: as every change is stored as a separate file, binary files (which typically don't compress well even for apparently small changes) will quickly take up quite a bit of space in either object or pack form.

Git Things - Hacker News Discussion

I wish people would stop insisting that Git branches are nothing but refs - Hacker News Discussion

Useful git commands - Marc Garcia - more advanced Git shell commands.

More productive Git

Git from the inside out - Mary Rose Cook - a deeper dive into how Git works under the hood.

Git From the Bits Up - Tim Berglund

Git from the Bottom Up

Deep Dive into Git - Edward Thomson

Learn the workings of Git, not just the commands

Things I think everyone should know about Git - Things I wish everyone knew about Git (Part II)

Git from the Bottom Up

Criticism

What’s wrong with Git? A conceptual design analysis

Why SQLite Does Not Use Git

Confusing git terminology - Hacker News Discussion

The single thing that made everything "click" together is that most things are just pointers to commits: branch names, HEAD, tags, all of them are pointers.

The other thing caught me out multiple times is that most commands seem inconsistent because git assumes default arguments:

git checkout file.txt is the same as git checkout HEAD -- file.txt

When you're on my-branch, git rebase main is the same as git rebase main my-branch

Rebasing

git rebase: what can go wrong?

2 different kinds of rebase - only one of them requires you to deal with merge conflicts.

  1. rebasing on an ancestor, like git rebase -i HEAD^^^^^^^ to squash many small commits into one. As long as you’re just squashing commits, you’ll never have to resolve a merge conflict while doing this.
  2. rebasing onto a branch that has diverged, like git rebase main. This can cause merge conflicts.

Undoing rebases is hard


A rebase based workflow requires two rebases

  • rebase master onto feature (easier - integrating changes from stable master into feature)
  • rebase feature back to master (or this could be a merge commit) (harder - more potential for conflicts if feature branch has diverged significantly)
  • push master

Revert

Undo commit with a new commit.