pkb contents > git | just under 2296 words | updated 06/14/2017
Git is a versioning tool tailored to the needs of programmers. Like all versioning tools, Git records a series of changes, letting you restore an earlier version if something goes wrong with the current one. In particular, Git is a versioning tool that works offline; lets you choose your file editing programs; saves manually, not automatically (reflecting the stance that old versions are useful only if they are complete, coherent, functioning); saves multiple documents at a time, not just one; and allows branching.
How could having easy access to the entire history of a file make you a more efficient programmer in the long term?
What do you think are the pros and cons of manually choosing when to create a commit,like you do in Git, vs having versions automatically saved, like Google Docs does?
Why do you think some version control systems, like Git, allow saving multiple files in one commit, while others, like Google Docs, treat each file separately?
What happens when you initialize a repository? Why do you need to do it?
How is the staging area different from the working directory and the repository? What value do you think it offers?
How can you use the staging area to make sure you have one commit per logical change?
There are three general workflows in Git: solo, collaborative (local-remote), and GitHub (local-remote-collaborator). Obviously workflows should be customized to suit the circumstances (number of collaborators, purpose of branches, purpose of master).
Cloning or initializing Git in a directory creates a staging area and repository with one branch, the master . Master should be production-quality code that always runs, so work should be done in branches , which are in most cases intended to be temporary. Branches are important for sharing code and for compartmentalizing your own work.
Git tracks which commit you're 'on' by means of the HEAD pointer. HEAD can be pointed to a commit or to a branch that, in turn, points to its 'tip' (its most recent commit). Each commit points to its parent commit, making most earlier commits reachable . 'Checking out' means moving the HEAD pointer to a new commit; checking out a commit that's not the tip of a branch puts you in detached HEAD state , and any commits you make from here will be unreachable. Git periodically runs a garbage collector process that deletes unreachable commits; until the garbage collector runs, all commits are accessible via their SHA if you happen to know it.
So, the workflow:
For collaborative work via remotes, you retain your tripartite solo working environment but add new steps:
For collaborative work via GitHub, you retain your tripartite solo working environment and, from your command line, work with your GitHub repository like a remote repository (remember to cache your GitHub login ). GitHub has additional functionality, though, like issues, wikis, forking (the ability to clone someone else's GitHub projects to your GitHub account). Every GitHub repository has three special files by default: README.md , a description of the project; CONTRIBUTING.md , instructions for how to contribute to the project; and ISSUE_TEMPLATE.md , a template for raising issues with the project.
A sample workflow:
Describe the differences between forks, clones, and branches. When would you use one instead of another?
What are some situations when branches would be helpful in keeping your history organized? How would branches help?
How do the diagrams help you visualize the branch structure?
When would you want to make changes in a separate branch rather than directly in master? What benefits does each approach have
What is the result of merging two branches together? Why do we represent it in the diagram the way we do?
What are the pros and cons of Git’s automatic merging vs. always doing merges manually?
git --version
git config --global color.ui auto # make diff output colored
git config --global merge.conflictStyle diff3 # make merge files show content of original
git init # create .git project in working directory
git clone remote_loc [clone_name] # copy repository to local drive; remote_loc can be path, HTTP, SSH
# to start with someone else's files, clone their repository
# cloning copies the current state and commit history of their directory
git branch branchname # create new branch
git checkout branchname # switch branches
git checkout -b branchname # create and switch to new branch
git add file1 file2 ... # add newly edited file/s to staging area
git add -A # add all edits and deletions to staging area
git commit -m "Your message here" # commit to repository
# Change editor for longer commit messages: https://www.youtube.com/watch?v=s_eFuGauy6k
# Style guide for commit messages: http://udacity.github.io/git-styleguide/
# title can include a tag like 'feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore'
# title should be in imperative present tense, and should be <50 chars
# body lines <72 chars; should address 'what' and 'why', not 'how' (should be evident in the code)
# include relevant issue #s in footer if applicable
git merge branchname # call from branch you want to merge into
# If there is a merge conflict, discrepancies will show up inside the documents in the working directory;
# undo the merge (see below) or edit, add, and commit the affected documents to complete the merge.
git rm filename '*pattern.txt' # deletes files and stages deletions
git checkout shortSHA # discard changes to working dir by checking out specified commit
git checkout -- filename.ext # restore file to version from previous commit
git checkout HEAD [files] # (partially) discard changes to working dir by checking out most recent commit
git checkout file1, file2 .. # partially discard changes to working dir by restoring from staging area
# 5 or 7 of 40-character SHA should be enough to identify a commit
# CHECKOUT usually moves the HEAD pointer; exception, when it's applied at the file level
git reset --soft shortSHA # move branch tip to an earlier commit, abandoning intervening commits
git reset --mixed shortSHA # move branch tip to earlier commit, reset staging area to that commit
git reset --hard shortSHA # reset staging area, working dir to earlier commit and move branch tip to same
git reset # branch tip unchanged; resets staging area to HEAD
git reset file1 file2 ... # partially resets staging area from HEAD; options above don't apply
# RESET moves a branch pointer; it should be used to undo changes on a private branch
git branch -d branchname # delete branch after successful merge
git merge --abort # to abandon a merge, run this after git reset HEAD
git commit --amend # 'undo' most recent commit by making new commit of parent commit
git revert HEAD-2 # recycle commit-from-two-commits-ago as a new commit, extending the branch tip
# REVERT should be used to undo changes on a public branch
git gc # run garbage collector
git status # check status
git diff -u file # see differences working directory and staging area
git diff --staged # see differences between staging area and repository
git diff shortSHA # see differences between working directory and specified commit
git diff shortSHA1 shortSHA2 # see differences between specified commits
# Type 'q' to exit diff mode
git log # view commits history
git log -n 10 # view 10 most recent commits
git log --stat # esp helpful view for multi-file commits
git branch # list all branches and indicate working branch
git log --graph --oneline branch1 branch2 # visualize changes between branches
git show HEAD # show most recent commit
git show shortSHA # diff a commit with its parent
When would you want to use a remote repository rather than keeping all your work local?
Why might you want to always pull changes manually rather than having Git automatically stay up-to-date with your remote repository?
What is the benefit of having a copy of the last known state of the remote stored locally?
git clone remote_loc [clone_name] # copy remote repository to local drive
git init
git remote # check local for existing remotes; -v option makes verbose
git remote add remotename remote_loc # give remote a convenient name
git remote rename oldname newname
git remote rm remotename # remove convenient name
# Remote branches are prefixed by their remote's name so you don’t mix them up with local branches
git fetch remotename [branchname] # check for changes in remote directory without merging
git merge remotename/branchname # merge remote branch into local's active branch
# https://git-scm.com/docs/git-merge#_how_conflicts_are_presented
git pull remotename [branchname] # fetch & merge content into local's active branch
git push -u remotename branchname # FIRST TIME: push content from local's specified branch to remote
git push # subsequent times, if no change to remote or branch